A Procedural cube is created using triangles. This procedural cube consists of 12 Triangles, 36 Vertices and 36 Indices.
The function uses a vector3 for the size, and a vector4 RGBA for the color, and a boolean for if a cubemap is used.
void CreateCube(vec3 size, vec4 color, bool cubemap) { /*4__5 / /| /7_/ |6 0| 1| / 3|_2|/ */
The cube is created in this way. I used this as a reference idea to visualize.
vec3 s = size * 0.5f; vec3 v0 = vec3(-s.x, -s.y, -s.z); vec3 v1 = vec3(s.x, -s.y, -s.z); vec3 v2 = vec3(s.x, s.y, -s.z); vec3 v3 = vec3(-s.x, s.y, -s.z); vec3 v4 = vec3(-s.x, -s.y, s.z); vec3 v5 = vec3(s.x, -s.y, s.z); vec3 v6 = vec3(s.x, s.y, s.z); vec3 v7 = vec3(-s.x, s.y, s.z); vec3 n0 = vec3(0.0f, 0.0f, -1.0f); vec3 n1 = vec3(-1.0f, 0.0f, 0.0f); vec3 n2 = vec3(0.0f, 0.0f, 1.0f); vec3 n3 = vec3(1.0f, 0.0f, 0.0f); vec3 n4 = vec3(0.0f, -1.0f, 0.0f); vec3 n5 = vec3(0.0f, 1.0f, 0.0f);
The data that is needed in order to create the cube, The cube is calculated from its center position. Also the normals are created
struct VertexData { vec3 position; vec3 normal; vec4 color; vec3 texcoord; };
The VertexData is a structure that holds the data that we want the cube to have.
mesh->vertexsize = 36; mesh->vertexdata = new VertexData[36]; //face 1 mesh->vertexdata[0].position = v2; mesh->vertexdata[1].position = v1; mesh->vertexdata[2].position = v0; mesh->vertexdata[3].position = v0; mesh->vertexdata[4].position = v3; mesh->vertexdata[5].position = v2; //face2 mesh->vertexdata[6].position = v3; mesh->vertexdata[7].position = v0; mesh->vertexdata[8].position = v4; mesh->vertexdata[9].position = v4; mesh->vertexdata[10].position = v7; mesh->vertexdata[11].position = v3; //face3 mesh->vertexdata[12].position = v7; mesh->vertexdata[13].position = v4; mesh->vertexdata[14].position = v5; mesh->vertexdata[15].position = v5; mesh->vertexdata[16].position = v6; mesh->vertexdata[17].position = v7; //face4 mesh->vertexdata[18].position = v6; mesh->vertexdata[19].position = v5; mesh->vertexdata[20].position = v1; mesh->vertexdata[21].position = v1; mesh->vertexdata[22].position = v2; mesh->vertexdata[23].position = v6; //face5 mesh->vertexdata[24].position = v1; mesh->vertexdata[25].position = v5; mesh->vertexdata[26].position = v4; mesh->vertexdata[27].position = v4; mesh->vertexdata[28].position = v0; mesh->vertexdata[29].position = v1; //face6 mesh->vertexdata[30].position = v2; mesh->vertexdata[31].position = v3; mesh->vertexdata[32].position = v7; mesh->vertexdata[33].position = v7; mesh->vertexdata[34].position = v6; mesh->vertexdata[35].position = v2;We set the position of each face according to the position we calculated from the size input.
//TEXTCOORD if (cubemap) { vec3 uv0 = vec3(-1.0f, -1.0f, -1.0f) * normalize(s); vec3 uv1 = vec3(1.0f, -1.0f, -1.0f) * normalize(s); vec3 uv2 = vec3(1.0f, 1.0f, -1.0f) * normalize(s); vec3 uv3 = vec3(-1.0f, 1.0f, -1.0f) * normalize(s); vec3 uv4 = vec3(-1.0f, -1.0f, 1.0f) * normalize(s); vec3 uv5 = vec3(1.0f, -1.0f, 1.0f) * normalize(s); vec3 uv6 = vec3(1.0f, 1.0f, 1.0f) * normalize(s); vec3 uv7 = vec3(-1.0f, 1.0f, 1.0f) * normalize(s); //face 1 mesh->vertexdata[0].texcoord = uv2; mesh->vertexdata[1].texcoord = uv1; mesh->vertexdata[2].texcoord = uv0; mesh->vertexdata[3].texcoord = uv0; mesh->vertexdata[4].texcoord = uv3; mesh->vertexdata[5].texcoord = uv2; //face2 mesh->vertexdata[6].texcoord = uv3; mesh->vertexdata[7].texcoord = uv0; mesh->vertexdata[8].texcoord = uv4; mesh->vertexdata[9].texcoord = uv4; mesh->vertexdata[10].texcoord = uv7; mesh->vertexdata[11].texcoord = uv3; //fase3 mesh->vertexdata[12].texcoord = uv7; mesh->vertexdata[13].texcoord = uv4; mesh->vertexdata[14].texcoord = uv5; mesh->vertexdata[15].texcoord = uv5; mesh->vertexdata[16].texcoord = uv6; mesh->vertexdata[17].texcoord = uv7; //face4 mesh->vertexdata[18].texcoord = uv6; mesh->vertexdata[19].texcoord = uv5; mesh->vertexdata[20].texcoord = uv1; mesh->vertexdata[21].texcoord = uv1; mesh->vertexdata[22].texcoord = uv2; mesh->vertexdata[23].texcoord = uv6; //face5 mesh->vertexdata[24].texcoord = uv4; mesh->vertexdata[25].texcoord = uv0; mesh->vertexdata[26].texcoord = uv1; mesh->vertexdata[27].texcoord = uv1; mesh->vertexdata[28].texcoord = uv5; mesh->vertexdata[29].texcoord = uv4; //face6 mesh->vertexdata[30].texcoord = uv7; mesh->vertexdata[31].texcoord = uv6; mesh->vertexdata[32].texcoord = uv2; mesh->vertexdata[33].texcoord = uv2; mesh->vertexdata[34].texcoord = uv3; mesh->vertexdata[35].texcoord = uv7; } else { float inverted = 1.0f; if (s.x < 0){ inverted = 1.0f; } else{ inverted = -1.0f; } vec3 uv0 = vec3(0.0f, 0.0f, 0.0f) * inverted; vec3 uv1 = vec3(1.0f, 0.0f, 0.0f) * inverted; vec3 uv2 = vec3(1.0f, 1.0f, 0.0f) * inverted; vec3 uv3 = vec3(0.0f, 1.0f, 0.0f) * inverted; //face 1 mesh->vertexdata[0].texcoord = uv2; mesh->vertexdata[1].texcoord = uv1; mesh->vertexdata[2].texcoord = uv0; mesh->vertexdata[3].texcoord = uv0; mesh->vertexdata[4].texcoord = uv3; mesh->vertexdata[5].texcoord = uv2; //face2 mesh->vertexdata[6].texcoord = uv2; mesh->vertexdata[7].texcoord = uv1; mesh->vertexdata[8].texcoord = uv0; mesh->vertexdata[9].texcoord = uv0; mesh->vertexdata[10].texcoord = uv3; mesh->vertexdata[11].texcoord = uv2; //face3 mesh->vertexdata[12].texcoord = uv2; mesh->vertexdata[13].texcoord = uv1; mesh->vertexdata[14].texcoord = uv0; mesh->vertexdata[15].texcoord = uv0; mesh->vertexdata[16].texcoord = uv3; mesh->vertexdata[17].texcoord = uv2; //face4 mesh->vertexdata[18].texcoord = uv2; mesh->vertexdata[19].texcoord = uv1; mesh->vertexdata[20].texcoord = uv0; mesh->vertexdata[21].texcoord = uv0; mesh->vertexdata[22].texcoord = uv3; mesh->vertexdata[23].texcoord = uv2; //face5 mesh->vertexdata[24].texcoord = uv2; mesh->vertexdata[25].texcoord = uv1; mesh->vertexdata[26].texcoord = uv0; mesh->vertexdata[27].texcoord = uv0; mesh->vertexdata[28].texcoord = uv3; mesh->vertexdata[29].texcoord = uv2; //face6 mesh->vertexdata[30].texcoord = uv2; mesh->vertexdata[31].texcoord = uv1; mesh->vertexdata[32].texcoord = uv0; mesh->vertexdata[33].texcoord = uv0; mesh->vertexdata[34].texcoord = uv3; mesh->vertexdata[35].texcoord = uv2; }When the boolean 0f the cubemap is set to true. the uv coordinates are created in such a way that it is best for the cubemap.
When the boolean is not set, All the sides of the cube have a uv coordinate of 0 to 1.unsigned int j = 0; for (unsigned int i = j; i < (j + 6); i++){ mesh->vertexdata[i].normal = n0; } j += 6; for (unsigned int i = j; i < (j + 6); i++){ mesh->vertexdata[i].normal = n1; } j += 6; for (unsigned int i = j; i < (j + 6); i++){ mesh->vertexdata[i].normal = n2; } j += 6; for (unsigned int i = j; i < (j + 6); i++){ mesh->vertexdata[i].normal = n3; } j += 6; for (unsigned int i = j; i < (j + 6); i++){ mesh->vertexdata[i].normal = n4; } j += 6; for (unsigned int i = j; i < (j + 6); i++){ mesh->vertexdata[i].normal = n5; }The normals are set to the vertexdata.
for (unsigned int i = 0; i < 36; i++) { mesh->vertexdata[i].color = color; }Color is added to the vertexdata.
mesh->indicesize = 36; mesh->indicedata = new unsigned int[36]; for (unsigned int i = 0; i < 36; i++) { mesh->indicedata[i] = i; }The indices are also added to the mesh.
For more information or questions feel free to contact me.