aboutsummaryrefslogtreecommitdiff
path: root/src/models.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/models.c')
-rw-r--r--src/models.c139
1 files changed, 67 insertions, 72 deletions
diff --git a/src/models.c b/src/models.c
index 066b919e..07dee720 100644
--- a/src/models.c
+++ b/src/models.c
@@ -65,6 +65,16 @@ static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
// Module Functions Definition
//----------------------------------------------------------------------------------
+// Draw a line in 3D world space
+void Draw3DLine(Vector3 startPos, Vector3 endPos, Color color)
+{
+ rlBegin(RL_LINES);
+ rlColor4ub(color.r, color.g, color.b, color.a);
+ rlVertex3f(startPos.x, startPos.y, startPos.z);
+ rlVertex3f(endPos.x, endPos.y, endPos.z);
+ rlEnd();
+}
+
// Draw cube
// NOTE: Cube position is the center position
void DrawCube(Vector3 position, float width, float height, float length, Color color)
@@ -292,9 +302,9 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
- for(int i = 0; i < (rings + 2); i++)
+ for (int i = 0; i < (rings + 2); i++)
{
- for(int j = 0; j < slices; j++)
+ for (int j = 0; j < slices; j++)
{
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*i)),
@@ -331,9 +341,9 @@ void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Col
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
- for(int i = 0; i < (rings + 2); i++)
+ for (int i = 0; i < (rings + 2); i++)
{
- for(int j = 0; j < slices; j++)
+ for (int j = 0; j < slices; j++)
{
rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*i)),
@@ -376,7 +386,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
if (radiusTop > 0)
{
// Draw Body -------------------------------------------------------------------------------------
- for(int i = 0; i < 360; i += 360/sides)
+ for (int i = 0; i < 360; i += 360/sides)
{
rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); //Bottom Left
rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom); //Bottom Right
@@ -388,7 +398,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
}
// Draw Cap --------------------------------------------------------------------------------------
- for(int i = 0; i < 360; i += 360/sides)
+ for (int i = 0; i < 360; i += 360/sides)
{
rlVertex3f(0, height, 0);
rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop);
@@ -398,7 +408,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
else
{
// Draw Cone -------------------------------------------------------------------------------------
- for(int i = 0; i < 360; i += 360/sides)
+ for (int i = 0; i < 360; i += 360/sides)
{
rlVertex3f(0, height, 0);
rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom);
@@ -407,7 +417,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
}
// Draw Base -----------------------------------------------------------------------------------------
- for(int i = 0; i < 360; i += 360/sides)
+ for (int i = 0; i < 360; i += 360/sides)
{
rlVertex3f(0, 0, 0);
rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom);
@@ -421,7 +431,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
// NOTE: It could be also used for pyramid and cone
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int sides, Color color)
{
- if(sides < 3) sides = 3;
+ if (sides < 3) sides = 3;
rlPushMatrix();
rlTranslatef(position.x, position.y, position.z);
@@ -429,7 +439,7 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
- for(int i = 0; i < 360; i += 360/sides)
+ for (int i = 0; i < 360; i += 360/sides)
{
rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom);
rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom);
@@ -490,7 +500,7 @@ void DrawGrid(int slices, float spacing)
int halfSlices = slices / 2;
rlBegin(RL_LINES);
- for(int i = -halfSlices; i <= halfSlices; i++)
+ for (int i = -halfSlices; i <= halfSlices; i++)
{
if (i == 0)
{
@@ -553,7 +563,7 @@ Model LoadModel(const char *fileName)
if (model.mesh.vertexCount == 0) TraceLog(WARNING, "Model could not be loaded");
else
{
- rlglLoadMesh(&model.mesh); // Upload vertex data to GPU
+ rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model)
model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial();
@@ -563,13 +573,13 @@ Model LoadModel(const char *fileName)
}
// Load a 3d model (from vertex data)
-Model LoadModelEx(Mesh data)
+Model LoadModelEx(Mesh data, bool dynamic)
{
Model model = { 0 };
model.mesh = data;
- rlglLoadMesh(&model.mesh); // Upload vertex data to GPU
+ rlglLoadMesh(&model.mesh, dynamic); // Upload vertex data to GPU
model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial();
@@ -668,7 +678,7 @@ Model LoadHeightmap(Image heightmap, Vector3 size)
model.mesh = GenMeshHeightmap(heightmap, size);
- rlglLoadMesh(&model.mesh);
+ rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model)
model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial();
@@ -683,7 +693,7 @@ Model LoadCubicmap(Image cubicmap)
model.mesh = GenMeshCubicmap(cubicmap, (Vector3){ 1.0, 1.0, 1.5f });
- rlglLoadMesh(&model.mesh);
+ rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model)
model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial();
@@ -691,31 +701,14 @@ Model LoadCubicmap(Image cubicmap)
return model;
}
-// Unload 3d model from memory
+// Unload 3d model from memory (mesh and material)
void UnloadModel(Model model)
{
- // Unload mesh data
- if (model.mesh.vertices != NULL) free(model.mesh.vertices);
- if (model.mesh.texcoords != NULL) free(model.mesh.texcoords);
- if (model.mesh.normals != NULL) free(model.mesh.normals);
- if (model.mesh.colors != NULL) free(model.mesh.colors);
- if (model.mesh.tangents != NULL) free(model.mesh.tangents);
- if (model.mesh.texcoords2 != NULL) free(model.mesh.texcoords2);
- if (model.mesh.indices != NULL) free(model.mesh.indices);
-
- TraceLog(INFO, "Unloaded model data from RAM (CPU)");
-
- rlDeleteBuffers(model.mesh.vboId[0]); // vertex
- rlDeleteBuffers(model.mesh.vboId[1]); // texcoords
- rlDeleteBuffers(model.mesh.vboId[2]); // normals
- rlDeleteBuffers(model.mesh.vboId[3]); // colors
- rlDeleteBuffers(model.mesh.vboId[4]); // tangents
- rlDeleteBuffers(model.mesh.vboId[5]); // texcoords2
- rlDeleteBuffers(model.mesh.vboId[6]); // indices
-
- rlDeleteVertexArrays(model.mesh.vaoId);
-
+ rlglUnloadMesh(&model.mesh);
+
UnloadMaterial(model.material);
+
+ TraceLog(INFO, "Unloaded model data from RAM and VRAM");
}
// Load material data (from file)
@@ -749,6 +742,18 @@ Material LoadDefaultMaterial(void)
return material;
}
+// Load standard material (uses material attributes and lighting shader)
+// NOTE: Standard shader supports multiple maps and lights
+Material LoadStandardMaterial(void)
+{
+ Material material = LoadDefaultMaterial();
+
+ material.shader = GetStandardShader();
+
+ return material;
+}
+
+// Unload material from memory
void UnloadMaterial(Material material)
{
rlDeleteTextures(material.texDiffuse.id);
@@ -793,9 +798,9 @@ static Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
Vector3 scaleFactor = { size.x/mapX, size.y/255.0f, size.z/mapZ };
- for(int z = 0; z < mapZ-1; z++)
+ for (int z = 0; z < mapZ-1; z++)
{
- for(int x = 0; x < mapX-1; x++)
+ for (int x = 0; x < mapX-1; x++)
{
// Fill vertices array with data
//----------------------------------------------------------
@@ -1245,42 +1250,29 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
//Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates
model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
- model.material.colDiffuse = tint;
+ // model.material.colDiffuse = tint;
- rlglDrawEx(model.mesh, model.material, model.transform, false);
+ rlglDrawMesh(model.mesh, model.material, model.transform);
}
// Draw a model wires (with texture if set)
void DrawModelWires(Model model, Vector3 position, float scale, Color tint)
{
- Vector3 vScale = { scale, scale, scale };
- Vector3 rotationAxis = { 0.0f, 0.0f, 0.0f };
-
- // Calculate transformation matrix from function parameters
- // Get transform matrix (rotation -> scale -> translation)
- Matrix matRotation = MatrixRotate(rotationAxis, 0.0f);
- Matrix matScale = MatrixScale(vScale.x, vScale.y, vScale.z);
- Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z);
+ rlEnableWireMode();
- model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
- model.material.colDiffuse = tint;
+ DrawModel(model, position, scale, tint);
- rlglDrawEx(model.mesh, model.material, model.transform, true);
+ rlDisableWireMode();
}
// Draw a model wires (with texture if set) with extended parameters
void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
{
- // Calculate transformation matrix from function parameters
- // Get transform matrix (rotation -> scale -> translation)
- Matrix matRotation = MatrixRotate(rotationAxis, rotationAngle*DEG2RAD);
- Matrix matScale = MatrixScale(scale.x, scale.y, scale.z);
- Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z);
+ rlEnableWireMode();
- model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
- model.material.colDiffuse = tint;
+ DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint);
- rlglDrawEx(model.mesh, model.material, model.transform, true);
+ rlDisableWireMode();
}
// Draw a billboard
@@ -1425,7 +1417,7 @@ bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius
float vector = VectorDotProduct(raySpherePos, ray.direction);
float d = sphereRadius*sphereRadius - (distance*distance - vector*vector);
- if(d >= 0.0f) collision = true;
+ if (d >= 0.0f) collision = true;
return collision;
}
@@ -1440,14 +1432,14 @@ bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadi
float vector = VectorDotProduct(raySpherePos, ray.direction);
float d = sphereRadius*sphereRadius - (distance*distance - vector*vector);
- if(d >= 0.0f) collision = true;
+ if (d >= 0.0f) collision = true;
// Calculate collision point
Vector3 offset = ray.direction;
float collisionDistance = 0;
// Check if ray origin is inside the sphere to calculate the correct collision point
- if(distance < sphereRadius) collisionDistance = vector + sqrt(d);
+ if (distance < sphereRadius) collisionDistance = vector + sqrt(d);
else collisionDistance = vector - sqrt(d);
VectorScale(&offset, collisionDistance);
@@ -1785,11 +1777,11 @@ static Mesh LoadOBJ(const char *fileName)
// First reading pass: Get numVertex, numNormals, numTexCoords, numTriangles
// NOTE: vertex, texcoords and normals could be optimized (to be used indexed on faces definition)
// NOTE: faces MUST be defined as TRIANGLES (3 vertex per face)
- while(!feof(objFile))
+ while (!feof(objFile))
{
fscanf(objFile, "%c", &dataType);
- switch(dataType)
+ switch (dataType)
{
case '#': // Comments
case 'o': // Object name (One OBJ file can contain multible named meshes)
@@ -1850,11 +1842,11 @@ static Mesh LoadOBJ(const char *fileName)
// Second reading pass: Get vertex data to fill intermediate arrays
// NOTE: This second pass is required in case of multiple meshes defined in same OBJ
// TODO: Consider that different meshes can have different vertex data available (position, texcoords, normals)
- while(!feof(objFile))
+ while (!feof(objFile))
{
fscanf(objFile, "%c", &dataType);
- switch(dataType)
+ switch (dataType)
{
case '#': case 'o': case 'g': case 's': case 'm': case 'u': case 'f': fgets(comments, 200, objFile); break;
case 'v':
@@ -1911,11 +1903,11 @@ static Mesh LoadOBJ(const char *fileName)
if (numNormals == 0) TraceLog(INFO, "[%s] No normals data on OBJ, normals will be generated from faces data", fileName);
// Third reading pass: Get faces (triangles) data and fill VertexArray
- while(!feof(objFile))
+ while (!feof(objFile))
{
fscanf(objFile, "%c", &dataType);
- switch(dataType)
+ switch (dataType)
{
case '#': case 'o': case 'g': case 's': case 'm': case 'u': case 'v': fgets(comments, 200, objFile); break;
case 'f':
@@ -2031,7 +2023,7 @@ static Material LoadMTL(const char *fileName)
return material;
}
- while(!feof(mtlFile))
+ while (!feof(mtlFile))
{
fgets(buffer, MAX_BUFFER_SIZE, mtlFile);
@@ -2086,7 +2078,10 @@ static Material LoadMTL(const char *fileName)
{
if (buffer[1] == 's') // Ns int Shininess (specular exponent). Ranges from 0 to 1000.
{
- sscanf(buffer, "Ns %i", &material.glossiness);
+ int shininess = 0;
+ sscanf(buffer, "Ns %i", &shininess);
+
+ material.glossiness = (float)shininess;
}
else if (buffer[1] == 'i') // Ni int Refraction index.
{