diff options
| author | raysan5 <raysan5@gmail.com> | 2014-04-19 16:36:49 +0200 |
|---|---|---|
| committer | raysan5 <raysan5@gmail.com> | 2014-04-19 16:36:49 +0200 |
| commit | f06a15ac8b3fe92d101ae795225fbf56fa670dba (patch) | |
| tree | cdfba90ee24fd078a15c89d8753ee3e11d8e229b /src/models.c | |
| parent | 650a8f7f159d3ce2addb1b0fdb31c3f460005391 (diff) | |
| download | raylib-f06a15ac8b3fe92d101ae795225fbf56fa670dba.tar.gz raylib-f06a15ac8b3fe92d101ae795225fbf56fa670dba.zip | |
raylib 1.1
View CHANGELOG for a detailed list of changes
Diffstat (limited to 'src/models.c')
| -rw-r--r-- | src/models.c | 647 |
1 files changed, 343 insertions, 304 deletions
diff --git a/src/models.c b/src/models.c index 84ef43fa..5eb5d107 100644 --- a/src/models.c +++ b/src/models.c @@ -25,9 +25,9 @@ #include "raylib.h" -#include <GL/gl.h> // OpenGL functions #include <stdio.h> // Standard input/output functions, used to read model files data #include <stdlib.h> // Declares malloc() and free() for memory management +#include <string.h> // Required for strcmp() #include <math.h> // Used for sin, cos, tan #include "raymath.h" // Required for data type Matrix and Matrix functions @@ -52,6 +52,7 @@ // Module specific Functions Declaration //---------------------------------------------------------------------------------- static float GetHeightValue(Color pixel); +static VertexData LoadOBJ(const char *fileName); //---------------------------------------------------------------------------------- // Module Functions Definition @@ -67,9 +68,9 @@ void DrawCube(Vector3 position, float width, float height, float lenght, Color c rlPushMatrix(); - // NOTE: Be careful! Function order matters (scale, translate, rotate) - //rlScalef(2.0f, 2.0f, 2.0f); + // NOTE: Be careful! Function order matters (rotate -> scale -> translate) //rlTranslatef(0.0f, 0.0f, 0.0f); + //rlScalef(2.0f, 2.0f, 2.0f); //rlRotatef(45, 0, 1, 0); rlBegin(RL_TRIANGLES); @@ -215,9 +216,9 @@ void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float hei float y = position.y; float z = position.z; - rlEnableTexture(texture.glId); + rlEnableTexture(texture.id); - rlPushMatrix(); + //rlPushMatrix(); // NOTE: Be careful! Function order matters (scale, translate, rotate) //rlScalef(2.0f, 2.0f, 2.0f); //rlTranslatef(2.0f, 0.0f, 0.0f); @@ -262,7 +263,7 @@ void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float hei rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z+lenght/2); // Top Right Of The Texture and Quad rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-lenght/2); // Top Left Of The Texture and Quad rlEnd(); - rlPopMatrix(); + //rlPopMatrix(); rlDisableTexture(); } @@ -278,13 +279,13 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color { rlPushMatrix(); rlTranslatef(centerPos.x, centerPos.y, centerPos.z); - //rlRotatef(rotation, 0, 1, 0); rlScalef(radius, radius, radius); + //rlRotatef(rotation, 0, 1, 0); rlBegin(RL_TRIANGLES); rlColor4ub(color.r, color.g, color.b, color.a); - for(int i = 0; i < 2 * rings + 1; i ++) + for(int i = 0; i < 2 * rings + 1; i++) { for(int j = 0; j < slices; j++) { @@ -317,14 +318,14 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color) { rlPushMatrix(); - rlTranslatef(centerPos.x, centerPos.y, centerPos.z); - //rlRotatef(rotation, 0, 1, 0); + //rlTranslatef(centerPos.x, centerPos.y, centerPos.z); rlScalef(radius, radius, radius); + //rlRotatef(rotation, 0, 1, 0); rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a); - for(int i = 0; i < 2 * rings + 1; i ++) + for(int i = 0; i < 2 * rings + 1; i++) { for(int j = 0; j < slices; j++) { @@ -447,12 +448,12 @@ void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color) // NOTE: Plane is always created on XZ ground and then rotated rlPushMatrix(); rlTranslatef(centerPos.x, centerPos.y, centerPos.z); + rlScalef(size.x, 1.0f, size.y); // TODO: Review multiples rotations Gimbal-Lock... use matrix or quaternions... rlRotatef(rotation.x, 1, 0, 0); rlRotatef(rotation.y, 0, 1, 0); rlRotatef(rotation.z, 0, 0, 1); - rlScalef(size.x, 1.0f, size.y); rlBegin(RL_QUADS); rlColor4ub(color.r, color.g, color.b, color.a); @@ -568,14 +569,13 @@ void DrawGizmo(Vector3 position) rlPopMatrix(); } -void DrawGizmoEx(Vector3 position, Vector3 rot, float scale, bool orbits) -{ - static float rotation = 0; +void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale) +{ // NOTE: RGB = XYZ rlPushMatrix(); rlTranslatef(position.x, position.y, position.z); - rlRotatef(rotation, 0, 1, 0); rlScalef(scale, scale, scale); + rlRotatef(rotation.y, 0, 1, 0); rlBegin(RL_LINES); // X Axis @@ -612,279 +612,53 @@ void DrawGizmoEx(Vector3 position, Vector3 rot, float scale, bool orbits) rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x - .1, position.y, position.z - .9); // Extra - if(orbits) + int n = 3; + + // X Axis + for (int i=0; i < 360; i += 6) { - int n = 3; - - // X Axis - for (int i=0; i < 360; i += 6) - { - rlColor4ub(200, 0, 0, 255); rlVertex3f(0, position.x + sin(DEG2RAD*i) * scale/n, position.y + cos(DEG2RAD*i) * scale/n); - rlColor4ub(200, 0, 0, 255); rlVertex3f(0, position.x + sin(DEG2RAD*(i+6)) * scale/n, position.y + cos(DEG2RAD*(i+6)) * scale/n); - } - - // Y Axis - for (int i=0; i < 360; i += 6) - { - rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x + sin(DEG2RAD*i) * scale/n, 0, position.y + cos(DEG2RAD*i) * scale/n); - rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x + sin(DEG2RAD*(i+6)) * scale/n, 0, position.y + cos(DEG2RAD*(i+6)) * scale/n); - } - - // Z Axis - for (int i=0; i < 360; i += 6) - { - rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x + sin(DEG2RAD*i) * scale/n, position.y + cos(DEG2RAD*i) * scale/n, 0); - rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x + sin(DEG2RAD*(i+6)) * scale/n, position.y + cos(DEG2RAD*(i+6)) * scale/n, 0); - } + rlColor4ub(200, 0, 0, 255); rlVertex3f(0, position.x + sin(DEG2RAD*i) * scale/n, position.y + cos(DEG2RAD*i) * scale/n); + rlColor4ub(200, 0, 0, 255); rlVertex3f(0, position.x + sin(DEG2RAD*(i+6)) * scale/n, position.y + cos(DEG2RAD*(i+6)) * scale/n); + } + + // Y Axis + for (int i=0; i < 360; i += 6) + { + rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x + sin(DEG2RAD*i) * scale/n, 0, position.y + cos(DEG2RAD*i) * scale/n); + rlColor4ub(0, 200, 0, 255); rlVertex3f(position.x + sin(DEG2RAD*(i+6)) * scale/n, 0, position.y + cos(DEG2RAD*(i+6)) * scale/n); + } + + // Z Axis + for (int i=0; i < 360; i += 6) + { + rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x + sin(DEG2RAD*i) * scale/n, position.y + cos(DEG2RAD*i) * scale/n, 0); + rlColor4ub(0, 0, 200, 255); rlVertex3f(position.x + sin(DEG2RAD*(i+6)) * scale/n, position.y + cos(DEG2RAD*(i+6)) * scale/n, 0); } rlEnd(); rlPopMatrix(); - - rotation += 0.1f; } -// Load a 3d model (.OBJ) -// TODO: Add comments explaining this function process +// Load a 3d model Model LoadModel(const char *fileName) { VertexData vData; - char dataType; - char comments[200]; - - int numVertex = 0; - int numNormals = 0; - int numTexCoords = 0; - int numTriangles = 0; - - FILE* objFile; - - objFile = fopen(fileName, "rt"); - - while(!feof(objFile)) - { - fscanf(objFile, "%c", &dataType); - - switch(dataType) - { - case '#': // It's a comment - { - fgets(comments, 200, objFile); - } break; - case 'v': - { - fscanf(objFile, "%c", &dataType); - - if (dataType == 't') // Read texCoord - { - fgets(comments, 200, objFile); - fscanf(objFile, "%c", &dataType); - - while (dataType == 'v') - { - fgets(comments, 200, objFile); - fscanf(objFile, "%c", &dataType); - } - - if (dataType == '#') - { - fscanf(objFile, "%i", &numTexCoords); - } - - fgets(comments, 200, objFile); - } - else if (dataType == 'n') // Read normals - { - fgets(comments, 200, objFile); - fscanf(objFile, "%c", &dataType); - - while (dataType == 'v') - { - fgets(comments, 200, objFile); - fscanf(objFile, "%c", &dataType); - } - - if (dataType == '#') - { - fscanf(objFile, "%i", &numNormals); - } - - fgets(comments, 200, objFile); - } - else // Read vertex - { - fgets(comments, 200, objFile); - fscanf(objFile, "%c", &dataType); - - while (dataType == 'v') - { - fgets(comments, 200, objFile); - fscanf(objFile, "%c", &dataType); - } - - if (dataType == '#') - { - fscanf(objFile, "%i", &numVertex); - } - - fgets(comments, 200, objFile); - } - } break; - case 'f': - { - fgets(comments, 200, objFile); - fscanf(objFile, "%c", &dataType); - - while (dataType == 'f') - { - fgets(comments, 200, objFile); - fscanf(objFile, "%c", &dataType); - } - - if (dataType == '#') - { - fscanf(objFile, "%i", &numTriangles); - } - - fgets(comments, 200, objFile); - - } break; - default: break; - } - } - - Vector3 midVertices[numVertex]; - Vector3 midNormals[numNormals]; - Vector2 midTexCoords[numTexCoords]; - - vData.numVertices = numTriangles*3; - - vData.vertices = (float *)malloc(vData.numVertices * 3 * sizeof(float)); - vData.texcoords = (float *)malloc(vData.numVertices * 2 * sizeof(float)); - vData.normals = (float *)malloc(vData.numVertices * 3 * sizeof(float)); - - int countVertex = 0; - int countNormals = 0; - int countTexCoords = 0; - - int vCounter = 0; // Used to count vertices float by float - int tcCounter = 0; // Used to count texcoords float by float - int nCounter = 0; // Used to count normals float by float - - rewind(objFile); - - while(!feof(objFile)) - { - fscanf(objFile, "%c", &dataType); - - switch(dataType) - { - case '#': - { - fgets(comments, 200, objFile); - } break; - case 'v': - { - fscanf(objFile, "%c", &dataType); - - if (dataType == 't') // Read texCoord - { - float useless = 0; - - fscanf(objFile, "%f %f %f", &midTexCoords[countTexCoords].x, &midTexCoords[countTexCoords].y, &useless); - countTexCoords++; - - fscanf(objFile, "%c", &dataType); - } - else if (dataType == 'n') // Read normals - { - fscanf(objFile, "%f %f %f", &midNormals[countNormals].x, &midNormals[countNormals].y, &midNormals[countNormals].z ); - countNormals++; - - fscanf(objFile, "%c", &dataType); - } - else // Read vertex - { - fscanf(objFile, "%f %f %f", &midVertices[countVertex].x, &midVertices[countVertex].y, &midVertices[countVertex].z ); - countVertex++; - - fscanf(objFile, "%c", &dataType); - } - } break; - case 'f': - { - // At this point all vertex data (v, vt, vn) have been gathered on midVertices, midTexCoords, midNormals - // Now we can organize that data into our VertexData struct - - int vNum, vtNum, vnNum; - fscanf(objFile, "%c", &dataType); - fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum); - - vData.vertices[vCounter] = midVertices[vNum-1].x; - vData.vertices[vCounter + 1] = midVertices[vNum-1].y; - vData.vertices[vCounter + 2] = midVertices[vNum-1].z; - vCounter += 3; - - vData.normals[nCounter] = midNormals[vnNum-1].x; - vData.normals[nCounter + 1] = midNormals[vnNum-1].y; - vData.normals[nCounter + 2] = midNormals[vnNum-1].z; - nCounter += 3; - - vData.texcoords[tcCounter] = midTexCoords[vtNum-1].x; - vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y; - tcCounter += 2; - - fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum); - - vData.vertices[vCounter] = midVertices[vNum-1].x; - vData.vertices[vCounter + 1] = midVertices[vNum-1].y; - vData.vertices[vCounter + 2] = midVertices[vNum-1].z; - vCounter += 3; - - vData.normals[nCounter] = midNormals[vnNum-1].x; - vData.normals[nCounter + 1] = midNormals[vnNum-1].y; - vData.normals[nCounter + 2] = midNormals[vnNum-1].z; - nCounter += 3; - - vData.texcoords[tcCounter] = midTexCoords[vtNum-1].x; - vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y; - tcCounter += 2; - - fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum); - - vData.vertices[vCounter] = midVertices[vNum-1].x; - vData.vertices[vCounter + 1] = midVertices[vNum-1].y; - vData.vertices[vCounter + 2] = midVertices[vNum-1].z; - vCounter += 3; - - vData.normals[nCounter] = midNormals[vnNum-1].x; - vData.normals[nCounter + 1] = midNormals[vnNum-1].y; - vData.normals[nCounter + 2] = midNormals[vnNum-1].z; - nCounter += 3; - - vData.texcoords[tcCounter] = midTexCoords[vtNum-1].x; - vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y; - tcCounter += 2; - } break; - default: break; - } - } - - fclose(objFile); - - // NOTE: At this point we have all vertex, texcoord, normal data for the model in vData struct + if (strcmp(GetExtension(fileName),"obj") == 0) vData = LoadOBJ(fileName); + else TraceLog(WARNING, "[%s] Model extension not recognized, it can't be loaded", fileName); Model model; -#ifdef USE_OPENGL_11 - model.data = vData; // model data is vertex data -#else - model.vaoId = rlglLoadModel(vData); // Use loaded data to generate VAO + model.mesh = vData; // Model mesh is vertex data + model.textureId = 0; +#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2) + model.vaoId = rlglLoadModel(vData); // Use loaded data to generate VAO + model.textureId = 1; // Default whiteTexture + // Now that vertex data is uploaded to GPU, we can free arrays - free(vData.vertices); - free(vData.texcoords); - free(vData.normals); + //free(vData.vertices); + //free(vData.texcoords); + //free(vData.normals); #endif return model; @@ -902,11 +676,11 @@ Model LoadHeightmap(Image heightmap, float maxHeight) // TODO: Consider resolution when generating model data? int numTriangles = (mapX-1)*(mapZ-1)*2; // One quad every four pixels - vData.numVertices = numTriangles*3; + vData.vertexCount = numTriangles*3; - vData.vertices = (float *)malloc(vData.numVertices * 3 * sizeof(float)); - vData.normals = (float *)malloc(vData.numVertices * 3 * sizeof(float)); - vData.texcoords = (float *)malloc(vData.numVertices * 2 * sizeof(float)); + vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float)); + vData.normals = (float *)malloc(vData.vertexCount * 3 * sizeof(float)); + vData.texcoords = (float *)malloc(vData.vertexCount * 2 * sizeof(float)); int vCounter = 0; // Used to count vertices float by float int tcCounter = 0; // Used to count texcoords float by float @@ -973,7 +747,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight) // Fill normals array with data //-------------------------------------------------------------- - // TODO: Review normals calculation + // NOTE: Current Model implementation doe not use normals! for (int i = 0; i < 18; i += 3) { vData.normals[nCounter + i] = 0.0f; @@ -981,6 +755,8 @@ Model LoadHeightmap(Image heightmap, float maxHeight) vData.normals[nCounter + i + 2] = 0.0f; } + // TODO: Calculate normals in an efficient way + nCounter += 18; // 6 vertex, 18 floats trisCounter += 2; @@ -991,15 +767,17 @@ Model LoadHeightmap(Image heightmap, float maxHeight) Model model; -#ifdef USE_OPENGL_11 - model.data = vData; // model data is vertex data -#else + model.mesh = vData; // Model mesh is vertex data + model.textureId = 0; + +#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2) model.vaoId = rlglLoadModel(vData); // Use loaded data to generate VAO + model.textureId = 1; // Default whiteTexture // Now that vertex data is uploaded to GPU, we can free arrays - free(vData.vertices); - free(vData.texcoords); - free(vData.normals); + //free(vData.vertices); + //free(vData.texcoords); + //free(vData.normals); #endif return model; @@ -1008,37 +786,43 @@ Model LoadHeightmap(Image heightmap, float maxHeight) // Unload 3d model from memory void UnloadModel(Model model) { -#ifdef USE_OPENGL_11 - free(model.data.vertices); - free(model.data.texcoords); - free(model.data.normals); -#endif + free(model.mesh.vertices); + free(model.mesh.texcoords); + free(model.mesh.normals); #if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2) rlDeleteVertexArrays(model.vaoId); #endif } -// Draw a model -void DrawModel(Model model, Vector3 position, float scale, Color color) +void SetModelTexture(Model *model, Texture2D texture) { - rlglDrawModel(model, position, scale, false); + if (texture.id <= 0) model->textureId = 1; // Default white texture (use mesh color) + else model->textureId = texture.id; } -// Draw a textured model -void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint) +// Draw a model (with texture if set) +void DrawModel(Model model, Vector3 position, float scale, Color tint) { - rlEnableTexture(texture.glId); - - DrawModel(model, position, scale, tint); - - rlDisableTexture(); + Vector3 vScale = { scale, scale, scale }; + Vector3 rotation = { 0, 0, 0 }; + + rlglDrawModel(model, position, rotation, vScale, tint, false); } -// Draw a model wires +// Draw a model with extended parameters +void DrawModelEx(Model model, Vector3 position, Vector3 rotation, Vector3 scale, Color tint) +{ + rlglDrawModel(model, position, rotation, scale, tint, false); +} + +// Draw a model wires (with texture if set) void DrawModelWires(Model model, Vector3 position, float scale, Color color) { - rlglDrawModel(model, position, scale, true); + Vector3 vScale = { scale, scale, scale }; + Vector3 rotation = { 0, 0, 0 }; + + rlglDrawModel(model, position, rotation, vScale, color, true); } // Draw a billboard @@ -1070,7 +854,7 @@ void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Vector3 c = VectorAdd(center, p2); Vector3 d = VectorSubtract(center, p1); - rlEnableTexture(texture.glId); + rlEnableTexture(texture.id); rlBegin(RL_QUADS); rlColor4ub(tint.r, tint.g, tint.b, tint.a); @@ -1113,7 +897,7 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec Vector3 c = VectorAdd(center, p2); Vector3 d = VectorSubtract(center, p1); - rlEnableTexture(texture.glId); + rlEnableTexture(texture.id); rlBegin(RL_QUADS); rlColor4ub(tint.r, tint.g, tint.b, tint.a); @@ -1142,4 +926,259 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec static float GetHeightValue(Color pixel) { return (((float)pixel.r + (float)pixel.g + (float)pixel.b)/3); +} + +// Load OBJ mesh data +static VertexData LoadOBJ(const char *fileName) +{ + VertexData vData; + + char dataType; + char comments[200]; + + int numVertex = 0; + int numNormals = 0; + int numTexCoords = 0; + int numTriangles = 0; + + FILE* objFile; + + objFile = fopen(fileName, "rt"); + + // First pass over all file to get numVertex, numNormals, numTexCoords, numTriangles + // NOTE: vertex, texcoords and normals could be optimized (to be used indexed on faces definition) + while(!feof(objFile)) + { + fscanf(objFile, "%c", &dataType); + + switch(dataType) + { + case '#': // It's a comment + { + fgets(comments, 200, objFile); + } break; + case 'o': // New object + { + // TODO: Read multiple objects, we need to know numMeshes + verticesPerMesh + + // NOTE: One OBJ file can contain multible meshes defined, one after every 'o' + + } break; + case 'v': + { + fscanf(objFile, "%c", &dataType); + + if (dataType == 't') // Read texCoord + { + fgets(comments, 200, objFile); + fscanf(objFile, "%c", &dataType); + + while (dataType == 'v') + { + fgets(comments, 200, objFile); + fscanf(objFile, "%c", &dataType); + } + + if (dataType == '#') + { + fscanf(objFile, "%i", &numTexCoords); + } + + fgets(comments, 200, objFile); + } + else if (dataType == 'n') // Read normals + { + fgets(comments, 200, objFile); + fscanf(objFile, "%c", &dataType); + + while (dataType == 'v') + { + fgets(comments, 200, objFile); + fscanf(objFile, "%c", &dataType); + } + + if (dataType == '#') + { + fscanf(objFile, "%i", &numNormals); + } + + fgets(comments, 200, objFile); + } + else // Read vertex + { + fgets(comments, 200, objFile); + fscanf(objFile, "%c", &dataType); + + while (dataType == 'v') + { + fgets(comments, 200, objFile); + fscanf(objFile, "%c", &dataType); + } + + if (dataType == '#') + { + fscanf(objFile, "%i", &numVertex); + } + + fgets(comments, 200, objFile); + } + } break; + case 'f': + { + fgets(comments, 200, objFile); + fscanf(objFile, "%c", &dataType); + + while (dataType == 'f') + { + fgets(comments, 200, objFile); + fscanf(objFile, "%c", &dataType); + } + + if (dataType == '#') + { + fscanf(objFile, "%i", &numTriangles); + } + + fgets(comments, 200, objFile); + + } break; + default: break; + } + } + + // Once we know the number of vertices to store, we create required arrays + Vector3 *midVertices = (Vector3 *)malloc(numVertex*sizeof(Vector3)); + Vector3 *midNormals = (Vector3 *)malloc(numNormals*sizeof(Vector3)); + Vector2 *midTexCoords = (Vector2 *)malloc(numTexCoords*sizeof(Vector2)); + + vData.vertexCount = numTriangles*3; + + // Additional arrays to store vertex data as floats + vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float)); + vData.texcoords = (float *)malloc(vData.vertexCount * 2 * sizeof(float)); + vData.normals = (float *)malloc(vData.vertexCount * 3 * sizeof(float)); + vData.colors = (float *)malloc(vData.vertexCount * 4 * sizeof(float)); + + int countVertex = 0; + int countNormals = 0; + int countTexCoords = 0; + + int vCounter = 0; // Used to count vertices float by float + int tcCounter = 0; // Used to count texcoords float by float + int nCounter = 0; // Used to count normals float by float + + rewind(objFile); // Return to the beginning of the file, to read again + + // Reading again file to get vertex data + while(!feof(objFile)) + { + fscanf(objFile, "%c", &dataType); + + switch(dataType) + { + case '#': + { + fgets(comments, 200, objFile); + } break; + case 'v': + { + fscanf(objFile, "%c", &dataType); + + if (dataType == 't') // Read texCoord + { + float useless = 0; + + fscanf(objFile, "%f %f %f", &midTexCoords[countTexCoords].x, &midTexCoords[countTexCoords].y, &useless); + countTexCoords++; + + fscanf(objFile, "%c", &dataType); + } + else if (dataType == 'n') // Read normals + { + fscanf(objFile, "%f %f %f", &midNormals[countNormals].x, &midNormals[countNormals].y, &midNormals[countNormals].z ); + countNormals++; + + fscanf(objFile, "%c", &dataType); + } + else // Read vertex + { + fscanf(objFile, "%f %f %f", &midVertices[countVertex].x, &midVertices[countVertex].y, &midVertices[countVertex].z ); + countVertex++; + + fscanf(objFile, "%c", &dataType); + } + } break; + case 'f': + { + // At this point all vertex data (v, vt, vn) have been gathered on midVertices, midTexCoords, midNormals + // Now we can organize that data into our VertexData struct + + int vNum, vtNum, vnNum; + fscanf(objFile, "%c", &dataType); + fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum); + + vData.vertices[vCounter] = midVertices[vNum-1].x; + vData.vertices[vCounter + 1] = midVertices[vNum-1].y; + vData.vertices[vCounter + 2] = midVertices[vNum-1].z; + vCounter += 3; + + vData.normals[nCounter] = midNormals[vnNum-1].x; + vData.normals[nCounter + 1] = midNormals[vnNum-1].y; + vData.normals[nCounter + 2] = midNormals[vnNum-1].z; + nCounter += 3; + + vData.texcoords[tcCounter] = midTexCoords[vtNum-1].x; + vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y; + tcCounter += 2; + + fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum); + + vData.vertices[vCounter] = midVertices[vNum-1].x; + vData.vertices[vCounter + 1] = midVertices[vNum-1].y; + vData.vertices[vCounter + 2] = midVertices[vNum-1].z; + vCounter += 3; + + vData.normals[nCounter] = midNormals[vnNum-1].x; + vData.normals[nCounter + 1] = midNormals[vnNum-1].y; + vData.normals[nCounter + 2] = midNormals[vnNum-1].z; + nCounter += 3; + + vData.texcoords[tcCounter] = midTexCoords[vtNum-1].x; + vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y; + tcCounter += 2; + + fscanf(objFile, "%i/%i/%i", &vNum, &vtNum, &vnNum); + + vData.vertices[vCounter] = midVertices[vNum-1].x; + vData.vertices[vCounter + 1] = midVertices[vNum-1].y; + vData.vertices[vCounter + 2] = midVertices[vNum-1].z; + vCounter += 3; + + vData.normals[nCounter] = midNormals[vnNum-1].x; + vData.normals[nCounter + 1] = midNormals[vnNum-1].y; + vData.normals[nCounter + 2] = midNormals[vnNum-1].z; + nCounter += 3; + + vData.texcoords[tcCounter] = midTexCoords[vtNum-1].x; + vData.texcoords[tcCounter + 1] = -midTexCoords[vtNum-1].y; + tcCounter += 2; + } break; + default: break; + } + } + + fclose(objFile); + + // NOTE: We set all vertex colors to white + for (int i = 0; i < (4*vData.vertexCount); i++) vData.colors[i] = 1.0f; + + // Now we can free temp mid* arrays + free(midVertices); + free(midNormals); + free(midTexCoords); + + // NOTE: At this point we have all vertex, texcoord, normal data for the model in vData struct + TraceLog(INFO, "[%s] Model loaded successfully in RAM (CPU)", fileName); + + return vData; }
\ No newline at end of file |
