Reorganize data for consistency
This commit is contained in:
parent
bc08271da3
commit
037edbaa13
3 changed files with 282 additions and 210 deletions
52
src/models.c
52
src/models.c
|
@ -691,31 +691,14 @@ Model LoadCubicmap(Image cubicmap)
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unload 3d model from memory
|
// Unload 3d model from memory (mesh and material)
|
||||||
void UnloadModel(Model model)
|
void UnloadModel(Model model)
|
||||||
{
|
{
|
||||||
// Unload mesh data
|
rlglUnloadMesh(&model.mesh);
|
||||||
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);
|
|
||||||
|
|
||||||
UnloadMaterial(model.material);
|
UnloadMaterial(model.material);
|
||||||
|
|
||||||
|
TraceLog(INFO, "Unloaded model data from RAM and VRAM");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load material data (from file)
|
// Load material data (from file)
|
||||||
|
@ -1247,40 +1230,27 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
|
||||||
model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
|
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)
|
// Draw a model wires (with texture if set)
|
||||||
void DrawModelWires(Model model, Vector3 position, float scale, Color tint)
|
void DrawModelWires(Model model, Vector3 position, float scale, Color tint)
|
||||||
{
|
{
|
||||||
Vector3 vScale = { scale, scale, scale };
|
rlEnableWireMode();
|
||||||
Vector3 rotationAxis = { 0.0f, 0.0f, 0.0f };
|
|
||||||
|
|
||||||
// Calculate transformation matrix from function parameters
|
DrawModel(model, position, scale, tint);
|
||||||
// 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);
|
|
||||||
|
|
||||||
model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
|
rlDisableWireMode();
|
||||||
model.material.colDiffuse = tint;
|
|
||||||
|
|
||||||
rlglDrawEx(model.mesh, model.material, model.transform, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a model wires (with texture if set) with extended parameters
|
// 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)
|
void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
|
||||||
{
|
{
|
||||||
// Calculate transformation matrix from function parameters
|
rlEnableWireMode();
|
||||||
// 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);
|
|
||||||
|
|
||||||
model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
|
DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint);
|
||||||
model.material.colDiffuse = tint;
|
|
||||||
|
|
||||||
rlglDrawEx(model.mesh, model.material, model.transform, true);
|
rlDisableWireMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a billboard
|
// Draw a billboard
|
||||||
|
|
431
src/rlgl.c
431
src/rlgl.c
|
@ -740,6 +740,24 @@ void rlDisableDepthTest(void)
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable wire mode
|
||||||
|
void rlEnableWireMode(void)
|
||||||
|
{
|
||||||
|
#if defined (GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
||||||
|
// NOTE: glPolygonMode() not available on OpenGL ES
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable wire mode
|
||||||
|
void rlDisableWireMode(void)
|
||||||
|
{
|
||||||
|
#if defined (GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
||||||
|
// NOTE: glPolygonMode() not available on OpenGL ES
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Unload texture from GPU memory
|
// Unload texture from GPU memory
|
||||||
void rlDeleteTextures(unsigned int id)
|
void rlDeleteTextures(unsigned int id)
|
||||||
{
|
{
|
||||||
|
@ -1033,178 +1051,18 @@ void rlglClose(void)
|
||||||
void rlglDraw(void)
|
void rlglDraw(void)
|
||||||
{
|
{
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
/*
|
||||||
|
for (int i = 0; i < modelsCount; i++)
|
||||||
|
{
|
||||||
|
rlglDrawMesh(models[i]->mesh, models[i]->material, models[i]->transform);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// NOTE: Default buffers always drawn at the end
|
||||||
UpdateDefaultBuffers();
|
UpdateDefaultBuffers();
|
||||||
DrawDefaultBuffers();
|
DrawDefaultBuffers();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw a 3d mesh with material and transform
|
|
||||||
void rlglDrawEx(Mesh mesh, Material material, Matrix transform, bool wires)
|
|
||||||
{
|
|
||||||
#if defined (GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
|
||||||
// NOTE: glPolygonMode() not available on OpenGL ES
|
|
||||||
if (wires) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_11)
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, material.texDiffuse.id);
|
|
||||||
|
|
||||||
// NOTE: On OpenGL 1.1 we use Vertex Arrays to draw model
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable texture coords array
|
|
||||||
if (mesh.normals != NULL) glEnableClientState(GL_NORMAL_ARRAY); // Enable normals array
|
|
||||||
if (mesh.colors != NULL) glEnableClientState(GL_COLOR_ARRAY); // Enable colors array
|
|
||||||
|
|
||||||
glVertexPointer(3, GL_FLOAT, 0, mesh.vertices); // Pointer to vertex coords array
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, 0, mesh.texcoords); // Pointer to texture coords array
|
|
||||||
if (mesh.normals != NULL) glNormalPointer(GL_FLOAT, 0, mesh.normals); // Pointer to normals array
|
|
||||||
if (mesh.colors != NULL) glColorPointer(4, GL_UNSIGNED_BYTE, 0, mesh.colors); // Pointer to colors array
|
|
||||||
|
|
||||||
rlPushMatrix();
|
|
||||||
rlMultMatrixf(MatrixToFloat(transform));
|
|
||||||
rlColor4ub(material.colDiffuse.r, material.colDiffuse.g, material.colDiffuse.b, material.colDiffuse.a);
|
|
||||||
|
|
||||||
if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, mesh.indices);
|
|
||||||
else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount);
|
|
||||||
rlPopMatrix();
|
|
||||||
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex array
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Disable texture coords array
|
|
||||||
if (mesh.normals != NULL) glDisableClientState(GL_NORMAL_ARRAY); // Disable normals array
|
|
||||||
if (mesh.colors != NULL) glDisableClientState(GL_NORMAL_ARRAY); // Disable colors array
|
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
|
||||||
glUseProgram(material.shader.id);
|
|
||||||
|
|
||||||
// At this point the modelview matrix just contains the view matrix (camera)
|
|
||||||
// That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
|
|
||||||
Matrix matView = modelview; // View matrix (camera)
|
|
||||||
Matrix matProjection = projection; // Projection matrix (perspective)
|
|
||||||
|
|
||||||
// Calculate model-view matrix combining matModel and matView
|
|
||||||
Matrix matModelView = MatrixMultiply(transform, matView); // Transform to camera-space coordinates
|
|
||||||
|
|
||||||
// Calculate model-view-projection matrix (MVP)
|
|
||||||
Matrix matMVP = MatrixMultiply(matModelView, matProjection); // Transform to screen-space coordinates
|
|
||||||
|
|
||||||
// Send combined model-view-projection matrix to shader
|
|
||||||
glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP));
|
|
||||||
|
|
||||||
// Apply color tinting (material.colDiffuse)
|
|
||||||
// NOTE: Just update one uniform on fragment shader
|
|
||||||
float vColor[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 };
|
|
||||||
glUniform4fv(material.shader.tintColorLoc, 1, vColor);
|
|
||||||
|
|
||||||
// Set shader textures (diffuse, normal, specular)
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, material.texDiffuse.id);
|
|
||||||
glUniform1i(material.shader.mapDiffuseLoc, 0); // Texture fits in active texture unit 0
|
|
||||||
|
|
||||||
if ((material.texNormal.id != 0) && (material.shader.mapNormalLoc != -1))
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, material.texNormal.id);
|
|
||||||
glUniform1i(material.shader.mapNormalLoc, 1); // Texture fits in active texture unit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((material.texSpecular.id != 0) && (material.shader.mapSpecularLoc != -1))
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, material.texSpecular.id);
|
|
||||||
glUniform1i(material.shader.mapSpecularLoc, 2); // Texture fits in active texture unit 2
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vaoSupported)
|
|
||||||
{
|
|
||||||
glBindVertexArray(mesh.vaoId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Bind mesh VBO data: vertex position (shader-location = 0)
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]);
|
|
||||||
glVertexAttribPointer(material.shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
|
||||||
glEnableVertexAttribArray(material.shader.vertexLoc);
|
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]);
|
|
||||||
glVertexAttribPointer(material.shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
|
||||||
glEnableVertexAttribArray(material.shader.texcoordLoc);
|
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex normals (shader-location = 2, if available)
|
|
||||||
if (material.shader.normalLoc != -1)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[2]);
|
|
||||||
glVertexAttribPointer(material.shader.normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
|
||||||
glEnableVertexAttribArray(material.shader.normalLoc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex colors (shader-location = 3, if available) , tangents, texcoords2 (if available)
|
|
||||||
if (material.shader.colorLoc != -1)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]);
|
|
||||||
glVertexAttribPointer(material.shader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
|
|
||||||
glEnableVertexAttribArray(material.shader.colorLoc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
|
|
||||||
if (material.shader.tangentLoc != -1)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[4]);
|
|
||||||
glVertexAttribPointer(material.shader.tangentLoc, 3, GL_FLOAT, 0, 0, 0);
|
|
||||||
glEnableVertexAttribArray(material.shader.tangentLoc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
|
|
||||||
if (material.shader.texcoord2Loc != -1)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[5]);
|
|
||||||
glVertexAttribPointer(material.shader.texcoord2Loc, 2, GL_FLOAT, 0, 0, 0);
|
|
||||||
glEnableVertexAttribArray(material.shader.texcoord2Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw call!
|
|
||||||
if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw
|
|
||||||
else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount);
|
|
||||||
|
|
||||||
if (material.texNormal.id != 0)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (material.texSpecular.id != 0)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0); // Set shader active texture to default 0
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
|
|
||||||
|
|
||||||
if (vaoSupported) glBindVertexArray(0); // Unbind VAO
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0); // Unbind VBOs
|
|
||||||
if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
glUseProgram(0); // Unbind shader program
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
|
|
||||||
// NOTE: glPolygonMode() not available on OpenGL ES
|
|
||||||
if (wires) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize Graphics Device (OpenGL stuff)
|
// Initialize Graphics Device (OpenGL stuff)
|
||||||
// NOTE: Stores global variables screenWidth and screenHeight
|
// NOTE: Stores global variables screenWidth and screenHeight
|
||||||
void rlglInitGraphics(int offsetX, int offsetY, int width, int height)
|
void rlglInitGraphics(int offsetX, int offsetY, int width, int height)
|
||||||
|
@ -1776,6 +1634,245 @@ void rlglLoadMesh(Mesh *mesh)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update vertex data on GPU (upload new data to one buffer)
|
||||||
|
void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex)
|
||||||
|
{
|
||||||
|
// Activate mesh VAO
|
||||||
|
if (vaoSupported) glBindVertexArray(mesh.vaoId);
|
||||||
|
|
||||||
|
switch (buffer)
|
||||||
|
{
|
||||||
|
case 0: // Update vertices (vertex position)
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]);
|
||||||
|
if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*numVertex, mesh.vertices, GL_DYNAMIC_DRAW);
|
||||||
|
else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*numVertex, mesh.vertices);
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case 1: // Update texcoords (vertex texture coordinates)
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]);
|
||||||
|
if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*numVertex, mesh.texcoords, GL_DYNAMIC_DRAW);
|
||||||
|
else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*2*numVertex, mesh.texcoords);
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case 2: // Update normals (vertex normals)
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]);
|
||||||
|
if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*numVertex, mesh.normals, GL_DYNAMIC_DRAW);
|
||||||
|
else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*numVertex, mesh.normals);
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case 3: // Update colors (vertex colors)
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[2]);
|
||||||
|
if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*numVertex, mesh.colors, GL_DYNAMIC_DRAW);
|
||||||
|
else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*numVertex, mesh.colors);
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case 4: // Update tangents (vertex tangents)
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]);
|
||||||
|
if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*numVertex, mesh.tangents, GL_DYNAMIC_DRAW);
|
||||||
|
else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*numVertex, mesh.tangents);
|
||||||
|
} break;
|
||||||
|
case 5: // Update texcoords2 (vertex second texture coordinates)
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]);
|
||||||
|
if (numVertex >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*numVertex, mesh.texcoords2, GL_DYNAMIC_DRAW);
|
||||||
|
else glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*2*numVertex, mesh.texcoords2);
|
||||||
|
} break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbind the current VAO
|
||||||
|
if (vaoSupported) glBindVertexArray(0);
|
||||||
|
|
||||||
|
// Another option would be using buffer mapping...
|
||||||
|
//mesh.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
|
||||||
|
// Now we can modify vertices
|
||||||
|
//glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw a 3d mesh with material and transform
|
||||||
|
void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||||
|
{
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_11)
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, material.texDiffuse.id);
|
||||||
|
|
||||||
|
// NOTE: On OpenGL 1.1 we use Vertex Arrays to draw model
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable texture coords array
|
||||||
|
if (mesh.normals != NULL) glEnableClientState(GL_NORMAL_ARRAY); // Enable normals array
|
||||||
|
if (mesh.colors != NULL) glEnableClientState(GL_COLOR_ARRAY); // Enable colors array
|
||||||
|
|
||||||
|
glVertexPointer(3, GL_FLOAT, 0, mesh.vertices); // Pointer to vertex coords array
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, 0, mesh.texcoords); // Pointer to texture coords array
|
||||||
|
if (mesh.normals != NULL) glNormalPointer(GL_FLOAT, 0, mesh.normals); // Pointer to normals array
|
||||||
|
if (mesh.colors != NULL) glColorPointer(4, GL_UNSIGNED_BYTE, 0, mesh.colors); // Pointer to colors array
|
||||||
|
|
||||||
|
rlPushMatrix();
|
||||||
|
rlMultMatrixf(MatrixToFloat(transform));
|
||||||
|
rlColor4ub(material.colDiffuse.r, material.colDiffuse.g, material.colDiffuse.b, material.colDiffuse.a);
|
||||||
|
|
||||||
|
if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, mesh.indices);
|
||||||
|
else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount);
|
||||||
|
rlPopMatrix();
|
||||||
|
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex array
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Disable texture coords array
|
||||||
|
if (mesh.normals != NULL) glDisableClientState(GL_NORMAL_ARRAY); // Disable normals array
|
||||||
|
if (mesh.colors != NULL) glDisableClientState(GL_NORMAL_ARRAY); // Disable colors array
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
glUseProgram(material.shader.id);
|
||||||
|
|
||||||
|
// At this point the modelview matrix just contains the view matrix (camera)
|
||||||
|
// That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
|
||||||
|
Matrix matView = modelview; // View matrix (camera)
|
||||||
|
Matrix matProjection = projection; // Projection matrix (perspective)
|
||||||
|
|
||||||
|
// Calculate model-view matrix combining matModel and matView
|
||||||
|
Matrix matModelView = MatrixMultiply(transform, matView); // Transform to camera-space coordinates
|
||||||
|
|
||||||
|
// Calculate model-view-projection matrix (MVP)
|
||||||
|
Matrix matMVP = MatrixMultiply(matModelView, matProjection); // Transform to screen-space coordinates
|
||||||
|
|
||||||
|
// Send combined model-view-projection matrix to shader
|
||||||
|
glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP));
|
||||||
|
|
||||||
|
// Apply color tinting (material.colDiffuse)
|
||||||
|
// NOTE: Just update one uniform on fragment shader
|
||||||
|
float vColor[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 };
|
||||||
|
glUniform4fv(material.shader.tintColorLoc, 1, vColor);
|
||||||
|
|
||||||
|
// Set shader textures (diffuse, normal, specular)
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, material.texDiffuse.id);
|
||||||
|
glUniform1i(material.shader.mapDiffuseLoc, 0); // Texture fits in active texture unit 0
|
||||||
|
|
||||||
|
if ((material.texNormal.id != 0) && (material.shader.mapNormalLoc != -1))
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, material.texNormal.id);
|
||||||
|
glUniform1i(material.shader.mapNormalLoc, 1); // Texture fits in active texture unit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((material.texSpecular.id != 0) && (material.shader.mapSpecularLoc != -1))
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, material.texSpecular.id);
|
||||||
|
glUniform1i(material.shader.mapSpecularLoc, 2); // Texture fits in active texture unit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vaoSupported)
|
||||||
|
{
|
||||||
|
glBindVertexArray(mesh.vaoId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Bind mesh VBO data: vertex position (shader-location = 0)
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]);
|
||||||
|
glVertexAttribPointer(material.shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||||
|
glEnableVertexAttribArray(material.shader.vertexLoc);
|
||||||
|
|
||||||
|
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]);
|
||||||
|
glVertexAttribPointer(material.shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
||||||
|
glEnableVertexAttribArray(material.shader.texcoordLoc);
|
||||||
|
|
||||||
|
// Bind mesh VBO data: vertex normals (shader-location = 2, if available)
|
||||||
|
if (material.shader.normalLoc != -1)
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[2]);
|
||||||
|
glVertexAttribPointer(material.shader.normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||||
|
glEnableVertexAttribArray(material.shader.normalLoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind mesh VBO data: vertex colors (shader-location = 3, if available) , tangents, texcoords2 (if available)
|
||||||
|
if (material.shader.colorLoc != -1)
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]);
|
||||||
|
glVertexAttribPointer(material.shader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
|
||||||
|
glEnableVertexAttribArray(material.shader.colorLoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
|
||||||
|
if (material.shader.tangentLoc != -1)
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[4]);
|
||||||
|
glVertexAttribPointer(material.shader.tangentLoc, 3, GL_FLOAT, 0, 0, 0);
|
||||||
|
glEnableVertexAttribArray(material.shader.tangentLoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
|
||||||
|
if (material.shader.texcoord2Loc != -1)
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[5]);
|
||||||
|
glVertexAttribPointer(material.shader.texcoord2Loc, 2, GL_FLOAT, 0, 0, 0);
|
||||||
|
glEnableVertexAttribArray(material.shader.texcoord2Loc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw call!
|
||||||
|
if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw
|
||||||
|
else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount);
|
||||||
|
|
||||||
|
if (material.texNormal.id != 0)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (material.texSpecular.id != 0)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0); // Set shader active texture to default 0
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
|
||||||
|
|
||||||
|
if (vaoSupported) glBindVertexArray(0); // Unbind VAO
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0); // Unbind VBOs
|
||||||
|
if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glUseProgram(0); // Unbind shader program
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unload mesh data from CPU and GPU
|
||||||
|
void rlglUnloadMesh(Mesh *mesh)
|
||||||
|
{
|
||||||
|
if (mesh->vertices != NULL) free(mesh->vertices);
|
||||||
|
if (mesh->texcoords != NULL) free(mesh->texcoords);
|
||||||
|
if (mesh->normals != NULL) free(mesh->normals);
|
||||||
|
if (mesh->colors != NULL) free(mesh->colors);
|
||||||
|
if (mesh->tangents != NULL) free(mesh->tangents);
|
||||||
|
if (mesh->texcoords2 != NULL) free(mesh->texcoords2);
|
||||||
|
if (mesh->indices != NULL) free(mesh->indices);
|
||||||
|
|
||||||
|
rlDeleteBuffers(mesh->vboId[0]); // vertex
|
||||||
|
rlDeleteBuffers(mesh->vboId[1]); // texcoords
|
||||||
|
rlDeleteBuffers(mesh->vboId[2]); // normals
|
||||||
|
rlDeleteBuffers(mesh->vboId[3]); // colors
|
||||||
|
rlDeleteBuffers(mesh->vboId[4]); // tangents
|
||||||
|
rlDeleteBuffers(mesh->vboId[5]); // texcoords2
|
||||||
|
rlDeleteBuffers(mesh->vboId[6]); // indices
|
||||||
|
|
||||||
|
rlDeleteVertexArrays(mesh->vaoId);
|
||||||
|
}
|
||||||
|
|
||||||
// Read screen pixel data (color buffer)
|
// Read screen pixel data (color buffer)
|
||||||
unsigned char *rlglReadScreenPixels(int width, int height)
|
unsigned char *rlglReadScreenPixels(int width, int height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -256,6 +256,8 @@ void rlEnableRenderTexture(unsigned int id); // Enable render texture (fbo)
|
||||||
void rlDisableRenderTexture(void); // Disable render texture (fbo), return to default framebuffer
|
void rlDisableRenderTexture(void); // Disable render texture (fbo), return to default framebuffer
|
||||||
void rlEnableDepthTest(void); // Enable depth test
|
void rlEnableDepthTest(void); // Enable depth test
|
||||||
void rlDisableDepthTest(void); // Disable depth test
|
void rlDisableDepthTest(void); // Disable depth test
|
||||||
|
void rlEnableWireMode(void); // Enable wire mode
|
||||||
|
void rlDisableWireMode(void); // Disable wire mode
|
||||||
void rlDeleteTextures(unsigned int id); // Delete OpenGL texture from GPU
|
void rlDeleteTextures(unsigned int id); // Delete OpenGL texture from GPU
|
||||||
void rlDeleteRenderTextures(RenderTexture2D target); // Delete render textures (fbo) from GPU
|
void rlDeleteRenderTextures(RenderTexture2D target); // Delete render textures (fbo) from GPU
|
||||||
void rlDeleteShader(unsigned int id); // Delete OpenGL shader program from GPU
|
void rlDeleteShader(unsigned int id); // Delete OpenGL shader program from GPU
|
||||||
|
@ -277,8 +279,11 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
|
||||||
RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments)
|
RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments)
|
||||||
void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data); // Update GPU texture with new data
|
void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data); // Update GPU texture with new data
|
||||||
void rlglGenerateMipmaps(Texture2D texture); // Generate mipmap data for selected texture
|
void rlglGenerateMipmaps(Texture2D texture); // Generate mipmap data for selected texture
|
||||||
void rlglLoadMesh(Mesh *mesh); // Upload vertex data into GPU and provided VAO/VBO ids
|
|
||||||
void rlglDrawEx(Mesh mesh, Material material, Matrix transform, bool wires);
|
void rlglLoadMesh(Mesh *mesh); // Upload vertex data into GPU and provided VAO/VBO ids
|
||||||
|
void rlglUpdateMesh(Mesh mesh, int buffer, int numVertex); // Update vertex data on GPU (upload new data to one buffer)
|
||||||
|
void rlglDrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform
|
||||||
|
void rlglUnloadMesh(Mesh *mesh); // Unload mesh data from CPU and GPU
|
||||||
|
|
||||||
Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates
|
Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue