summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRay <[email protected]>2021-03-25 14:28:12 +0100
committerRay <[email protected]>2021-03-25 14:28:12 +0100
commitcba412cc313e4f95eafb3fba9303400e65c98984 (patch)
tree672a1ae3117e96210cd4d43801748799f5740eea /src
parent9569d6a802a2230c92503456d544a5470a59d5cf (diff)
downloadraylib-cba412cc313e4f95eafb3fba9303400e65c98984.tar.gz
raylib-cba412cc313e4f95eafb3fba9303400e65c98984.zip
WARNING: BREAKING: rlgl redesign -WIP-
rlgl module has been completely redesigned to move Mesh/Material structures to [models] module. Still some work to do, broken elements: - [models] OpenGL 1.1 mesh rendering: DrawMesh() - [models] Mesh Instancing: DrawMeshInstanced() - [models] Stereo rendering: DrawMesh() - [models] GL_FLOAT, GL_UNSIGNED_INT exposed - [models] GenMeshCustom() - [rlgl] GenTexture*() functions removal?
Diffstat (limited to 'src')
-rw-r--r--src/core.c6
-rw-r--r--src/models.c392
-rw-r--r--src/raylib.h111
-rw-r--r--src/rlgl.h943
-rw-r--r--src/shapes.c36
-rw-r--r--src/textures.c12
6 files changed, 732 insertions, 768 deletions
diff --git a/src/core.c b/src/core.c
index 99b4fa28..d4f9f4fc 100644
--- a/src/core.c
+++ b/src/core.c
@@ -2082,13 +2082,13 @@ void UnloadShader(Shader shader)
// Begin custom shader mode
void BeginShaderMode(Shader shader)
{
- rlSetShaderActive(shader);
+ rlSetShader(shader);
}
// End custom shader mode (returns to default shader)
void EndShaderMode(void)
{
- BeginShaderMode(rlGetShaderDefault());
+ rlSetShader(rlGetShaderDefault());
}
// Get shader uniform location
@@ -2129,7 +2129,7 @@ void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat)
void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture)
{
rlEnableShader(shader.id);
- rlSetUniformSampler(locIndex, texture);
+ rlSetUniformSampler(locIndex, texture.id);
//rlDisableShader();
}
diff --git a/src/models.c b/src/models.c
index af2f6d97..a7814416 100644
--- a/src/models.c
+++ b/src/models.c
@@ -386,7 +386,7 @@ void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float hei
rlCheckRenderBatchLimit(36);
- rlEnableTexture(texture.id);
+ rlSetTexture(texture.id);
//rlPushMatrix();
// NOTE: Transformation is applied in inverse order (scale -> rotate -> translate)
@@ -435,7 +435,7 @@ void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float hei
rlEnd();
//rlPopMatrix();
- rlDisableTexture();
+ rlSetTexture(0);
}
// Draw sphere
@@ -725,7 +725,7 @@ Model LoadModel(const char *fileName)
else
{
// Upload vertex data to GPU (static mesh)
- for (int i = 0; i < model.meshCount; i++) rlLoadMesh(&model.meshes[i], false);
+ for (int i = 0; i < model.meshCount; i++) UploadMesh(&model.meshes[i], false);
}
if (model.materialCount == 0)
@@ -813,29 +813,356 @@ void UnloadModelKeepMeshes(Model model)
TRACELOG(LOG_INFO, "MODEL: Unloaded model (but not meshes) from RAM and VRAM");
}
-// Load meshes from model file
-Mesh *LoadMeshes(const char *fileName, int *meshCount)
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_FLOAT 0x1406
+
+// Upload vertex data into a VAO (if supported) and VBO
+void UploadMesh(Mesh *mesh, bool dynamic)
{
- Mesh *meshes = NULL;
- int count = 0;
+ if (mesh->vaoId > 0)
+ {
+ // Check if mesh has already been loaded in GPU
+ TRACELOG(LOG_WARNING, "VAO: [ID %i] Trying to re-load an already loaded mesh", mesh->vaoId);
+ return;
+ }
+
+ mesh->vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VERTEX_BUFFERS, sizeof(unsigned int));
+
+ mesh->vaoId = 0; // Vertex Array Object
+ mesh->vboId[0] = 0; // Vertex positions VBO
+ mesh->vboId[1] = 0; // Vertex texcoords VBO
+ mesh->vboId[2] = 0; // Vertex normals VBO
+ mesh->vboId[3] = 0; // Vertex colors VBO
+ mesh->vboId[4] = 0; // Vertex tangents VBO
+ mesh->vboId[5] = 0; // Vertex texcoords2 VBO
+ mesh->vboId[6] = 0; // Vertex indices VBO
+
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ mesh->vaoId = rlLoadVertexArray();
+ rlEnableVertexArray(mesh->vaoId);
+
+ // NOTE: Attributes must be uploaded considering default locations points
+
+ // Enable vertex attributes: position (shader-location = 0)
+ mesh->vboId[0] = rlLoadVertexBuffer(mesh->vertices, mesh->vertexCount*3*sizeof(float), dynamic);
+ rlSetVertexAttribute(0, 3, GL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(0);
+
+ // Enable vertex attributes: texcoords (shader-location = 1)
+ mesh->vboId[1] = rlLoadVertexBuffer(mesh->texcoords, mesh->vertexCount*2*sizeof(float), dynamic);
+ rlSetVertexAttribute(1, 2, GL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(1);
+
+ if (mesh->normals != NULL)
+ {
+ // Enable vertex attributes: normals (shader-location = 2)
+ mesh->vboId[2] = rlLoadVertexBuffer(mesh->normals, mesh->vertexCount*3*sizeof(float), dynamic);
+ rlSetVertexAttribute(2, 3, GL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(2);
+ }
+ else
+ {
+ // Default color vertex attribute set to WHITE
+ float value[3] = { 1.0f, 1.0f, 1.0f };
+ rlSetVertexAttributeDefault(2, value, SHADER_ATTRIB_VEC3, 3);
+ rlDisableVertexAttribute(2);
+ }
+
+ if (mesh->colors != NULL)
+ {
+ // Enable vertex attribute: color (shader-location = 3)
+ mesh->vboId[3] = rlLoadVertexBuffer(mesh->colors, mesh->vertexCount*4*sizeof(unsigned char), dynamic);
+ rlSetVertexAttribute(3, 4, GL_UNSIGNED_BYTE, 1, 0, 0);
+ rlEnableVertexAttribute(3);
+ }
+ else
+ {
+ // Default color vertex attribute set to WHITE
+ float value[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ rlSetVertexAttributeDefault(3, value, SHADER_ATTRIB_VEC4, 4);
+ rlDisableVertexAttribute(3);
+ }
+
+ if (mesh->tangents != NULL)
+ {
+ // Enable vertex attribute: tangent (shader-location = 4)
+ mesh->vboId[4] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), dynamic);
+ rlSetVertexAttribute(4, 4, GL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(4);
+ }
+ else
+ {
+ // Default tangents vertex attribute
+ float value[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ rlSetVertexAttributeDefault(4, value, SHADER_ATTRIB_VEC4, 4);
+ rlDisableVertexAttribute(4);
+ }
+
+ if (mesh->texcoords2 != NULL)
+ {
+ // Enable vertex attribute: texcoord2 (shader-location = 5)
+ mesh->vboId[5] = rlLoadVertexBuffer(mesh->texcoords2, mesh->vertexCount*2*sizeof(float), dynamic);
+ rlSetVertexAttribute(5, 2, GL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(5);
+ }
+ else
+ {
+ // Default texcoord2 vertex attribute
+ float value[2] = { 0.0f, 0.0f };
+ rlSetVertexAttributeDefault(5, value, SHADER_ATTRIB_VEC2, 2);
+ rlDisableVertexAttribute(5);
+ }
- // TODO: Load meshes from file (OBJ, IQM, GLTF)
+ if (mesh->indices != NULL)
+ {
+ mesh->vboId[6] = rlLoadVertexBufferElement(mesh->indices, mesh->triangleCount*3*sizeof(unsigned short), dynamic);
+ }
- *meshCount = count;
- return meshes;
+ if (mesh->vaoId > 0) TRACELOG(LOG_INFO, "VAO: [ID %i] Mesh uploaded successfully to VRAM (GPU)", mesh->vaoId);
+ else TRACELOG(LOG_INFO, "VBO: Mesh uploaded successfully to VRAM (GPU)");
+
+ rlDisableVertexArray();
+#endif
}
-// Upload mesh vertex data to GPU
-void UploadMesh(Mesh *mesh)
+// Draw a 3d mesh with material and transform
+void DrawMesh(Mesh mesh, Material material, Matrix transform)
{
- rlLoadMesh(mesh, false); // Static mesh by default
+#if defined(GRAPHICS_API_OPENGL_11)
+/*
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, material.maps[MATERIAL_MAP_DIFFUSE].texture.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.maps[MATERIAL_MAP_DIFFUSE].color.r, material.maps[MATERIAL_MAP_DIFFUSE].color.g, material.maps[MATERIAL_MAP_DIFFUSE].color.b, material.maps[MATERIAL_MAP_DIFFUSE].color.a);
+
+ if (mesh.indices != NULL) glDrawArrayElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, mesh.indices);
+ else glDrawArrays(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)
+ // Bind shader program
+ rlEnableShader(material.shader.id);
+
+ // Matrices and other values required by shader
+ //-----------------------------------------------------
+ // Calculate and send to shader model matrix
+ if (material.shader.locs[SHADER_LOC_MATRIX_MODEL] != -1)
+ {
+ rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MODEL], transform);
+ }
+
+ // Upload to shader material.colDiffuse
+ if (material.shader.locs[SHADER_LOC_COLOR_DIFFUSE] != -1)
+ {
+ float values[4] = {
+ (float)material.maps[MATERIAL_MAP_DIFFUSE].color.r/255.0f,
+ (float)material.maps[MATERIAL_MAP_DIFFUSE].color.g/255.0f,
+ (float)material.maps[MATERIAL_MAP_DIFFUSE].color.b/255.0f,
+ (float)material.maps[MATERIAL_MAP_DIFFUSE].color.a/255.0f
+ };
+
+ rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_DIFFUSE], values, SHADER_UNIFORM_VEC4, 1);
+ }
+
+ // Upload to shader material.colSpecular (if available)
+ if (material.shader.locs[SHADER_LOC_COLOR_SPECULAR] != -1)
+ {
+ float values[4] = {
+ (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.r/255.0f,
+ (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.g/255.0f,
+ (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.b/255.0f,
+ (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.a/255.0f
+ };
+
+ rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_SPECULAR], values, SHADER_UNIFORM_VEC4, 1);
+ }
+
+ if (material.shader.locs[SHADER_LOC_MATRIX_VIEW] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_VIEW], rlGetMatrixModelview());
+ if (material.shader.locs[SHADER_LOC_MATRIX_PROJECTION] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_PROJECTION], rlGetMatrixProjection());
+
+ // At this point the modelview matrix just contains the view matrix (camera)
+ // That's because BeginMode3D() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
+ Matrix matView = rlGetMatrixModelview(); // View matrix (camera)
+ Matrix matProjection = rlGetMatrixProjection(); // Projection matrix (perspective)
+
+ // Accumulate several transformations:
+ // matView: rlgl internal modelview matrix (actually, just view matrix)
+ // rlGetMatrixTransform(): rlgl internal transform matrix due to push/pop matrix stack
+ // transform: function parameter transformation
+ Matrix matModelView = MatrixMultiply(transform, MatrixMultiply(rlGetMatrixTransform(), matView));
+ //-----------------------------------------------------
+
+ // Bind active texture maps (if available)
+ for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
+ {
+ if (material.maps[i].texture.id > 0)
+ {
+ // Select current shader texture slot
+ rlActiveTextureSlot(i);
+
+ // Enable texture for active slot
+ if ((i == MATERIAL_MAP_IRRADIANCE) ||
+ (i == MATERIAL_MAP_PREFILTER) ||
+ (i == MATERIAL_MAP_CUBEMAP)) rlEnableTextureCubemap(material.maps[i].texture.id);
+ else rlEnableTexture(material.maps[i].texture.id);
+
+ rlSetUniform(material.shader.locs[SHADER_LOC_MAP_DIFFUSE + i], &i, SHADER_UNIFORM_INT, 1);
+ }
+ }
+
+ // Try binding vertex array objects (VAO)
+ // or use VBOs if not possible
+ if (!rlEnableVertexArray(mesh.vaoId))
+ {
+ // Bind mesh VBO data: vertex position (shader-location = 0)
+ rlEnableVertexBuffer(mesh.vboId[0]);
+ rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
+
+ rlEnableVertexBuffer(mesh.vboId[0]);
+ rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
+
+ // Bind mesh VBO data: vertex texcoords (shader-location = 1)
+ rlEnableVertexBuffer(mesh.vboId[1]);
+ rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01]);
+
+ if (material.shader.locs[SHADER_LOC_VERTEX_NORMAL] != -1)
+ {
+ // Bind mesh VBO data: vertex normals (shader-location = 2)
+ rlEnableVertexBuffer(mesh.vboId[2]);
+ rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL], 3, GL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL]);
+ }
+
+ // Bind mesh VBO data: vertex colors (shader-location = 3, if available)
+ if (material.shader.locs[SHADER_LOC_VERTEX_COLOR] != -1)
+ {
+ if (mesh.vboId[3] != 0)
+ {
+ rlEnableVertexBuffer(mesh.vboId[3]);
+ rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, 1, 0, 0);
+ rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
+ }
+ else
+ {
+ // Set default value for unused attribute
+ // NOTE: Required when using default shader and no VAO support
+ float value[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ rlSetVertexAttributeDefault(material.shader.locs[SHADER_LOC_VERTEX_COLOR], value, SHADER_ATTRIB_VEC2, 4);
+ rlDisableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
+ }
+ }
+
+ // Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
+ if (material.shader.locs[SHADER_LOC_VERTEX_TANGENT] != -1)
+ {
+ rlEnableVertexBuffer(mesh.vboId[4]);
+ rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT], 4, GL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT]);
+ }
+
+ // Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
+ if (material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] != -1)
+ {
+ rlEnableVertexBuffer(mesh.vboId[5]);
+ rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, GL_FLOAT, 0, 0, 0);
+ rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
+ }
+
+ if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]);
+ }
+
+ //rlDrawVertexData(int vertexCount, Matrix matModelView, bool stereo)
+
+ int eyesCount = 1;
+ //if (RLGL.State.stereoRender) eyesCount = 2;
+
+ for (int eye = 0; eye < eyesCount; eye++)
+ {
+ if (eyesCount == 1) rlSetMatrixModelview(matModelView);
+ else
+ {
+ // Setup current eye viewport (half screen width)
+ //rlViewport(eye*rlGetFramebufferWidth()/2, 0, rlGetFramebufferWidth()/2, rlGetFramebufferHeight());
+
+ // Set current eye view offset to modelview matrix
+ //rlSetMatrixModelview(MatrixMultiply(matModelView, RLGL.State.offsetStereo[eye]));
+
+ // Set current eye projection matrix
+ //rlSetMatrixProjection(RLGL.State.projectionStereo[eye]);
+ }
+
+ // Calculate model-view-projection matrix (MVP)
+ Matrix matMVP = MatrixMultiply(rlGetMatrixModelview(), rlGetMatrixProjection()); // Transform to screen-space coordinates
+
+ // Send combined model-view-projection matrix to shader
+ rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MVP], matMVP);
+
+ // Draw calls
+ if (mesh.indices != NULL) rlDrawVertexArrayElements(0, mesh.triangleCount*3);
+ else rlDrawVertexArray(0, mesh.vertexCount);
+ }
+
+ // Unbind all binded texture maps
+ for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
+ {
+ // Select current shader texture slot
+ rlActiveTextureSlot(i);
+
+ // Disable texture for active slot
+ if ((i == MATERIAL_MAP_IRRADIANCE) ||
+ (i == MATERIAL_MAP_PREFILTER) ||
+ (i == MATERIAL_MAP_CUBEMAP)) rlDisableTextureCubemap();
+ else rlDisableTexture();
+ }
+
+ // Disable all possible vertex array objects (or VBOs)
+ rlDisableVertexArray();
+ rlDisableVertexBuffer();
+ rlDisableVertexBufferElement();
+
+ // Disable shader program
+ rlDisableShader();
+
+ // Restore rlgl internal modelview and projection matrices
+ rlSetMatrixModelview(matView);
+ rlSetMatrixProjection(matProjection);
+#endif
}
-// Unload mesh from memory (RAM and/or VRAM)
+// Unload mesh from memory (RAM and VRAM)
void UnloadMesh(Mesh mesh)
{
// Unload rlgl mesh vboId data
- rlUnloadMesh(&mesh);
+ rlUnloadVertexArray(mesh.vaoId);
+
+ for (int i = 0; i < MAX_MESH_VERTEX_BUFFERS; i++) rlUnloadVertexBuffer(mesh.vboId[i]);
+ RL_FREE(mesh.vboId);
RL_FREE(mesh.vertices);
RL_FREE(mesh.texcoords);
@@ -918,6 +1245,7 @@ bool ExportMesh(Mesh mesh, const char *fileName)
return success;
}
+
// Load materials from model file
Material *LoadMaterials(const char *fileName, int *materialCount)
{
@@ -1076,8 +1404,8 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
}
// Upload new vertex data to GPU for model drawing
- rlUpdateBuffer(model.meshes[m].vboId[0], model.meshes[m].animVertices, model.meshes[m].vertexCount*3*sizeof(float)); // Update vertex position
- rlUpdateBuffer(model.meshes[m].vboId[2], model.meshes[m].animNormals, model.meshes[m].vertexCount*3*sizeof(float)); // Update vertex normals
+ rlUpdateVertexBuffer(model.meshes[m].vboId[0], model.meshes[m].animVertices, model.meshes[m].vertexCount*3*sizeof(float), 0); // Update vertex position
+ rlUpdateVertexBuffer(model.meshes[m].vboId[2], model.meshes[m].animNormals, model.meshes[m].vertexCount*3*sizeof(float), 0); // Update vertex normals
}
}
}
@@ -1180,8 +1508,8 @@ Mesh GenMeshPoly(int sides, float radius)
RL_FREE(texcoords);
// Upload vertex data to GPU (static mesh)
- // NOTE: mesh.vboId array is allocated inside rlLoadMesh()
- rlLoadMesh(&mesh, false);
+ // NOTE: mesh.vboId array is allocated inside UploadMesh()
+ UploadMesh(&mesh, false);
return mesh;
}
@@ -1314,7 +1642,7 @@ Mesh GenMeshPlane(float width, float length, int resX, int resZ)
#endif
// Upload vertex data to GPU (static mesh)
- rlLoadMesh(&mesh, false);
+ UploadMesh(&mesh, false);
return mesh;
}
@@ -1479,7 +1807,7 @@ par_shapes_mesh* par_shapes_create_icosahedron(); // 20 sides polyhedron
#endif
// Upload vertex data to GPU (static mesh)
- rlLoadMesh(&mesh, false);
+ UploadMesh(&mesh, false);
return mesh;
}
@@ -1519,7 +1847,7 @@ RLAPI Mesh GenMeshSphere(float radius, int rings, int slices)
par_shapes_free_mesh(sphere);
// Upload vertex data to GPU (static mesh)
- rlLoadMesh(&mesh, false);
+ UploadMesh(&mesh, false);
}
else TRACELOG(LOG_WARNING, "MESH: Failed to generate mesh: sphere");
@@ -1563,7 +1891,7 @@ RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices)
par_shapes_free_mesh(sphere);
// Upload vertex data to GPU (static mesh)
- rlLoadMesh(&mesh, false);
+ UploadMesh(&mesh, false);
}
else TRACELOG(LOG_WARNING, "MESH: Failed to generate mesh: hemisphere");
@@ -1626,7 +1954,7 @@ Mesh GenMeshCylinder(float radius, float height, int slices)
par_shapes_free_mesh(cylinder);
// Upload vertex data to GPU (static mesh)
- rlLoadMesh(&mesh, false);
+ UploadMesh(&mesh, false);
}
else TRACELOG(LOG_WARNING, "MESH: Failed to generate mesh: cylinder");
@@ -1672,7 +2000,7 @@ Mesh GenMeshTorus(float radius, float size, int radSeg, int sides)
par_shapes_free_mesh(torus);
// Upload vertex data to GPU (static mesh)
- rlLoadMesh(&mesh, false);
+ UploadMesh(&mesh, false);
}
else TRACELOG(LOG_WARNING, "MESH: Failed to generate mesh: torus");
@@ -1716,7 +2044,7 @@ Mesh GenMeshKnot(float radius, float size, int radSeg, int sides)
par_shapes_free_mesh(knot);
// Upload vertex data to GPU (static mesh)
- rlLoadMesh(&mesh, false);
+ UploadMesh(&mesh, false);
}
else TRACELOG(LOG_WARNING, "MESH: Failed to generate mesh: knot");
@@ -1853,7 +2181,7 @@ Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
UnloadImageColors(pixels); // Unload pixels color data
// Upload vertex data to GPU (static mesh)
- rlLoadMesh(&mesh, false);
+ UploadMesh(&mesh, false);
return mesh;
}
@@ -2204,7 +2532,7 @@ Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
UnloadImageColors(pixels); // Unload pixels color data
// Upload vertex data to GPU (static mesh)
- rlLoadMesh(&mesh, false);
+ UploadMesh(&mesh, false);
return mesh;
}
@@ -2315,7 +2643,7 @@ void MeshTangents(Mesh *mesh)
RL_FREE(tan2);
// Load a new tangent attributes buffer
- mesh->vboId[SHADER_LOC_VERTEX_TANGENT] = rlLoadVertexBuffer(mesh->vaoId, SHADER_LOC_VERTEX_TANGENT, mesh->tangents, mesh->vertexCount*4*sizeof(float), false);
+ mesh->vboId[SHADER_LOC_VERTEX_TANGENT] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), false);
TRACELOG(LOG_INFO, "MESH: Tangents data computed for provided mesh");
}
@@ -2367,7 +2695,7 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
colorTint.a = (unsigned char)((((float)color.a/255.0)*((float)tint.a/255.0))*255.0f);
model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color = colorTint;
- rlDrawMesh(model.meshes[i], model.materials[model.meshMaterial[i]], model.transform);
+ DrawMesh(model.meshes[i], model.materials[model.meshMaterial[i]], model.transform);
model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color = color;
}
}
@@ -2433,7 +2761,7 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector
rlCheckRenderBatchLimit(4);
- rlEnableTexture(texture.id);
+ rlSetTexture(texture.id);
rlBegin(RL_QUADS);
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
@@ -2455,7 +2783,7 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector
rlVertex3f(b.x, b.y, b.z);
rlEnd();
- rlDisableTexture();
+ rlSetTexture(0);
}
// Draw a bounding box with wires
diff --git a/src/raylib.h b/src/raylib.h
index fcf820a9..3ca9819a 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -701,6 +701,35 @@ typedef enum {
GAMEPAD_AXIS_RIGHT_TRIGGER = 5 // [1..-1] (pressure-level)
} GamepadAxis;
+// Mesh vertex attributes
+typedef enum {
+ MESH_VERTEX_POSITION = 1,
+ MESH_VERTEX_TEXCOORD1 = 2,
+ MESH_VERTEX_TEXCOORD2 = 4,
+ MESH_VERTEX_NORMAL = 8,
+ MESH_VERTEX_TANGENT = 16,
+ MESH_VERTEX_COLOR = 32,
+ MESH_VERTEX_INDEX = 64
+} MeshVertexAttributes;
+
+// Material map index
+typedef enum {
+ MATERIAL_MAP_ALBEDO = 0, // MATERIAL_MAP_DIFFUSE
+ MATERIAL_MAP_METALNESS = 1, // MATERIAL_MAP_SPECULAR
+ MATERIAL_MAP_NORMAL = 2,
+ MATERIAL_MAP_ROUGHNESS = 3,
+ MATERIAL_MAP_OCCLUSION,
+ MATERIAL_MAP_EMISSION,
+ MATERIAL_MAP_HEIGHT,
+ MATERIAL_MAP_BRDG,
+ MATERIAL_MAP_CUBEMAP, // NOTE: Uses GL_TEXTURE_CUBE_MAP
+ MATERIAL_MAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
+ MATERIAL_MAP_PREFILTER // NOTE: Uses GL_TEXTURE_CUBE_MAP
+} MaterialMapIndex;
+
+#define MATERIAL_MAP_DIFFUSE MATERIAL_MAP_ALBEDO
+#define MATERIAL_MAP_SPECULAR MATERIAL_MAP_METALNESS
+
// Shader location index
typedef enum {
SHADER_LOC_VERTEX_POSITION = 0,
@@ -746,24 +775,6 @@ typedef enum {
SHADER_UNIFORM_SAMPLER2D
} ShaderUniformDataType;
-// Material map index
-typedef enum {
- MATERIAL_MAP_ALBEDO = 0, // MATERIAL_MAP_DIFFUSE
- MATERIAL_MAP_METALNESS = 1, // MATERIAL_MAP_SPECULAR
- MATERIAL_MAP_NORMAL = 2,
- MATERIAL_MAP_ROUGHNESS = 3,
- MATERIAL_MAP_OCCLUSION,
- MATERIAL_MAP_EMISSION,
- MATERIAL_MAP_HEIGHT,
- MATERIAL_MAP_BRDG,
- MATERIAL_MAP_CUBEMAP, // NOTE: Uses GL_TEXTURE_CUBE_MAP
- MATERIAL_MAP_IRRADIANCE, // NOTE: Uses GL_TEXTURE_CUBE_MAP
- MATERIAL_MAP_PREFILTER // NOTE: Uses GL_TEXTURE_CUBE_MAP
-} MaterialMapIndex;
-
-#define MATERIAL_MAP_DIFFUSE MATERIAL_MAP_ALBEDO
-#define MATERIAL_MAP_SPECULAR MATERIAL_MAP_METALNESS
-
// Pixel formats
// NOTE: Support depends on OpenGL version and platform
typedef enum {
@@ -1359,47 +1370,49 @@ RLAPI void DrawGrid(int slices, float spacing);
//------------------------------------------------------------------------------------
// Model loading/unloading functions
-RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
-RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
-RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM)
-RLAPI void UnloadModelKeepMeshes(Model model); // Unload model (but not meshes) from memory (RAM and/or VRAM)
+RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
+RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
+RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM)
+RLAPI void UnloadModelKeepMeshes(Model model); // Unload model (but not meshes) from memory (RAM and/or VRAM)
// Mesh loading/unloading functions
-RLAPI Mesh *LoadMeshes(const char *fileName, int *meshCount); // Load meshes from model file
-RLAPI void UploadMesh(Mesh *mesh); // Upload mesh vertex data to GPU (VRAM)
-RLAPI void UnloadMesh(Mesh mesh); // Unload mesh from memory (RAM and/or VRAM)
-RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success
+RLAPI void UploadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids
+RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform
+RLAPI void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int count); // Draw a 3d mesh with material and transform
+RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU
+RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success
// Material loading/unloading functions
-RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
-RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
-RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
-RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
-RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh
+RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
+RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
+RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
+RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
+RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh
// Model animations loading/unloading functions
-RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animsCount); // Load model animations from file
-RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose
-RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data
-RLAPI void UnloadModelAnimations(ModelAnimation* animations, unsigned int count); // Unload animation array data
-RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
+RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animsCount); // Load model animations from file
+RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose
+RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data
+RLAPI void UnloadModelAnimations(ModelAnimation* animations, unsigned int count); // Unload animation array data
+RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
// Mesh generation functions
-RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh
-RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions)
-RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh
-RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere)
-RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap)
-RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh
-RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh
-RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh
-RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data
-RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
+RLAPI Mesh GenMeshCustom(int vertexCount, int flags); // Generate custom empty mesh (data initialized to 0)
+RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh
+RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions)
+RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh
+RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere)
+RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap)
+RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh
+RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh
+RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh
+RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data
+RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
// Mesh manipulation functions
-RLAPI BoundingBox MeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
-RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents
-RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals
+RLAPI BoundingBox MeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
+RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents
+RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals
// Model drawing functions
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
diff --git a/src/rlgl.h b/src/rlgl.h
index f61bb6ba..e1c16104 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -283,6 +283,14 @@ typedef struct RenderBatch {
float currentDepth; // Current depth value for next draw
} RenderBatch;
+// Shader attribute data types
+typedef enum {
+ SHADER_ATTRIB_FLOAT = 0,
+ SHADER_ATTRIB_VEC2,
+ SHADER_ATTRIB_VEC3,
+ SHADER_ATTRIB_VEC4
+} ShaderAttributeDataType;
+
#if defined(RLGL_STANDALONE)
#ifndef __cplusplus
// Boolean type
@@ -321,49 +329,12 @@ typedef struct RenderBatch {
// TextureCubemap type, actually, same as Texture
typedef Texture TextureCubemap;
- // Vertex data definning a mesh
- typedef struct Mesh {
- int vertexCount; // number of vertices stored in arrays
- int triangleCount; // number of triangles stored (indexed or not)
- float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0)
- float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
- float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
- float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
- float *tangents; // vertex tangents (XYZW - 4 components per vertex) (shader-location = 4)
- unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
- unsigned short *indices;// vertex indices (in case vertex data comes indexed)
-
- // Animation vertex data
- float *animVertices; // Animated vertex positions (after bones transformations)
- float *animNormals; // Animated normals (after bones transformations)
- int *boneIds; // Vertex bone ids, up to 4 bones influence by vertex (skinning)
- float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning)
-
- // OpenGL identifiers
- unsigned int vaoId; // OpenGL Vertex Array Object id
- unsigned int *vboId; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
- } Mesh;
-
// Shader type (generic)
typedef struct Shader {
unsigned int id; // Shader program id
int *locs; // Shader locations array (MAX_SHADER_LOCATIONS)
} Shader;
- // Material texture map
- typedef struct MaterialMap {
- Texture2D texture; // Material map texture
- Color color; // Material map color
- float value; // Material map value
- } MaterialMap;
-
- // Material type (generic)
- typedef struct Material {
- Shader shader; // Material shader
- MaterialMap *maps; // Material maps (MAX_MATERIAL_MAPS)
- float params[4]; // Material generic parameters (if required)
- } Material;
-
// TraceLog message types
typedef enum {
LOG_ALL,
@@ -459,6 +430,9 @@ typedef struct RenderBatch {
SHADER_LOC_MAP_PREFILTER,
SHADER_LOC_MAP_BRDF
} ShaderLocationIndex;
+
+ #define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO
+ #define SHADER_LOC_MAP_SPECULAR SHADER_LOC_MAP_METALNESS
// Shader uniform data types
typedef enum {
@@ -473,9 +447,6 @@ typedef struct RenderBatch {
SHADER_UNIFORM_SAMPLER2D
} ShaderUniformDataType;
- #define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO
- #define SHADER_LOC_MAP_SPECULAR SHADER_LOC_MAP_METALNESS
-
// Material map type
typedef enum {
MATERIAL_MAP_ALBEDO = 0, // MATERIAL_MAP_DIFFUSE
@@ -533,35 +504,56 @@ RLAPI void rlColor4f(float x, float y, float z, float w); // Define one vertex (
// NOTE: This functions are used to completely abstract raylib code from OpenGL layer,
// some of them are direct wrappers over OpenGL calls, some others are custom
//------------------------------------------------------------------------------------
-RLAPI void rlEnableTexture(unsigned int id); // Enable texture usage
-RLAPI void rlDisableTexture(void); // Disable texture usage
+
+// Vertex buffers state
+RLAPI bool rlEnableVertexArray(unsigned int vaoId); // Enable vertex array (VAO, if supported)
+RLAPI void rlDisableVertexArray(void); // Disable vertex array (VAO, if supported)
+RLAPI void rlEnableVertexBuffer(unsigned int id); // Enable vertex buffer (VBO)
+RLAPI void rlDisableVertexBuffer(void); // Disable vertex buffer (VBO)
+RLAPI void rlEnableVertexBufferElement(unsigned int id);// Enable vertex buffer element (VBO element)
+RLAPI void rlDisableVertexBufferElement(void); // Disable vertex buffer element (VBO element)
+RLAPI void rlEnableVertexAttribute(unsigned int index); // Enable vertex attribute index
+RLAPI void rlDisableVertexAttribute(unsigned int index);// Disable vertex attribute index
+
+// Textures state
+RLAPI void rlActiveTextureSlot(int slot); // Select and active a texture slot
+RLAPI void rlEnableTexture(unsigned int id); // Enable texture
+RLAPI void rlDisableTexture(void); // Disable texture
+RLAPI void rlEnableTextureCubemap(unsigned int id); // Enable texture cubemap
+RLAPI void rlDisableTextureCubemap(void); // Disable texture cubemap
RLAPI void rlTextureParameters(unsigned int id, int param, int value); // Set texture parameters (filter, wrap)
-RLAPI void rlEnableShader(unsigned int id); // Enable shader program usage
-RLAPI void rlDisableShader(void); // Disable shader program usage
-RLAPI void rlEnableFramebuffer(unsigned int id); // Enable render texture (fbo)
-RLAPI void rlDisableFramebuffer(void); // Disable render texture (fbo), return to default framebuffer
-RLAPI void rlEnableDepthTest(void); // Enable depth test
-RLAPI void rlDisableDepthTest(void); // Disable depth test
-RLAPI void rlEnableDepthMask(void); // Enable depth write
-RLAPI void rlDisableDepthMask(void); // Disable depth write
-RLAPI void rlEnableBackfaceCulling(void); // Enable backface culling
-RLAPI void rlDisableBackfaceCulling(void); // Disable backface culling
-RLAPI void rlEnableScissorTest(void); // Enable scissor test
-RLAPI void rlDisableScissorTest(void); // Disable scissor test
+
+// Shader state
+RLAPI void rlEnableShader(unsigned int id); // Enable shader program
+RLAPI void rlDisableShader(void); // Disable shader program
+
+// Framebuffer state
+RLAPI void rlEnableFramebuffer(unsigned int id); // Enable render texture (fbo)
+RLAPI void rlDisableFramebuffer(void); // Disable render texture (fbo), return to default framebuffer
+
+// General render state
+RLAPI void rlEnableDepthTest(void); // Enable depth test
+RLAPI void rlDisableDepthTest(void); // Disable depth test
+RLAPI void rlEnableDepthMask(void); // Enable depth write
+RLAPI void rlDisableDepthMask(void); // Disable depth write
+RLAPI void rlEnableBackfaceCulling(void); // Enable backface culling
+RLAPI void rlDisableBackfaceCulling(void); // Disable backface culling
+RLAPI void rlEnableScissorTest(void); // Enable scissor test
+RLAPI void rlDisableScissorTest(void); // Disable scissor test
RLAPI void rlScissor(int x, int y, int width, int height); // Scissor test
-RLAPI void rlEnableWireMode(void); // Enable wire mode
-RLAPI void rlDisableWireMode(void); // Disable wire mode
-RLAPI void rlSetLineWidth(float width); // Set the line drawing width
-RLAPI float rlGetLineWidth(void); // Get the line drawing width
-RLAPI void rlEnableSmoothLines(void); // Enable line aliasing
-RLAPI void rlDisableSmoothLines(void); // Disable line aliasing
-RLAPI void rlEnableStereoRender(void); // Enable stereo rendering
-RLAPI void rlDisableStereoRender(void); // Disable stereo rendering
+RLAPI void rlEnableWireMode(void); // Enable wire mode
+RLAPI void rlDisableWireMode(void); // Disable wire mode
+RLAPI void rlSetLineWidth(float width); // Set the line drawing width
+RLAPI float rlGetLineWidth(void); // Get the line drawing width
+RLAPI void rlEnableSmoothLines(void); // Enable line aliasing
+RLAPI void rlDisableSmoothLines(void); // Disable line aliasing
+RLAPI void rlEnableStereoRender(void); // Enable stereo rendering
+RLAPI void rlDisableStereoRender(void); // Disable stereo rendering
RLAPI void rlClearColor(unsigned char r, unsigned char g, unsigned char b, unsigned char a); // Clear color buffer with color
-RLAPI void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
-RLAPI void rlCheckErrors(void); // Check and log OpenGL error codes
-RLAPI void rlSetBlendMode(int mode); // Set blending mode
+RLAPI void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
+RLAPI void rlCheckErrors(void); // Check and log OpenGL error codes
+RLAPI void rlSetBlendMode(int mode); // Set blending mode
RLAPI void rlSetBlendFactors(int glSrcFactor, int glDstFactor, int glEquation); // Set blending mode factor and equation (using OpenGL factors)
//------------------------------------------------------------------------------------
@@ -588,8 +580,23 @@ RLAPI void rlDrawRenderBatch(RenderBatch *batch); // Dra
RLAPI void rlSetRenderBatchActive(RenderBatch *batch); // Set the active render batch for rlgl (NULL for default internal)
RLAPI void rlDrawRenderBatchActive(void); // Update and draw internal render batch
RLAPI bool rlCheckRenderBatchLimit(int vCount); // Check internal buffer overflow for a given number of vertex
-
-// Textures data management
+RLAPI void rlSetTexture(unsigned int id); // Set current texture for render batch and check buffers limits
+
+//------------------------------------------------------------------------------------------------------------------------
+
+// Vertex buffers management
+RLAPI unsigned int rlLoadVertexArray(void); // Load vertex array (vao) if supported
+RLAPI unsigned int rlLoadVertexBuffer(void *buffer, int size, bool dynamic); // Load a vertex buffer attribute
+RLAPI unsigned int rlLoadVertexBufferElement(void *buffer, int size, bool dynamic); // Load a new attributes element buffer
+RLAPI void rlUpdateVertexBuffer(int bufferId, void *data, int dataSize, int offset); // Update GPU buffer with new data
+RLAPI void rlUnloadVertexArray(unsigned int vaoId);
+RLAPI void rlUnloadVertexBuffer(unsigned int vboId);
+RLAPI void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, void *pointer);
+RLAPI void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count); // Set vertex attribute default value
+RLAPI void rlDrawVertexArray(int offset, int count);
+RLAPI void rlDrawVertexArrayElements(int offset, int count);
+
+// Textures management
RLAPI unsigned int rlLoadTexture(void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU
RLAPI unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo)
RLAPI unsigned int rlLoadTextureCubemap(void *data, int size, int format); // Load texture cubemap
@@ -606,32 +613,22 @@ RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attac
RLAPI bool rlFramebufferComplete(unsigned int id); // Verify framebuffer is complete
RLAPI void rlUnloadFramebuffer(unsigned int id); // Delete framebuffer from GPU
-// Vertex data management
-// TODO: Avoid dealing with Mesh and Material structs?
-RLAPI void rlLoadMesh(Mesh *mesh, bool dynamic); // Upload vertex data into GPU and provided VAO/VBO ids
-RLAPI unsigned int rlLoadVertexBuffer(unsigned int vaoId, int index, void *buffer, int size, bool dynamic); // Load a vertex buffer attribute
-RLAPI void rlUpdateMesh(Mesh mesh, int buffer, int count); // Update vertex or index data on GPU (upload new data to one buffer)
-RLAPI void rlUpdateMeshAt(Mesh mesh, int buffer, int count, int index); // Update vertex or index data on GPU, at index
-RLAPI void rlUpdateBuffer(int bufferId, void *data, int dataSize); // Update GPU buffer with new data
-RLAPI void rlDrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform
-RLAPI void rlDrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int count); // Draw a 3d mesh with material and transform
-RLAPI void rlUnloadMesh(Mesh *mesh); // Unload mesh data from CPU and GPU
-
// Shaders management
-RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode); // Load shader from code strings
-RLAPI unsigned int rlCompileShader(const char *shaderCode, int type); // Compile custom shader and return shader id (type: GL_VERTEX_SHADER, GL_FRAGMENT_SHADER)
+RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode); // Load shader from code strings
+RLAPI unsigned int rlCompileShader(const char *shaderCode, int type); // Compile custom shader and return shader id (type: GL_VERTEX_SHADER, GL_FRAGMENT_SHADER)
RLAPI unsigned int rlLoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId); // Load custom shader program
-RLAPI void rlUnloadShaderProgram(unsigned int id); // Unload shader program
+RLAPI void rlUnloadShaderProgram(unsigned int id); // Unload shader program
RLAPI int rlGetLocationUniform(unsigned int shaderId, const char *uniformName); // Get shader location uniform
-RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute
+RLAPI int rlGetLocationAttrib(unsigned int shaderId, const char *attribName); // Get shader location attribute
RLAPI void rlSetUniform(int locIndex, const void *value, int uniformType, int count); // Set shader value uniform
-RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix
-RLAPI void rlSetUniformSampler(int locIndex, Texture2D texture); // Set shader value sampler
-RLAPI void rlSetShaderActive(Shader shader); // Set shader currently active
+RLAPI void rlSetUniformMatrix(int locIndex, Matrix mat); // Set shader value matrix
+RLAPI void rlSetUniformSampler(int locIndex, unsigned int textureId); // Set shader value sampler
+RLAPI void rlSetShader(Shader shader); // Set shader currently active
// Matrix state management
RLAPI Matrix rlGetMatrixModelview(void); // Get internal modelview matrix
RLAPI Matrix rlGetMatrixProjection(void); // Get internal projection matrix
+RLAPI Matrix rlGetMatrixTransform(void); // Get internal accumulated transform matrix
RLAPI void rlSetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
RLAPI void rlSetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
RLAPI void rlSetMatrixProjectionStereo(Matrix right, Matrix left); // Set eyes projection matrices for stereo rendering
@@ -832,8 +829,8 @@ typedef struct rlglData {
Shader currentShader; // Shader to be used on rendering (by default, defaultShader)
bool stereoRender; // Stereo rendering flag
- Matrix eyesProjection[2]; // VR stereo rendering eyes projection matrices
- Matrix eyesViewOffset[2]; // VR stereo rendering eyes view offset matrices
+ Matrix projectionStereo[2]; // VR stereo rendering eyes projection matrices
+ Matrix offsetStereo[2]; // VR stereo rendering eyes view offset matrices
int currentBlendMode; // Blending mode active
int glBlendSrcFactor; // Blending source factor
@@ -1249,57 +1246,99 @@ void rlColor3f(float x, float y, float z)
// Module Functions Definition - OpenGL style functions (common to 1.1, 3.3+, ES2)
//--------------------------------------------------------------------------------------
-// Enable texture usage
-void rlEnableTexture(unsigned int id)
+// Set current texture to use
+void rlSetTexture(unsigned int id)
{
+ if (id == 0)
+ {
#if defined(GRAPHICS_API_OPENGL_11)
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, id);
+ rlDisableTexture();
+#else
+ // NOTE: If quads batch limit is reached, we force a draw call and next batch starts
+ if (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter >=
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4)
+ {
+ rlDrawRenderBatch(RLGL.currentBatch);
+ }
#endif
-
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId != id)
+ }
+ else
{
- if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount > 0)
+#if defined(GRAPHICS_API_OPENGL_11)
+ rlEnableTexture(id);
+#else
+ if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId != id)
{
- // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4,
- // that way, following QUADS drawing will keep aligned with index processing
- // It implies adding some extra alignment vertex at the end of the draw,
- // those vertex are not processed but they are considered as an additional offset
- // for the next set of vertex to be drawn
- if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4);
- else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4)));
- else RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = 0;
-
- if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment))
+ if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount > 0)
{
- RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
- RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
- RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
+ // Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4,
+ // that way, following QUADS drawing will keep aligned with index processing
+ // It implies adding some extra alignment vertex at the end of the draw,
+ // those vertex are not processed but they are considered as an additional offset
+ // for the next set of vertex to be drawn
+ if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4);
+ else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4)));
+ else RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = 0;
+
+ if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment))
+ {
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
- RLGL.currentBatch->drawsCounter++;
+ RLGL.currentBatch->drawsCounter++;
+ }
}
- }
- if (RLGL.currentBatch->drawsCounter >= DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch);
+ if (RLGL.currentBatch->drawsCounter >= DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch);
- RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId = id;
- RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount = 0;
+ RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId = id;
+ RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount = 0;
+ }
}
#endif
}
-// Disable texture usage
+// Select and active a texture slot
+void rlActiveTextureSlot(int slot)
+{
+ glActiveTexture(GL_TEXTURE0 + slot);
+}
+
+// Enable texture
+void rlEnableTexture(unsigned int id)
+{
+#if defined(GRAPHICS_API_OPENGL_11)
+ glEnable(GL_TEXTURE_2D);
+#endif
+ glBindTexture(GL_TEXTURE_2D, id);
+}
+
+// Disable texture
void rlDisableTexture(void)
{
#if defined(GRAPHICS_API_OPENGL_11)
glDisable(GL_TEXTURE_2D);
+#endif
glBindTexture(GL_TEXTURE_2D, 0);
-#else
- // NOTE: If quads batch limit is reached,
- // we force a draw call and next batch starts
- if (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter >= (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4)) rlDrawRenderBatch(RLGL.currentBatch);
+}
+
+// Enable texture cubemap
+void rlEnableTextureCubemap(unsigned int id)
+{
+#if defined(GRAPHICS_API_OPENGL_11)
+ glEnable(GL_TEXTURE_CUBE_MAP);
#endif
+ glBindTexture(GL_TEXTURE_CUBE_MAP, id);
+}
+
+// Disable texture cubemap
+void rlDisableTextureCubemap(void)
+{
+#if defined(GRAPHICS_API_OPENGL_11)
+ glDisable(GL_TEXTURE_CUBE_MAP);
+#endif
+ glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
// Set texture parameters (wrap mode/filter mode)
@@ -1342,7 +1381,7 @@ void rlTextureParameters(unsigned int id, int param, int value)
glBindTexture(GL_TEXTURE_2D, 0);
}
-// Enable shader program usage
+// Enable shader program
void rlEnableShader(unsigned int id)
{
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
@@ -1350,7 +1389,7 @@ void rlEnableShader(unsigned int id)
#endif
}
-// Disable shader program usage
+// Disable shader program
void rlDisableShader(void)
{
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2))
@@ -1716,7 +1755,7 @@ void rlglInit(int width, int height)
#if defined(GRAPHICS_API_OPENGL_ES2)
if (RLGL.ExtSupported.vao) TRACELOG(LOG_INFO, "GL: VAO extension detected, VAO functions initialized successfully");
- else TRACELOG(LOG_WARNING, "GL: VAO extension not found, VAO usage not supported");
+ else TRACELOG(LOG_WARNING, "GL: VAO extension not found, VAO not supported");
if (RLGL.ExtSupported.texNPOT) TRACELOG(LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported");
else TRACELOG(LOG_WARNING, "GL: NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)");
@@ -2149,9 +2188,9 @@ void rlDrawRenderBatch(RenderBatch *batch)
rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight);
// Set current eye view offset to modelview matrix
- rlSetMatrixModelview(MatrixMultiply(matModelView, RLGL.State.eyesViewOffset[eye]));
+ rlSetMatrixModelview(MatrixMultiply(matModelView, RLGL.State.offsetStereo[eye]));
// Set current eye projection matrix
- rlSetMatrixProjection(RLGL.State.eyesProjection[eye]);
+ rlSetMatrixProjection(RLGL.State.projectionStereo[eye]);
}
// Draw buffers
@@ -2959,584 +2998,143 @@ void rlUnloadFramebuffer(unsigned int id)
// Vertex data management
//-----------------------------------------------------------------------------------------
-// Upload vertex data into a VAO (if supported) and VBO
-void rlLoadMesh(Mesh *mesh, bool dynamic)
+// Load a new attributes buffer
+unsigned int rlLoadVertexBuffer(void *buffer, int size, bool dynamic)
{
- if (mesh->vaoId > 0)
- {
- // Check if mesh has already been loaded in GPU
- TRACELOG(LOG_WARNING, "VAO: [ID %i] Trying to re-load an already loaded mesh", mesh->vaoId);
- return;
- }
-
- mesh->vboId = (unsigned int *)RL_CALLOC(MAX_MESH_VERTEX_BUFFERS, sizeof(unsigned int));
-
- mesh->vaoId = 0; // Vertex Array Object
- mesh->vboId[0] = 0; // Vertex positions VBO
- mesh->vboId[1] = 0; // Vertex texcoords VBO
- mesh->vboId[2] = 0; // Vertex normals VBO
- mesh->vboId[3] = 0; // Vertex colors VBO
- mesh->vboId[4] = 0; // Vertex tangents VBO
- mesh->vboId[5] = 0; // Vertex texcoords2 VBO
- mesh->vboId[6] = 0; // Vertex indices VBO
+ unsigned int id = 0;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- int drawHint = GL_STATIC_DRAW;
- if (dynamic) drawHint = GL_DYNAMIC_DRAW;
-
- if (RLGL.ExtSupported.vao)
- {
- // Initialize Quads VAO (Buffer A)
- glGenVertexArrays(1, &mesh->vaoId);
- glBindVertexArray(mesh->vaoId);
- }
-
- // NOTE: Attributes must be uploaded considering default locations points
-
- // Enable vertex attributes: position (shader-location = 0)
- glGenBuffers(1, &mesh->vboId[0]);
- glBindBuffer(GL_ARRAY_BUFFER, mesh->vboId[0]);
- glBufferData(GL_ARRAY_BUFFER, mesh->vertexCount*3*sizeof(float), mesh->vertices, drawHint);
- glVertexAttribPointer(0, 3, GL_FLOAT, 0, 0, 0);
- glEnableVertexAttribArray(0);
-
- // Enable vertex attributes: texcoords (shader-location = 1)
- glGenBuffers(1, &mesh->vboId[1]);
- glBindBuffer(GL_ARRAY_BUFFER, mesh->vboId[1]);
- glBufferData(GL_ARRAY_BUFFER, mesh->vertexCount*2*sizeof(float), mesh->texcoords, drawHint);
- glVertexAttribPointer(1, 2, GL_FLOAT, 0, 0, 0);
- glEnableVertexAttribArray(1);
-
- // Enable vertex attributes: normals (shader-location = 2)
- if (mesh->normals != NULL)
- {
- glGenBuffers(1, &mesh->vboId[2]);
- glBindBuffer(GL_ARRAY_BUFFER, mesh->vboId[2]);
- glBufferData(GL_ARRAY_BUFFER, mesh->vertexCount*3*sizeof(float), mesh->normals, drawHint);
- glVertexAttribPointer(2, 3, GL_FLOAT, 0, 0, 0);
- glEnableVertexAttribArray(2);
- }
- else
- {
- // Default color vertex attribute set to WHITE
- glVertexAttrib3f(2, 1.0f, 1.0f, 1.0f);
- glDisableVertexAttribArray(2);
- }
-
- // Default color vertex attribute (shader-location = 3)
- if (mesh->colors != NULL)
- {
- glGenBuffers(1, &mesh->vboId[3]);
- glBindBuffer(GL_ARRAY_BUFFER, mesh->vboId[3]);
- glBufferData(GL_ARRAY_BUFFER, mesh->vertexCount*4*sizeof(unsigned char), mesh->colors, drawHint);
- glVertexAttribPointer(3, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
- glEnableVertexAttribArray(3);
- }
- else
- {
- // Default color vertex attribute set to WHITE
- glVertexAttrib4f(3, 1.0f, 1.0f, 1.0f, 1.0f);
- glDisableVertexAttribArray(3);
- }
-
- // Default tangent vertex attribute (shader-location = 4)
- if (mesh->tangents != NULL)
- {
- glGenBuffers(1, &mesh->vboId[4]);
- glBindBuffer(GL_ARRAY_BUFFER, mesh->vboId[4]);
- glBufferData(GL_ARRAY_BUFFER, mesh->vertexCount*4*sizeof(float), mesh->tangents, drawHint);
- glVertexAttribPointer(4, 4, GL_FLOAT, 0, 0, 0);
- glEnableVertexAttribArray(4);
- }
- else
- {
- // Default tangents vertex attribute
- glVertexAttrib4f(4, 0.0f, 0.0f, 0.0f, 0.0f);
- glDisableVertexAttribArray(4);
- }
-
- // Default texcoord2 vertex attribute (shader-location = 5)
- if (mesh->texcoords2 != NULL)
- {
- glGenBuffers(1, &mesh->vboId[5]);
- glBindBuffer(GL_ARRAY_BUFFER, mesh->vboId[5]);
- glBufferData(GL_ARRAY_BUFFER, mesh->vertexCount*2*sizeof(float), mesh->texcoords2, drawHint);
- glVertexAttribPointer(5, 2, GL_FLOAT, 0, 0, 0);
- glEnableVertexAttribArray(5);
- }
- else
- {
- // Default texcoord2 vertex attribute
- glVertexAttrib2f(5, 0.0f, 0.0f);
- glDisableVertexAttribArray(5);
- }
-
- if (mesh->indices != NULL)
- {
- glGenBuffers(1, &mesh->vboId[6]);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->vboId[6]);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh->triangleCount*3*sizeof(unsigned short), mesh->indices, drawHint);
- }
-
- if (RLGL.ExtSupported.vao)
- {
- if (mesh->vaoId > 0) TRACELOG(LOG_INFO, "VAO: [ID %i] Mesh uploaded successfully to VRAM (GPU)", mesh->vaoId);
- else TRACELOG(LOG_WARNING, "VAO: Failed to load mesh to VRAM (GPU)");
- }
- else
- {
- TRACELOG(LOG_INFO, "VBO: Mesh uploaded successfully to VRAM (GPU)");
- }
+ glGenBuffers(1, &id);
+ glBindBuffer(GL_ARRAY_BUFFER, id);
+ glBufferData(GL_ARRAY_BUFFER, size, buffer, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
#endif
+
+ return id;
}
-// Load a new attributes buffer
-unsigned int rlLoadVertexBuffer(unsigned int vaoId, int index, void *buffer, int size, bool dynamic)
+// Load a new attributes element buffer
+unsigned int rlLoadVertexBufferElement(void *buffer, int size, bool dynamic)
{
unsigned int id = 0;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- int drawHint = GL_STATIC_DRAW;
- if (dynamic) drawHint = GL_DYNAMIC_DRAW;
-
- if (RLGL.ExtSupported.vao) glBindVertexArray(vaoId);
-
glGenBuffers(1, &id);
- glBindBuffer(GL_ARRAY_BUFFER, id);
- glBufferData(GL_ARRAY_BUFFER, size, buffer, drawHint);
- glVertexAttribPointer(index, 2, GL_FLOAT, 0, 0, 0);
- glEnableVertexAttribArray(index);
-
- if (RLGL.ExtSupported.vao) glBindVertexArray(0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, buffer, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
#endif
return id;
}
-// Update vertex or index data on GPU (upload new data to one buffer)
-void rlUpdateMesh(Mesh mesh, int buffer, int count)
+void rlEnableVertexBuffer(unsigned int id)
{
- rlUpdateMeshAt(mesh, buffer, count, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, id);
}
-// Update vertex or index data on GPU, at index
-// WARNING: error checking is in place that will cause the data to not be
-// updated if offset + size exceeds what the buffer can hold
-void rlUpdateMeshAt(Mesh mesh, int buffer, int count, int index)
+void rlDisableVertexBuffer(void)
{
-#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- // Activate mesh VAO
- if (RLGL.ExtSupported.vao) glBindVertexArray(mesh.vaoId);
-
- switch (buffer)
- {
- case 0: // Update vertices (vertex position)
- {
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]);
- if (index == 0 && count >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, count*3*sizeof(float), mesh.vertices, GL_DYNAMIC_DRAW);
- else if (index + count >= mesh.vertexCount) break;
- else glBufferSubData(GL_ARRAY_BUFFER, index*3*sizeof(float), count*3*sizeof(float), mesh.vertices);
-
- } break;
- case 1: // Update texcoords (vertex texture coordinates)
- {
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]);
- if (index == 0 && count >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, count*2*sizeof(float), mesh.texcoords, GL_DYNAMIC_DRAW);
- else if (index + count >= mesh.vertexCount) break;
- else glBufferSubData(GL_ARRAY_BUFFER, index*2*sizeof(float), count*2*sizeof(float), mesh.texcoords);
-
- } break;
- case 2: // Update normals (vertex normals)
- {
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[2]);
- if (index == 0 && count >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, count*3*sizeof(float), mesh.normals, GL_DYNAMIC_DRAW);
- else if (index + count >= mesh.vertexCount) break;
- else glBufferSubData(GL_ARRAY_BUFFER, index*3*sizeof(float), count*3*sizeof(float), mesh.normals);
-
- } break;
- case 3: // Update colors (vertex colors)
- {
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]);
- if (index == 0 && count >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, count*4*sizeof(unsigned char), mesh.colors, GL_DYNAMIC_DRAW);
- else if (index + count >= mesh.vertexCount) break;
- else glBufferSubData(GL_ARRAY_BUFFER, index*4*sizeof(unsigned char), count*4*sizeof(unsigned char), mesh.colors);
-
- } break;
- case 4: // Update tangents (vertex tangents)
- {
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[4]);
- if (index == 0 && count >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, count*4*sizeof(float), mesh.tangents, GL_DYNAMIC_DRAW);
- else if (index + count >= mesh.vertexCount) break;
- else glBufferSubData(GL_ARRAY_BUFFER, index*4*sizeof(float), count*4*sizeof(float), mesh.tangents);
-
- } break;
- case 5: // Update texcoords2 (vertex second texture coordinates)
- {
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[5]);
- if (index == 0 && count >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, count*2*sizeof(float), mesh.texcoords2, GL_DYNAMIC_DRAW);
- else if (index + count >= mesh.vertexCount) break;
- else glBufferSubData(GL_ARRAY_BUFFER, index*2*sizeof(float), count*2*sizeof(float), mesh.texcoords2);
-
- } break;
- case 6: // Update indices (triangle index buffer)
- {
- // the * 3 is because each triangle has 3 indices
- unsigned short *indices = mesh.indices;
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vboId[6]);
-
- if (index == 0 && count >= mesh.triangleCount) glBufferData(GL_ELEMENT_ARRAY_BUFFER, count*3*sizeof(*indices), indices, GL_DYNAMIC_DRAW);
- else if (index + count >= mesh.triangleCount) break;
- else glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, index*3*sizeof(*indices), count*3*sizeof(*indices), indices);
-
- } break;
- default: break;
- }
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
- // Unbind the current VAO
- if (RLGL.ExtSupported.vao) glBindVertexArray(0);
+void rlEnableVertexBufferElement(unsigned int id)
+{
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id);
+}
- // 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);
-#endif
+void rlDisableVertexBufferElement(void)
+{
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
// Update GPU buffer with new data
-void rlUpdateBuffer(int bufferId, void *data, int dataSize)
+// NOTE: dataSize and offset must be provided in bytes
+void rlUpdateVertexBuffer(int bufferId, void *data, int dataSize, int offset)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glBindBuffer(GL_ARRAY_BUFFER, bufferId);
- glBufferSubData(GL_ARRAY_BUFFER, 0, dataSize, data);
+ glBufferSubData(GL_ARRAY_BUFFER, offset, dataSize, data);
#endif
}
-// Draw a 3d mesh with material and transform
-void rlDrawMesh(Mesh mesh, Material material, Matrix transform)
+bool rlEnableVertexArray(unsigned int vaoId)
{
-#if defined(GRAPHICS_API_OPENGL_11)
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, material.maps[MATERIAL_MAP_DIFFUSE].texture.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.maps[MATERIAL_MAP_DIFFUSE].color.r, material.maps[MATERIAL_MAP_DIFFUSE].color.g, material.maps[MATERIAL_MAP_DIFFUSE].color.b, material.maps[MATERIAL_MAP_DIFFUSE].color.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
-
+ bool result = false;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- // Bind shader program
- rlEnableShader(material.shader.id);
-
- // Matrices and other values required by shader
- //-----------------------------------------------------
- // Calculate and send to shader model matrix
- if (material.shader.locs[SHADER_LOC_MATRIX_MODEL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MODEL], transform);
-
- // Upload to shader material.colDiffuse
- if (material.shader.locs[SHADER_LOC_COLOR_DIFFUSE] != -1)
+ if (RLGL.ExtSupported.vao)
{
- float values[4] = {
- (float)material.maps[MATERIAL_MAP_DIFFUSE].color.r/255.0f,
- (float)material.maps[MATERIAL_MAP_DIFFUSE].color.g/255.0f,
- (float)material.maps[MATERIAL_MAP_DIFFUSE].color.b/255.0f,
- (float)material.maps[MATERIAL_MAP_DIFFUSE].color.a/255.0f
- };
-
- rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_DIFFUSE], values, SHADER_UNIFORM_VEC4, 1);
- }
-
- // Upload to shader material.colSpecular (if available)
- if (material.shader.locs[SHADER_LOC_COLOR_SPECULAR] != -1)
- {
- float values[4] = {
- (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.r/255.0f,
- (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.g/255.0f,
- (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.b/255.0f,
- (float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.a/255.0f
- };
-
- rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_SPECULAR], values, SHADER_UNIFORM_VEC4, 1);
- }
-
- if (material.shader.locs[SHADER_LOC_MATRIX_VIEW] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_VIEW], RLGL.State.modelview);
- if (material.shader.locs[SHADER_LOC_MATRIX_PROJECTION] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_PROJECTION], RLGL.State.projection);
-
- // At this point the modelview matrix just contains the view matrix (camera)
- // That's because BeginMode3D() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
- Matrix matView = RLGL.State.modelview; // View matrix (camera)
- Matrix matProjection = RLGL.State.projection; // Projection matrix (perspective)
-
- // TODO: Consider possible transform matrices in the RLGL.State.stack
- // Is this the right order? or should we start with the first stored matrix instead of the last one?
- //Matrix matStackTransform = MatrixIdentity();
- //for (int i = RLGL.State.stackCounter; i > 0; i--) matStackTransform = MatrixMultiply(RLGL.State.stack[i], matStackTransform);
-
- // Transform to camera-space coordinates
- Matrix matModelView = MatrixMultiply(transform, MatrixMultiply(RLGL.State.transform, matView));
- //-----------------------------------------------------
-
- // Bind active texture maps (if available)
- for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
- {
- if (material.maps[i].texture.id > 0)
- {
- glActiveTexture(GL_TEXTURE0 + i);
- if ((i == MATERIAL_MAP_IRRADIANCE) || (i == MATERIAL_MAP_PREFILTER) || (i == MATERIAL_MAP_CUBEMAP)) glBindTexture(GL_TEXTURE_CUBE_MAP, material.maps[i].texture.id);
- else glBindTexture(GL_TEXTURE_2D, material.maps[i].texture.id);
-
- rlSetUniform(material.shader.locs[SHADER_LOC_MAP_DIFFUSE + i], &i, SHADER_UNIFORM_INT, 1);
- }
- }
-
- // Bind vertex array objects (or VBOs)
- if (RLGL.ExtSupported.vao) glBindVertexArray(mesh.vaoId);
- else
- {
- // Bind mesh VBO data: vertex position (shader-location = 0)
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[0]);
- glVertexAttribPointer(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
- glEnableVertexAttribArray(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
-
- // Bind mesh VBO data: vertex texcoords (shader-location = 1)
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[1]);
- glVertexAttribPointer(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
- glEnableVertexAttribArray(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01]);
-
- // Bind mesh VBO data: vertex normals (shader-location = 2, if available)
- if (material.shader.locs[SHADER_LOC_VERTEX_NORMAL] != -1)
- {
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[2]);
- glVertexAttribPointer(material.shader.locs[SHADER_LOC_VERTEX_NORMAL], 3, GL_FLOAT, 0, 0, 0);
- glEnableVertexAttribArray(material.shader.locs[SHADER_LOC_VERTEX_NORMAL]);
- }
-
- // Bind mesh VBO data: vertex colors (shader-location = 3, if available)
- if (material.shader.locs[SHADER_LOC_VERTEX_COLOR] != -1)
- {
- if (mesh.vboId[3] != 0)
- {
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[3]);
- glVertexAttribPointer(material.shader.locs[SHADER_LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
- glEnableVertexAttribArray(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
- }
- else
- {
- // Set default value for unused attribute
- // NOTE: Required when using default shader and no VAO support
- glVertexAttrib4f(material.shader.locs[SHADER_LOC_VERTEX_COLOR], 1.0f, 1.0f, 1.0f, 1.0f);
- glDisableVertexAttribArray(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
- }
- }
-
- // Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
- if (material.shader.locs[SHADER_LOC_VERTEX_TANGENT] != -1)
- {
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[4]);
- glVertexAttribPointer(material.shader.locs[SHADER_LOC_VERTEX_TANGENT], 4, GL_FLOAT, 0, 0, 0);
- glEnableVertexAttribArray(material.shader.locs[SHADER_LOC_VERTEX_TANGENT]);
- }
-
- // Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
- if (material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] != -1)
- {
- glBindBuffer(GL_ARRAY_BUFFER, mesh.vboId[5]);
- glVertexAttribPointer(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, GL_FLOAT, 0, 0, 0);
- glEnableVertexAttribArray(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
- }
-
- if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vboId[6]);
- }
-
- int eyesCount = 1;
- if (RLGL.State.stereoRender) eyesCount = 2;
-
- for (int eye = 0; eye < eyesCount; eye++)
- {
- if (eyesCount == 1) RLGL.State.modelview = matModelView;
- else
- {
- // Setup current eye viewport (half screen width)
- rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight);
-
- // Set current eye view offset to modelview matrix
- rlSetMatrixModelview(MatrixMultiply(matModelView, RLGL.State.eyesViewOffset[eye]));
- // Set current eye projection matrix
- rlSetMatrixProjection(RLGL.State.eyesProjection[eye]);
- }
-
- // Calculate model-view-projection matrix (MVP)
- Matrix matMVP = MatrixMultiply(RLGL.State.modelview, RLGL.State.projection); // Transform to screen-space coordinates
-
- // Send combined model-view-projection matrix to shader
- rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MVP], matMVP);
-
- // 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);
- }
-
- // Unbind all binded texture maps
- for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
- {
- glActiveTexture(GL_TEXTURE0 + i); // Set shader active texture
- if ((i == MATERIAL_MAP_IRRADIANCE) || (i == MATERIAL_MAP_PREFILTER) || (i == MATERIAL_MAP_CUBEMAP)) glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
- else glBindTexture(GL_TEXTURE_2D, 0); // Unbind current active texture
+ glBindVertexArray(vaoId);
+ result = true;
}
+#endif
+ return result;
+}
- // Unind vertex array objects (or VBOs)
+void rlDisableVertexArray(void)
+{
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (RLGL.ExtSupported.vao) glBindVertexArray(0);
- else
- {
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
-
- // Unbind shader program
- rlDisableShader();
-
- // Restore RLGL.State.projection/RLGL.State.modelview matrices
- // NOTE: In stereo rendering matrices are being modified to fit every eye
- RLGL.State.projection = matProjection;
- RLGL.State.modelview = matView;
#endif
}
-// Draw a 3d mesh with material and transform
-void rlDrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int count)
+void rlEnableVertexAttribute(unsigned int index)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- if (RLGL.ExtSupported.instancing)
- {
- // Bind shader program
- rlEnableShader(material.shader.id);
-
- // Upload to shader material.colDiffuse
- if (material.shader.locs[SHADER_LOC_COLOR_DIFFUSE] != -1)
- glUniform4f(material.shader.locs[SHADER_LOC_COLOR_DIFFUSE], (float)material.maps[MATERIAL_MAP_DIFFUSE].color.r/255.0f,
- (float)material.maps[MATERIAL_MAP_DIFFUSE].color.g/255.0f,
- (float)material.maps[MATERIAL_MAP_DIFFUSE].color.b/255.0f,
- (float)material.maps[MATERIAL_MAP_DIFFUSE].color.a/255.0f);
-
- // Upload to shader material.colSpecular (if available)
- if (material.shader.locs[SHADER_LOC_COLOR_SPECULAR] != -1)
- glUniform4f(material.shader.locs[SHADER_LOC_COLOR_SPECULAR], (float)material.maps[MATERIAL_MAP_SPECULAR].color.r/255.0f,
- (float)material.maps[MATERIAL_MAP_SPECULAR].color.g/255.0f,
- (float)material.maps[MATERIAL_MAP_SPECULAR].color.b/255.0f,
- (float)material.maps[MATERIAL_MAP_SPECULAR].color.a/255.0f);
-
- // Bind active texture maps (if available)
- for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
- {
- if (material.maps[i].texture.id > 0)
- {
- glActiveTexture(GL_TEXTURE0 + i);
- if ((i == MATERIAL_MAP_IRRADIANCE) || (i == MATERIAL_MAP_PREFILTER) || (i == MATERIAL_MAP_CUBEMAP))
- glBindTexture(GL_TEXTURE_CUBE_MAP, material.maps[i].texture.id);
- else glBindTexture(GL_TEXTURE_2D, material.maps[i].texture.id);
-
- glUniform1i(material.shader.locs[SHADER_LOC_MAP_DIFFUSE + i], i);
- }
- }
-
- // Bind vertex array objects (or VBOs)
- glBindVertexArray(mesh.vaoId);
-
- // At this point the modelview matrix just contains the view matrix (camera)
- // For instanced shaders "mvp" is not premultiplied by any instance transform, only RLGL.State.transform
- glUniformMatrix4fv(material.shader.locs[SHADER_LOC_MATRIX_MVP], 1, false,
- MatrixToFloat(MatrixMultiply(MatrixMultiply(RLGL.State.transform, RLGL.State.modelview), RLGL.State.projection)));
-
- float16* instanceTransforms = RL_MALLOC(count*sizeof(float16));
-
- for (int i = 0; i < count; i++) instanceTransforms[i] = MatrixToFloatV(transforms[i]);
-
- // This could alternatively use a static VBO and either glMapBuffer or glBufferSubData.
- // It isn't clear which would be reliably faster in all cases and on all platforms, and
- // anecdotally glMapBuffer seems very slow (syncs) while glBufferSubData seems no faster
- // since we're transferring all the transform matrices anyway.
- unsigned int instancesB = 0;
- glGenBuffers(1, &instancesB);
- glBindBuffer(GL_ARRAY_BUFFER, instancesB);
- glBufferData(GL_ARRAY_BUFFER, count*sizeof(float16), instanceTransforms, GL_STATIC_DRAW);
-
- // Instances are put in SHADER_LOC_MATRIX_MODEL attribute location with space for 4x Vector4, eg:
- // layout (location = 12) in mat4 instance;
- unsigned int instanceA = material.shader.locs[SHADER_LOC_MATRIX_MODEL];
-
- for (unsigned int i = 0; i < 4; i++)
- {
- glEnableVertexAttribArray(instanceA+i);
- glVertexAttribPointer(instanceA + i, 4, GL_FLOAT, GL_FALSE, sizeof(Matrix), (void *)(i*sizeof(Vector4)));
- glVertexAttribDivisor(instanceA + i, 1);
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glEnableVertexAttribArray(index);
+#endif
+}
- // Draw instanced
- if (mesh.indices != NULL) glDrawElementsInstanced(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0, count);
- else glDrawArraysInstanced(GL_TRIANGLES, 0, mesh.vertexCount, count);
+void rlDisableVertexAttribute(unsigned int index)
+{
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ glDisableVertexAttribArray(index);
+#endif
+}
- glDeleteBuffers(1, &instancesB);
- RL_FREE(instanceTransforms);
+void rlDrawVertexArray(int offset, int count)
+{
+ glDrawArrays(GL_TRIANGLES, offset, count);
+}
- // Unbind all binded texture maps
- for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
- {
- glActiveTexture(GL_TEXTURE0 + i); // Set shader active texture
- if ((i == MATERIAL_MAP_IRRADIANCE) || (i == MATERIAL_MAP_PREFILTER) || (i == MATERIAL_MAP_CUBEMAP)) glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
- else glBindTexture(GL_TEXTURE_2D, 0); // Unbind current active texture
- }
+void rlDrawVertexArrayElements(int offset, int count)
+{
+ // TODO: review offset
+ glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, 0);
+}
- // Unind vertex array objects (or VBOs)
- glBindVertexArray(0);
+unsigned int rlLoadVertexArray(void)
+{
+ unsigned int vaoId = 0;
+
+ glGenVertexArrays(1, &vaoId);
+
+ return vaoId;
+}
- // Unbind shader program
- glUseProgram(0);
- }
-#endif
+void rlSetVertexAttribute(unsigned int index, int compSize, int type, bool normalized, int stride, void *pointer)
+{
+ glVertexAttribPointer(index, compSize, type, normalized, stride, pointer);
}
-// Unload mesh data from CPU and GPU
-void rlUnloadMesh(Mesh *mesh)
+void rlUnloadVertexArray(unsigned int vaoId)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- for (int i = 0; i < 7; i++) glDeleteBuffers(1, &mesh->vboId[i]); // DEFAULT_MESH_VERTEX_BUFFERS (model.c)
if (RLGL.ExtSupported.vao)
{
glBindVertexArray(0);
- glDeleteVertexArrays(1, &mesh->vaoId);
- TRACELOG(LOG_INFO, "VAO: [ID %i] Unloaded vertex data from VRAM (GPU)", mesh->vaoId);
+ glDeleteVertexArrays(1, &vaoId);
+ TRACELOG(LOG_INFO, "VAO: [ID %i] Unloaded vertex array data from VRAM (GPU)", vaoId);
}
- else TRACELOG(LOG_INFO, "VBO: Unloaded vertex data from VRAM (GPU)");
#endif
+}
- RL_FREE(mesh->vboId);
- mesh->vboId = NULL;
+void rlUnloadVertexBuffer(unsigned int vboId)
+{
+ glDeleteBuffers(1, &vboId);
+ TRACELOG(LOG_INFO, "VBO: Unloaded vertex data from VRAM (GPU)");
}
+
+
// Shaders management
//-----------------------------------------------------------------------------------------------
// Load shader from code strings
@@ -3741,7 +3339,22 @@ void rlSetUniform(int locIndex, const void *value, int uniformType, int count)
case SHADER_UNIFORM_IVEC3: glUniform3iv(locIndex, count, (int *)value); break;
case SHADER_UNIFORM_IVEC4: glUniform4iv(locIndex, count, (int *)value); break;
case SHADER_UNIFORM_SAMPLER2D: glUniform1iv(locIndex, count, (int *)value); break;
- default: TRACELOG(LOG_WARNING, "SHADER: Failed to set uniform, data type not recognized");
+ default: TRACELOG(LOG_WARNING, "SHADER: Failed to set uniform value, data type not recognized");
+ }
+#endif
+}
+
+// Set shader value attribute
+void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType, int count)
+{
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ switch (attribType)
+ {
+ case SHADER_ATTRIB_FLOAT: if (count == 1) glVertexAttrib1fv(locIndex, (float *)value); break;
+ case SHADER_ATTRIB_VEC2: if (count == 2) glVertexAttrib2fv(locIndex, (float *)value); break;
+ case SHADER_ATTRIB_VEC3: if (count == 3) glVertexAttrib3fv(locIndex, (float *)value); break;
+ case SHADER_ATTRIB_VEC4: if (count == 4) glVertexAttrib4fv(locIndex, (float *)value); break;
+ default: TRACELOG(LOG_WARNING, "SHADER: Failed to set attrib default value, data type not recognized");
}
#endif
}
@@ -3755,11 +3368,11 @@ void rlSetUniformMatrix(int locIndex, Matrix mat)
}
// Set shader value uniform sampler
-void rlSetUniformSampler(int locIndex, Texture2D texture)
+void rlSetUniformSampler(int locIndex, unsigned int textureId)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Check if texture is already active
- for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++) if (RLGL.State.activeTextureId[i] == texture.id) return;
+ for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++) if (RLGL.State.activeTextureId[i] == textureId) return;
// Register a new active texture for the internal batch system
// NOTE: Default texture is always activated as GL_TEXTURE0
@@ -3767,8 +3380,8 @@ void rlSetUniformSampler(int locIndex, Texture2D texture)
{
if (RLGL.State.activeTextureId[i] == 0)
{
- glUniform1i(locIndex, 1 + i); // Activate new texture unit
- RLGL.State.activeTextureId[i] = texture.id; // Save texture id for binding on drawing
+ glUniform1i(locIndex, 1 + i); // Activate new texture unit
+ RLGL.State.activeTextureId[i] = textureId; // Save texture id for binding on drawing
break;
}
}
@@ -3776,7 +3389,7 @@ void rlSetUniformSampler(int locIndex, Texture2D texture)
}
// Set shader currently active
-void rlSetShaderActive(Shader shader)
+void rlSetShader(Shader shader)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (RLGL.State.currentShader.id != shader.id)
@@ -3821,7 +3434,17 @@ Matrix rlGetMatrixProjection(void)
#else
return RLGL.State.projection;
#endif
-#
+}
+
+// Get internal accumulated transform matrix
+Matrix rlGetMatrixTransform(void)
+{
+ // TODO: Consider possible transform matrices in the RLGL.State.stack
+ // Is this the right order? or should we start with the first stored matrix instead of the last one?
+ //Matrix matStackTransform = MatrixIdentity();
+ //for (int i = RLGL.State.stackCounter; i > 0; i--) matStackTransform = MatrixMultiply(RLGL.State.stack[i], matStackTransform);
+
+ return RLGL.State.transform;
}
// Set a custom modelview matrix (replaces internal modelview matrix)
@@ -3844,8 +3467,8 @@ void rlSetMatrixProjection(Matrix projection)
void rlSetMatrixProjectionStereo(Matrix right, Matrix left)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- RLGL.State.eyesProjection[0] = right;
- RLGL.State.eyesProjection[1] = left;
+ RLGL.State.projectionStereo[0] = right;
+ RLGL.State.projectionStereo[1] = left;
#endif
}
@@ -3853,8 +3476,8 @@ void rlSetMatrixProjectionStereo(Matrix right, Matrix left)
void rlSetMatrixViewOffsetStereo(Matrix right, Matrix left)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- RLGL.State.eyesViewOffset[0] = right;
- RLGL.State.eyesViewOffset[1] = left;
+ RLGL.State.offsetStereo[0] = right;
+ RLGL.State.offsetStereo[1] = left;
#endif
}
@@ -3900,8 +3523,8 @@ TextureCubemap rlGenTextureCubemap(Shader shader, Texture2D panorama, int size,
};
#if !defined(GENTEXTURECUBEMAP_USE_BATCH_SYSTEM)
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, panorama.id);
+ rlActiveTextureSlot(0);
+ rlEnableTexture(panorama.id);
#endif
rlViewport(0, 0, size, size); // Set viewport to current fbo dimensions
@@ -3913,7 +3536,7 @@ TextureCubemap rlGenTextureCubemap(Shader shader, Texture2D panorama, int size,
rlEnableFramebuffer(fbo);
#if defined(GENTEXTURECUBEMAP_USE_BATCH_SYSTEM)
- rlEnableTexture(panorama.id); // WARNING: It must be called after enabling current framebuffer if using internal batch system!
+ rlSetTexture(panorama.id); // WARNING: It must be called after enabling current framebuffer if using internal batch system!
#endif
rlClearScreenBuffers();
rlGenDrawCube();
@@ -3984,8 +3607,8 @@ TextureCubemap rlGenTextureIrradiance(Shader shader, TextureCubemap cubemap, int
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
};
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
+ rlActiveTextureSlot(0);
+ rlEnableTextureCubemap(cubemap.id);
rlViewport(0, 0, size, size); // Set viewport to current fbo dimensions
@@ -4061,8 +3684,8 @@ TextureCubemap rlGenTexturePrefilter(Shader shader, TextureCubemap cubemap, int
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
};
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
+ rlActiveTextureSlot(0);
+ rlEnableTextureCubemap(cubemap.id);
// TODO: Locations should be taken out of this function... too shader dependant...
int roughnessLoc = rlGetLocationUniform(shader.id, "roughness");
diff --git a/src/shapes.c b/src/shapes.c
index b615f78a..48ad85f4 100644
--- a/src/shapes.c
+++ b/src/shapes.c
@@ -233,7 +233,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
#if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(4*segments/2);
- rlEnableTexture(rlGetShapesTexture().id);
+ rlSetTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS);
// NOTE: Every QUAD actually represents two segments
@@ -275,7 +275,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA
}
rlEnd();
- rlDisableTexture();
+ rlSetTexture(0);
#else
rlCheckRenderBatchLimit(3*segments);
@@ -472,7 +472,7 @@ void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startA
#if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(4*segments);
- rlEnableTexture(rlGetShapesTexture().id);
+ rlSetTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS);
for (int i = 0; i < segments; i++)
@@ -495,7 +495,7 @@ void DrawRing(Vector2 center, float innerRadius, float outerRadius, float startA
}
rlEnd();
- rlDisableTexture();
+ rlSetTexture(0);
#else
rlCheckRenderBatchLimit(6*segments);
@@ -656,7 +656,7 @@ void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color
bottomRight.y = y + (dx + rec.width)*sinRotation + (dy + rec.height)*cosRotation;
}
- rlEnableTexture(rlGetShapesTexture().id);
+ rlSetTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS);
rlNormal3f(0.0f, 0.0f, 1.0f);
@@ -675,7 +675,7 @@ void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color
rlVertex2f(topRight.x, topRight.y);
rlEnd();
- rlDisableTexture();
+ rlSetTexture(0);
}
// Draw a vertical-gradient-filled rectangle
@@ -696,7 +696,7 @@ void DrawRectangleGradientH(int posX, int posY, int width, int height, Color col
// NOTE: Colors refer to corners, starting at top-lef corner and counter-clockwise
void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4)
{
- rlEnableTexture(rlGetShapesTexture().id);
+ rlSetTexture(rlGetShapesTexture().id);
rlPushMatrix();
rlBegin(RL_QUADS);
@@ -721,7 +721,7 @@ void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3,
rlEnd();
rlPopMatrix();
- rlDisableTexture();
+ rlSetTexture(0);
}
// Draw rectangle outline
@@ -825,7 +825,7 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
#if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(16*segments/2 + 5*4);
- rlEnableTexture(rlGetShapesTexture().id);
+ rlSetTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS);
// Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner
@@ -920,7 +920,7 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co
rlVertex2f(point[9].x, point[9].y);
rlEnd();
- rlDisableTexture();
+ rlSetTexture(0);
#else
rlCheckRenderBatchLimit(12*segments + 5*6); // 4 corners with 3 vertices per segment + 5 rectangles with 6 vertices each
@@ -1055,7 +1055,7 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int
#if defined(SUPPORT_QUADS_DRAW_MODE)
rlCheckRenderBatchLimit(4*4*segments + 4*4); // 4 corners with 4 vertices for each segment + 4 rectangles with 4 vertices each
- rlEnableTexture(rlGetShapesTexture().id);
+ rlSetTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS);
@@ -1125,7 +1125,7 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int
rlVertex2f(point[14].x, point[14].y);
rlEnd();
- rlDisableTexture();
+ rlSetTexture(0);
#else
rlCheckRenderBatchLimit(4*6*segments + 4*6); // 4 corners with 6(2*3) vertices for each segment + 4 rectangles with 6 vertices each
@@ -1232,7 +1232,7 @@ void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
rlCheckRenderBatchLimit(4);
#if defined(SUPPORT_QUADS_DRAW_MODE)
- rlEnableTexture(rlGetShapesTexture().id);
+ rlSetTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
@@ -1250,7 +1250,7 @@ void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
rlVertex2f(v3.x, v3.y);
rlEnd();
- rlDisableTexture();
+ rlSetTexture(0);
#else
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
@@ -1289,7 +1289,7 @@ void DrawTriangleFan(Vector2 *points, int pointsCount, Color color)
{
rlCheckRenderBatchLimit((pointsCount - 2)*4);
- rlEnableTexture(rlGetShapesTexture().id);
+ rlSetTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
@@ -1308,7 +1308,7 @@ void DrawTriangleFan(Vector2 *points, int pointsCount, Color color)
rlVertex2f(points[i + 1].x, points[i + 1].y);
}
rlEnd();
- rlDisableTexture();
+ rlSetTexture(0);
}
}
@@ -1355,7 +1355,7 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
rlRotatef(rotation, 0.0f, 0.0f, 1.0f);
#if defined(SUPPORT_QUADS_DRAW_MODE)
- rlEnableTexture(rlGetShapesTexture().id);
+ rlSetTexture(rlGetShapesTexture().id);
rlBegin(RL_QUADS);
for (int i = 0; i < sides; i++)
@@ -1376,7 +1376,7 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius);
}
rlEnd();
- rlDisableTexture();
+ rlSetTexture(0);
#else
rlBegin(RL_TRIANGLES);
for (int i = 0; i < sides; i++)
diff --git a/src/textures.c b/src/textures.c
index 61e6f30b..0e61edc2 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -3243,7 +3243,7 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
bottomRight.y = y + (dx + dest.width)*sinRotation + (dy + dest.height)*cosRotation;
}
- rlEnableTexture(texture.id);
+ rlSetTexture(texture.id);
rlBegin(RL_QUADS);
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
@@ -3270,7 +3270,7 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
rlVertex2f(topRight.x, topRight.y);
rlEnd();
- rlDisableTexture();
+ rlSetTexture(0);
// NOTE: Vertex position can be transformed using matrices
// but the process is way more costly than just calculating
@@ -3278,7 +3278,7 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
// I leave here the old implementation for educational pourposes,
// just in case someone wants to do some performance test
/*
- rlEnableTexture(texture.id);
+ rlSetTexture(texture.id);
rlPushMatrix();
rlTranslatef(dest.x, dest.y, 0.0f);
if (rotation != 0.0f) rlRotatef(rotation, 0.0f, 0.0f, 1.0f);
@@ -3309,7 +3309,7 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
rlVertex2f(dest.width, 0.0f);
rlEnd();
rlPopMatrix();
- rlDisableTexture();
+ rlSetTexture(0);
*/
}
}
@@ -3372,7 +3372,7 @@ void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest,
coordD.x = (nPatchInfo.source.x + nPatchInfo.source.width)/width;
coordD.y = (nPatchInfo.source.y + nPatchInfo.source.height)/height;
- rlEnableTexture(texture.id);
+ rlSetTexture(texture.id);
rlPushMatrix();
rlTranslatef(dest.x, dest.y, 0.0f);
@@ -3506,7 +3506,7 @@ void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest,
rlEnd();
rlPopMatrix();
- rlDisableTexture();
+ rlSetTexture(0);
}
}