summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rlgl.h554
1 files changed, 302 insertions, 252 deletions
diff --git a/src/rlgl.h b/src/rlgl.h
index 548709cf..c2473ee9 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -128,31 +128,45 @@
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
-#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
- // This is the maximum amount of elements (quads) per batch
- // NOTE: Be careful with text, every letter maps to a quad
- #define MAX_BATCH_ELEMENTS 8192
-#elif defined(GRAPHICS_API_OPENGL_ES2)
- // We reduce memory sizes for embedded systems (RPI and HTML5)
- // NOTE: On HTML5 (emscripten) this is allocated on heap, by default it's only 16MB!...just take care...
- #define MAX_BATCH_ELEMENTS 2048
+// Default internal render batch limits
+#ifndef DEFAULT_BATCH_BUFFER_ELEMENTS
+ #if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
+ // This is the maximum amount of elements (quads) per batch
+ // NOTE: Be careful with text, every letter maps to a quad
+ #define DEFAULT_BATCH_BUFFER_ELEMENTS 8192
+ #elif defined(GRAPHICS_API_OPENGL_ES2)
+ // We reduce memory sizes for embedded systems (RPI and HTML5)
+ // NOTE: On HTML5 (emscripten) this is allocated on heap,
+ // by default it's only 16MB!...just take care...
+ #define DEFAULT_BATCH_BUFFER_ELEMENTS 2048
+ #endif
+#endif
+#ifndef DEFAULT_BATCH_BUFFERS
+ #define DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering)
+#endif
+#ifndef DEFAULT_BATCH_DRAWCALLS
+ #define DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture)
#endif
-#ifndef MAX_BATCH_BUFFERING
- #define MAX_BATCH_BUFFERING 1 // Max number of buffers for batching (multi-buffering)
+// Internal Matrix stack
+#ifndef MAX_MATRIX_STACK_SIZE
+ #define MAX_MATRIX_STACK_SIZE 32 // Maximum size of Matrix stack
#endif
-#define MAX_MATRIX_STACK_SIZE 32 // Max size of Matrix stack
-#define MAX_DRAWCALL_REGISTERED 256 // Max draws by state changes (mode, texture)
// Shader and material limits
-#define MAX_SHADER_LOCATIONS 32 // Maximum number of predefined locations stored in shader struct
-#define MAX_MATERIAL_MAPS 12 // Maximum number of texture maps stored in shader struct
+#ifndef MAX_SHADER_LOCATIONS
+ #define MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported
+#endif
+#ifndef MAX_MATERIAL_MAPS
+ #define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported
+#endif
-#ifndef RL_NEAR_CULL_DISTANCE
- #define RL_NEAR_CULL_DISTANCE 0.01 // Default near cull distance
+// Projection matrix culling
+#ifndef RL_CULL_DISTANCE_NEAR
+ #define RL_CULL_DISTANCE_NEAR 0.01 // Default near cull distance
#endif
-#ifndef RL_FAR_CULL_DISTANCE
- #define RL_FAR_CULL_DISTANCE 1000.0 // Default far cull distance
+#ifndef RL_CULL_DISTANCE_FAR
+ #define RL_CULL_DISTANCE_FAR 1000.0 // Default far cull distance
#endif
// Texture parameters (equivalent to OpenGL defines)
@@ -263,10 +277,6 @@ typedef unsigned char byte;
unsigned int *vboId; // OpenGL Vertex Buffer Objects id (7 types of vertex data)
} Mesh;
- // Shader and material limits
- #define MAX_SHADER_LOCATIONS 32
- #define MAX_MATERIAL_MAPS 12
-
// Shader type (generic)
typedef struct Shader {
unsigned int id; // Shader program id
@@ -758,36 +768,52 @@ RLAPI int GetPixelDataSize(int width, int height, int format);// Get pixel data
//----------------------------------------------------------------------------------
// Dynamic vertex buffers (position + texcoords + colors + indices arrays)
-typedef struct DynamicBuffer {
- int vCounter; // vertex position counter to process (and draw) from full buffer
- int tcCounter; // vertex texcoord counter to process (and draw) from full buffer
- int cCounter; // vertex color counter to process (and draw) from full buffer
-
- 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)
- unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
+typedef struct VertexBuffer {
+ int elementsCount; // Number of elements in the buffer (QUADS)
+
+ int vCounter; // Vertex position counter to process (and draw) from full buffer
+ int tcCounter; // Vertex texcoord counter to process (and draw) from full buffer
+ int cCounter; // Vertex color counter to process (and draw) from full buffer
+
+ 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)
+ unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33)
- unsigned int *indices; // vertex indices (in case vertex data comes indexed) (6 indices per quad)
+ unsigned int *indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad)
#elif defined(GRAPHICS_API_OPENGL_ES2)
- unsigned short *indices; // vertex indices (in case vertex data comes indexed) (6 indices per quad)
+ unsigned short *indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad)
#endif
unsigned int vaoId; // OpenGL Vertex Array Object id
unsigned int vboId[4]; // OpenGL Vertex Buffer Objects id (4 types of vertex data)
-} DynamicBuffer;
+} VertexBuffer;
// Draw call type
+// NOTE: Only texture changes register a new draw, other state-change-related elements are not
+// used at this moment (vaoId, shaderId, matrices), raylib just forces a batch draw call if any
+// of those state-change happens (this is done in core module)
typedef struct DrawCall {
int mode; // Drawing mode: LINES, TRIANGLES, QUADS
int vertexCount; // Number of vertex of the draw
int vertexAlignment; // Number of vertex required for index alignment (LINES, TRIANGLES)
- //unsigned int vaoId; // Vertex array id to be used on the draw
- //unsigned int shaderId; // Shader id to be used on the draw
+ //unsigned int vaoId; // Vertex array id to be used on the draw
+ //unsigned int shaderId; // Shader id to be used on the draw
unsigned int textureId; // Texture id to be used on the draw
//Matrix projection; // Projection matrix for this draw
//Matrix modelview; // Modelview matrix for this draw
} DrawCall;
+// RenderBatch type
+typedef struct RenderBatch {
+ int buffersCount; // Number of vertex buffers (multi-buffering support)
+ int currentBuffer; // Current buffer tracking in case of multi-buffering
+ VertexBuffer *vertexBuffer; // Dynamic buffer(s) for vertex data
+
+ DrawCall *draws; // Draw calls array
+ int drawsCounter; // Draw calls counter
+ float currentDepth; // Current depth value for next draw
+} RenderBatch;
+
#if defined(SUPPORT_VR_SIMULATOR)
// VR Stereo rendering configuration for simulator
typedef struct VrStereoConfig {
@@ -801,21 +827,19 @@ typedef struct VrStereoConfig {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
typedef struct rlglData {
+ RenderBatch *currentBatch; // Current render batch
+ RenderBatch defaultBatch; // Default internal render batch
+
struct {
int currentMatrixMode; // Current matrix mode
Matrix *currentMatrix; // Current matrix pointer
Matrix modelview; // Default modelview matrix
Matrix projection; // Default projection matrix
Matrix transform; // Transform matrix to be used with rlTranslate, rlRotate, rlScale
- bool doTransform; // Use transform matrix against vertex (if required)
+ bool transformRequired; // Require transform matrix application to current draw-call vertex (if required)
Matrix stack[MAX_MATRIX_STACK_SIZE];// Matrix stack for push/pop
int stackCounter; // Matrix stack counter
- DynamicBuffer vertexData[MAX_BATCH_BUFFERING];// Default dynamic buffer for elements data
- int currentBuffer; // Current buffer tracking, multi-buffering system is supported
- DrawCall *draws; // Draw calls array
- int drawsCounter; // Draw calls counter
-
Texture2D shapesTexture; // Texture used on shapes drawing (usually a white)
Rectangle shapesTextureRec; // Texture source rectangle used on shapes drawing
unsigned int defaultTextureId; // Default texture used on shapes/poly drawing (required by shader)
@@ -823,7 +847,6 @@ typedef struct rlglData {
unsigned int defaultFShaderId; // Default fragment shader Id (used by default shader program)
Shader defaultShader; // Basic shader, support vertex color and diffuse texture
Shader currentShader; // Shader to be used on rendering (by default, defaultShader)
- float currentDepth; // Current depth value
int framebufferWidth; // Default framebuffer width
int framebufferHeight; // Default framebuffer height
@@ -879,14 +902,16 @@ static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays; // Entry point poin
static unsigned int CompileShader(const char *shaderStr, int type); // Compile custom shader and return shader id
static unsigned int LoadShaderProgram(unsigned int vShaderId, unsigned int fShaderId); // Load custom shader program
-static Shader LoadShaderDefault(void); // Load default shader (just vertex positioning and texture coloring)
-static void SetShaderDefaultLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
-static void UnloadShaderDefault(void); // Unload default shader
+static Shader LoadShaderDefault(void); // Load default shader (just vertex positioning and texture coloring)
+static void SetShaderDefaultLocations(Shader *shader); // Bind default shader locations (attributes and uniforms)
+static void UnloadShaderDefault(void); // Unload default shader
-static void LoadBuffersDefault(void); // Load default internal buffers
-static void UpdateBuffersDefault(void); // Update default internal buffers (VAOs/VBOs) with vertex data
-static void DrawBuffersDefault(void); // Draw default internal buffers vertex data
-static void UnloadBuffersDefault(void); // Unload default internal buffers vertex data from CPU and GPU
+static RenderBatch LoadRenderBatch(int numBuffers, int bufferElements); // Load a render batch system
+static void UnloadRenderBatch(RenderBatch batch); // Unload render batch system
+static void DrawRenderBatch(RenderBatch *batch); // Draw render batch data (Update->Draw->Reset)
+static void SetRenderBatchActive(RenderBatch *batch); // Set the active render batch for rlgl
+static void SetRenderBatchDefault(void); // Set default render batch for rlgl
+//static bool CheckRenderBatchLimit(RenderBatch batch, int vCount); // Check render batch vertex buffer limits
static void GenDrawCube(void); // Generate and draw cube
static void GenDrawQuad(void); // Generate and draw quad
@@ -958,7 +983,7 @@ void rlPushMatrix(void)
if (RLGL.State.currentMatrixMode == RL_MODELVIEW)
{
- RLGL.State.doTransform = true;
+ RLGL.State.transformRequired = true;
RLGL.State.currentMatrix = &RLGL.State.transform;
}
@@ -979,7 +1004,7 @@ void rlPopMatrix(void)
if ((RLGL.State.stackCounter == 0) && (RLGL.State.currentMatrixMode == RL_MODELVIEW))
{
RLGL.State.currentMatrix = &RLGL.State.modelview;
- RLGL.State.doTransform = false;
+ RLGL.State.transformRequired = false;
}
}
@@ -1091,36 +1116,36 @@ void rlBegin(int mode)
{
// Draw mode can be RL_LINES, RL_TRIANGLES and RL_QUADS
// NOTE: In all three cases, vertex are accumulated over default internal vertex buffer
- if (RLGL.State.draws[RLGL.State.drawsCounter - 1].mode != mode)
+ if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode != mode)
{
- if (RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount > 0)
+ if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount > 0)
{
- // Make sure current RLGL.State.draws[i].vertexCount is aligned a multiple of 4,
+ // 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.State.draws[RLGL.State.drawsCounter - 1].mode == RL_LINES) RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment = ((RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount < 4)? RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount : RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount%4);
- else if (RLGL.State.draws[RLGL.State.drawsCounter - 1].mode == RL_TRIANGLES) RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment = ((RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount%4)));
+ 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.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment = 0;
+ else RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = 0;
- if (rlCheckBufferLimit(RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment)) rlglDraw();
+ if (rlCheckBufferLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment)) rlglDraw();
else
{
- RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter += RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment;
- RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter += RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment;
- RLGL.State.vertexData[RLGL.State.currentBuffer].tcCounter += RLGL.State.draws[RLGL.State.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.State.drawsCounter++;
+ RLGL.currentBatch->drawsCounter++;
}
}
- if (RLGL.State.drawsCounter >= MAX_DRAWCALL_REGISTERED) rlglDraw();
+ if (RLGL.currentBatch->drawsCounter >= DEFAULT_BATCH_DRAWCALLS) rlglDraw();
- RLGL.State.draws[RLGL.State.drawsCounter - 1].mode = mode;
- RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount = 0;
- RLGL.State.draws[RLGL.State.drawsCounter - 1].textureId = RLGL.State.defaultTextureId;
+ RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode = mode;
+ RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount = 0;
+ RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId = RLGL.State.defaultTextureId;
}
}
@@ -1131,30 +1156,30 @@ void rlEnd(void)
// NOTE: In OpenGL 1.1, one glColor call can be made for all the subsequent glVertex calls
// Make sure colors count match vertex count
- if (RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter != RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter)
+ if (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter != RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter)
{
- int addColors = RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter - RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter;
+ int addColors = RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter;
for (int i = 0; i < addColors; i++)
{
- RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter] = RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter - 4];
- RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter + 1] = RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter - 3];
- RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter + 2] = RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter - 2];
- RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter + 3] = RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter - 1];
- RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter++;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter] = RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter - 4];
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter + 1] = RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter - 3];
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter + 2] = RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter - 2];
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter + 3] = RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter - 1];
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter++;
}
}
// Make sure texcoords count match vertex count
- if (RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter != RLGL.State.vertexData[RLGL.State.currentBuffer].tcCounter)
+ if (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter != RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter)
{
- int addTexCoords = RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter - RLGL.State.vertexData[RLGL.State.currentBuffer].tcCounter;
+ int addTexCoords = RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter - RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter;
for (int i = 0; i < addTexCoords; i++)
{
- RLGL.State.vertexData[RLGL.State.currentBuffer].texcoords[2*RLGL.State.vertexData[RLGL.State.currentBuffer].tcCounter] = 0.0f;
- RLGL.State.vertexData[RLGL.State.currentBuffer].texcoords[2*RLGL.State.vertexData[RLGL.State.currentBuffer].tcCounter + 1] = 0.0f;
- RLGL.State.vertexData[RLGL.State.currentBuffer].tcCounter++;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter] = 0.0f;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter + 1] = 0.0f;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter++;
}
}
@@ -1163,11 +1188,11 @@ void rlEnd(void)
// NOTE: Depth increment is dependant on rlOrtho(): z-near and z-far values,
// as well as depth buffer bit-depth (16bit or 24bit or 32bit)
// Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits)
- RLGL.State.currentDepth += (1.0f/20000.0f);
+ RLGL.currentBatch->currentDepth += (1.0f/20000.0f);
// Verify internal buffers limits
// NOTE: This check is combined with usage of rlCheckBufferLimit()
- if ((RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter) >= (MAX_BATCH_ELEMENTS*4 - 4))
+ if ((RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter) >= (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4 - 4))
{
// WARNING: If we are between rlPushMatrix() and rlPopMatrix() and we need to force a rlglDraw(),
// we need to call rlPopMatrix() before to recover *RLGL.State.currentMatrix (RLGL.State.modelview) for the next forced draw call!
@@ -1184,40 +1209,40 @@ void rlVertex3f(float x, float y, float z)
Vector3 vec = { x, y, z };
// Transform provided vector if required
- if (RLGL.State.doTransform) vec = Vector3Transform(vec, RLGL.State.transform);
+ if (RLGL.State.transformRequired) vec = Vector3Transform(vec, RLGL.State.transform);
- // Verify that MAX_BATCH_ELEMENTS limit not reached
- if (RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter < (MAX_BATCH_ELEMENTS*4))
+ // Verify that current vertex buffer elements limit has not been reached
+ if (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter < (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4))
{
- RLGL.State.vertexData[RLGL.State.currentBuffer].vertices[3*RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter] = vec.x;
- RLGL.State.vertexData[RLGL.State.currentBuffer].vertices[3*RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter + 1] = vec.y;
- RLGL.State.vertexData[RLGL.State.currentBuffer].vertices[3*RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter + 2] = vec.z;
- RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter++;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter] = vec.x;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter + 1] = vec.y;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter + 2] = vec.z;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter++;
- RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount++;
+ RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount++;
}
- else TRACELOG(LOG_ERROR, "RLGL: Batch elements overflow (MAX_BATCH_ELEMENTS)");
+ else TRACELOG(LOG_ERROR, "RLGL: Batch elements overflow");
}
// Define one vertex (position)
void rlVertex2f(float x, float y)
{
- rlVertex3f(x, y, RLGL.State.currentDepth);
+ rlVertex3f(x, y, RLGL.currentBatch->currentDepth);
}
// Define one vertex (position)
void rlVertex2i(int x, int y)
{
- rlVertex3f((float)x, (float)y, RLGL.State.currentDepth);
+ rlVertex3f((float)x, (float)y, RLGL.currentBatch->currentDepth);
}
// Define one vertex (texture coordinate)
// NOTE: Texture coordinates are limited to QUADS only
void rlTexCoord2f(float x, float y)
{
- RLGL.State.vertexData[RLGL.State.currentBuffer].texcoords[2*RLGL.State.vertexData[RLGL.State.currentBuffer].tcCounter] = x;
- RLGL.State.vertexData[RLGL.State.currentBuffer].texcoords[2*RLGL.State.vertexData[RLGL.State.currentBuffer].tcCounter + 1] = y;
- RLGL.State.vertexData[RLGL.State.currentBuffer].tcCounter++;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter] = x;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter + 1] = y;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter++;
}
// Define one vertex (normal)
@@ -1230,11 +1255,11 @@ void rlNormal3f(float x, float y, float z)
// Define one vertex (color)
void rlColor4ub(byte x, byte y, byte z, byte w)
{
- RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter] = x;
- RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter + 1] = y;
- RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter + 2] = z;
- RLGL.State.vertexData[RLGL.State.currentBuffer].colors[4*RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter + 3] = w;
- RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter++;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter] = x;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter + 1] = y;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter + 2] = z;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter + 3] = w;
+ RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter++;
}
// Define one vertex (color)
@@ -1264,35 +1289,35 @@ void rlEnableTexture(unsigned int id)
#endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- if (RLGL.State.draws[RLGL.State.drawsCounter - 1].textureId != id)
+ if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId != id)
{
- if (RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount > 0)
+ if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount > 0)
{
- // Make sure current RLGL.State.draws[i].vertexCount is aligned a multiple of 4,
+ // 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.State.draws[RLGL.State.drawsCounter - 1].mode == RL_LINES) RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment = ((RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount < 4)? RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount : RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount%4);
- else if (RLGL.State.draws[RLGL.State.drawsCounter - 1].mode == RL_TRIANGLES) RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment = ((RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount%4)));
+ 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.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment = 0;
+ else RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = 0;
- if (rlCheckBufferLimit(RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment)) rlglDraw();
+ if (rlCheckBufferLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment)) rlglDraw();
else
{
- RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter += RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment;
- RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter += RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexAlignment;
- RLGL.State.vertexData[RLGL.State.currentBuffer].tcCounter += RLGL.State.draws[RLGL.State.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.State.drawsCounter++;
+ RLGL.currentBatch->drawsCounter++;
}
}
- if (RLGL.State.drawsCounter >= MAX_DRAWCALL_REGISTERED) rlglDraw();
+ if (RLGL.currentBatch->drawsCounter >= DEFAULT_BATCH_DRAWCALLS) rlglDraw();
- RLGL.State.draws[RLGL.State.drawsCounter - 1].textureId = id;
- RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount = 0;
+ RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId = id;
+ RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount = 0;
}
#endif
}
@@ -1306,7 +1331,7 @@ void rlDisableTexture(void)
#else
// NOTE: If quads batch limit is reached,
// we force a draw call and next batch starts
- if (RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter >= (MAX_BATCH_ELEMENTS*4)) rlglDraw();
+ if (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter >= (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4)) rlglDraw();
#endif
}
@@ -1691,33 +1716,14 @@ void rlglInit(int width, int height)
RLGL.State.currentShader = RLGL.State.defaultShader;
// Init default vertex arrays buffers
- LoadBuffersDefault();
-
- // Init transformations matrix accumulator
- RLGL.State.transform = MatrixIdentity();
+ RLGL.defaultBatch = LoadRenderBatch(DEFAULT_BATCH_BUFFERS, DEFAULT_BATCH_BUFFER_ELEMENTS);
+ RLGL.currentBatch = &RLGL.defaultBatch;
- // Init draw calls tracking system
- RLGL.State.draws = (DrawCall *)RL_MALLOC(sizeof(DrawCall)*MAX_DRAWCALL_REGISTERED);
-
- for (int i = 0; i < MAX_DRAWCALL_REGISTERED; i++)
- {
- RLGL.State.draws[i].mode = RL_QUADS;
- RLGL.State.draws[i].vertexCount = 0;
- RLGL.State.draws[i].vertexAlignment = 0;
- //RLGL.State.draws[i].vaoId = 0;
- //RLGL.State.draws[i].shaderId = 0;
- RLGL.State.draws[i].textureId = RLGL.State.defaultTextureId;
- //RLGL.State.draws[i].RLGL.State.projection = MatrixIdentity();
- //RLGL.State.draws[i].RLGL.State.modelview = MatrixIdentity();
- }
-
- RLGL.State.drawsCounter = 1; // Reset draws counter
- RLGL.State.currentDepth = -1.0f; // Reset depth value
-
- // Init RLGL.State.stack matrices (emulating OpenGL 1.1)
+ // Init stack matrices (emulating OpenGL 1.1)
for (int i = 0; i < MAX_MATRIX_STACK_SIZE; i++) RLGL.State.stack[i] = MatrixIdentity();
- // Init RLGL.State.projection and RLGL.State.modelview matrices
+ // Init internal matrices
+ RLGL.State.transform = MatrixIdentity();
RLGL.State.projection = MatrixIdentity();
RLGL.State.modelview = MatrixIdentity();
RLGL.State.currentMatrix = &RLGL.State.modelview;
@@ -1766,13 +1772,12 @@ void rlglInit(int width, int height)
void rlglClose(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- UnloadShaderDefault(); // Unload default shader
- UnloadBuffersDefault(); // Unload default buffers
+ UnloadRenderBatch(RLGL.defaultBatch);
+
+ UnloadShaderDefault(); // Unload default shader
glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture
TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Unloaded default texture data from VRAM (GPU)", RLGL.State.defaultTextureId);
-
- RL_FREE(RLGL.State.draws);
#endif
}
@@ -1780,12 +1785,7 @@ void rlglClose(void)
void rlglDraw(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- // Only process data if we have data to process
- if (RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter > 0)
- {
- UpdateBuffersDefault();
- DrawBuffersDefault(); // NOTE: Stereo rendering is checked inside
- }
+ DrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside
#endif
}
@@ -1796,7 +1796,7 @@ int rlGetVersion(void)
return OPENGL_11;
#elif defined(GRAPHICS_API_OPENGL_21)
#if defined(__APPLE__)
- return OPENGL_33; // NOTE: Force OpenGL 3.3 on OSX
+ return OPENGL_33; // NOTE: Force OpenGL 3.3 on OSX
#else
return OPENGL_21;
#endif
@@ -1812,7 +1812,7 @@ bool rlCheckBufferLimit(int vCount)
{
bool overflow = false;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- if ((RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter + vCount) >= (MAX_BATCH_ELEMENTS*4)) overflow = true;
+ if ((RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter + vCount) >= (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4)) overflow = true;
#endif
return overflow;
}
@@ -3796,8 +3796,7 @@ void EndVrDrawing(void)
rlDisableTexture();
// Update and draw render texture fbo with distortion to backbuffer
- UpdateBuffersDefault();
- DrawBuffersDefault();
+ DrawRenderBatch(RLGL.currentBatch);
// Restore RLGL.State.defaultShader
RLGL.State.currentShader = RLGL.State.defaultShader;
@@ -3859,7 +3858,6 @@ static unsigned int LoadShaderProgram(unsigned int vShaderId, unsigned int fShad
unsigned int program = 0;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-
GLint success = 0;
program = glCreateProgram();
@@ -4056,44 +4054,50 @@ static void UnloadShaderDefault(void)
glDeleteProgram(RLGL.State.defaultShader.id);
}
-// Load default internal buffers
-static void LoadBuffersDefault(void)
+// Load render batch
+static RenderBatch LoadRenderBatch(int numBuffers, int bufferElements)
{
- // Initialize CPU (RAM) arrays (vertex position, texcoord, color data and indexes)
+ RenderBatch batch = { 0 };
+
+ // Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes)
//--------------------------------------------------------------------------------------------
- for (int i = 0; i < MAX_BATCH_BUFFERING; i++)
+ batch.vertexBuffer = (VertexBuffer *)RL_MALLOC(sizeof(VertexBuffer)*numBuffers);
+
+ for (int i = 0; i < numBuffers; i++)
{
- RLGL.State.vertexData[i].vertices = (float *)RL_MALLOC(sizeof(float)*3*4*MAX_BATCH_ELEMENTS); // 3 float by vertex, 4 vertex by quad
- RLGL.State.vertexData[i].texcoords = (float *)RL_MALLOC(sizeof(float)*2*4*MAX_BATCH_ELEMENTS); // 2 float by texcoord, 4 texcoord by quad
- RLGL.State.vertexData[i].colors = (unsigned char *)RL_MALLOC(sizeof(unsigned char)*4*4*MAX_BATCH_ELEMENTS); // 4 float by color, 4 colors by quad
+ batch.vertexBuffer[i].elementsCount = bufferElements;
+
+ batch.vertexBuffer[i].vertices = (float *)RL_MALLOC(sizeof(float)*3*4*bufferElements); // 3 float by vertex, 4 vertex by quad
+ batch.vertexBuffer[i].texcoords = (float *)RL_MALLOC(sizeof(float)*2*4*bufferElements); // 2 float by texcoord, 4 texcoord by quad
+ batch.vertexBuffer[i].colors = (unsigned char *)RL_MALLOC(sizeof(unsigned char)*4*4*bufferElements); // 4 float by color, 4 colors by quad
#if defined(GRAPHICS_API_OPENGL_33)
- RLGL.State.vertexData[i].indices = (unsigned int *)RL_MALLOC(sizeof(unsigned int)*6*MAX_BATCH_ELEMENTS); // 6 int by quad (indices)
+ batch.vertexBuffer[i].indices = (unsigned int *)RL_MALLOC(sizeof(unsigned int)*6*bufferElements); // 6 int by quad (indices)
#elif defined(GRAPHICS_API_OPENGL_ES2)
- RLGL.State.vertexData[i].indices = (unsigned short *)RL_MALLOC(sizeof(unsigned short)*6*MAX_BATCH_ELEMENTS); // 6 int by quad (indices)
+ batch.vertexBuffer[i].indices = (unsigned short *)RL_MALLOC(sizeof(unsigned short)*6*bufferElements); // 6 int by quad (indices)
#endif
- for (int j = 0; j < (3*4*MAX_BATCH_ELEMENTS); j++) RLGL.State.vertexData[i].vertices[j] = 0.0f;
- for (int j = 0; j < (2*4*MAX_BATCH_ELEMENTS); j++) RLGL.State.vertexData[i].texcoords[j] = 0.0f;
- for (int j = 0; j < (4*4*MAX_BATCH_ELEMENTS); j++) RLGL.State.vertexData[i].colors[j] = 0;
+ for (int j = 0; j < (3*4*bufferElements); j++) batch.vertexBuffer[i].vertices[j] = 0.0f;
+ for (int j = 0; j < (2*4*bufferElements); j++) batch.vertexBuffer[i].texcoords[j] = 0.0f;
+ for (int j = 0; j < (4*4*bufferElements); j++) batch.vertexBuffer[i].colors[j] = 0;
int k = 0;
// Indices can be initialized right now
- for (int j = 0; j < (6*MAX_BATCH_ELEMENTS); j += 6)
+ for (int j = 0; j < (6*bufferElements); j += 6)
{
- RLGL.State.vertexData[i].indices[j] = 4*k;
- RLGL.State.vertexData[i].indices[j + 1] = 4*k + 1;
- RLGL.State.vertexData[i].indices[j + 2] = 4*k + 2;
- RLGL.State.vertexData[i].indices[j + 3] = 4*k;
- RLGL.State.vertexData[i].indices[j + 4] = 4*k + 2;
- RLGL.State.vertexData[i].indices[j + 5] = 4*k + 3;
+ batch.vertexBuffer[i].indices[j] = 4*k;
+ batch.vertexBuffer[i].indices[j + 1] = 4*k + 1;
+ batch.vertexBuffer[i].indices[j + 2] = 4*k + 2;
+ batch.vertexBuffer[i].indices[j + 3] = 4*k;
+ batch.vertexBuffer[i].indices[j + 4] = 4*k + 2;
+ batch.vertexBuffer[i].indices[j + 5] = 4*k + 3;
k++;
}
- RLGL.State.vertexData[i].vCounter = 0;
- RLGL.State.vertexData[i].tcCounter = 0;
- RLGL.State.vertexData[i].cCounter = 0;
+ batch.vertexBuffer[i].vCounter = 0;
+ batch.vertexBuffer[i].tcCounter = 0;
+ batch.vertexBuffer[i].cCounter = 0;
}
TRACELOG(LOG_INFO, "RLGL: Internal vertex buffers initialized successfully in RAM (CPU)");
@@ -4101,79 +4105,103 @@ static void LoadBuffersDefault(void)
// Upload to GPU (VRAM) vertex data and initialize VAOs/VBOs
//--------------------------------------------------------------------------------------------
- for (int i = 0; i < MAX_BATCH_BUFFERING; i++)
+ for (int i = 0; i < numBuffers; i++)
{
if (RLGL.ExtSupported.vao)
{
// Initialize Quads VAO
- glGenVertexArrays(1, &RLGL.State.vertexData[i].vaoId);
- glBindVertexArray(RLGL.State.vertexData[i].vaoId);
+ glGenVertexArrays(1, &batch.vertexBuffer[i].vaoId);
+ glBindVertexArray(batch.vertexBuffer[i].vaoId);
}
// Quads - Vertex buffers binding and attributes enable
// Vertex position buffer (shader-location = 0)
- glGenBuffers(1, &RLGL.State.vertexData[i].vboId[0]);
- glBindBuffer(GL_ARRAY_BUFFER, RLGL.State.vertexData[i].vboId[0]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*MAX_BATCH_ELEMENTS, RLGL.State.vertexData[i].vertices, GL_DYNAMIC_DRAW);
+ glGenBuffers(1, &batch.vertexBuffer[i].vboId[0]);
+ glBindBuffer(GL_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[0]);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*bufferElements, batch.vertexBuffer[i].vertices, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(RLGL.State.currentShader.locs[LOC_VERTEX_POSITION]);
glVertexAttribPointer(RLGL.State.currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
// Vertex texcoord buffer (shader-location = 1)
- glGenBuffers(1, &RLGL.State.vertexData[i].vboId[1]);
- glBindBuffer(GL_ARRAY_BUFFER, RLGL.State.vertexData[i].vboId[1]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*MAX_BATCH_ELEMENTS, RLGL.State.vertexData[i].texcoords, GL_DYNAMIC_DRAW);
+ glGenBuffers(1, &batch.vertexBuffer[i].vboId[1]);
+ glBindBuffer(GL_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[1]);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*bufferElements, batch.vertexBuffer[i].texcoords, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(RLGL.State.currentShader.locs[LOC_VERTEX_TEXCOORD01]);
glVertexAttribPointer(RLGL.State.currentShader.locs[LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
// Vertex color buffer (shader-location = 3)
- glGenBuffers(1, &RLGL.State.vertexData[i].vboId[2]);
- glBindBuffer(GL_ARRAY_BUFFER, RLGL.State.vertexData[i].vboId[2]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*4*MAX_BATCH_ELEMENTS, RLGL.State.vertexData[i].colors, GL_DYNAMIC_DRAW);
+ glGenBuffers(1, &batch.vertexBuffer[i].vboId[2]);
+ glBindBuffer(GL_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[2]);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned char)*4*4*bufferElements, batch.vertexBuffer[i].colors, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(RLGL.State.currentShader.locs[LOC_VERTEX_COLOR]);
glVertexAttribPointer(RLGL.State.currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
// Fill index buffer
- glGenBuffers(1, &RLGL.State.vertexData[i].vboId[3]);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, RLGL.State.vertexData[i].vboId[3]);
+ glGenBuffers(1, &batch.vertexBuffer[i].vboId[3]);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch.vertexBuffer[i].vboId[3]);
#if defined(GRAPHICS_API_OPENGL_33)
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*6*MAX_BATCH_ELEMENTS, RLGL.State.vertexData[i].indices, GL_STATIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*6*bufferElements, batch.vertexBuffer[i].indices, GL_STATIC_DRAW);
#elif defined(GRAPHICS_API_OPENGL_ES2)
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(short)*6*MAX_BATCH_ELEMENTS, RLGL.State.vertexData[i].indices, GL_STATIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(short)*6*bufferElements, batch.vertexBuffer[i].indices, GL_STATIC_DRAW);
#endif
}
- TRACELOG(LOG_INFO, "RLGL: Internal vertex buffers uploaded successfully to VRAM (GPU)");
+ TRACELOG(LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully");
// Unbind the current VAO
if (RLGL.ExtSupported.vao) glBindVertexArray(0);
//--------------------------------------------------------------------------------------------
+
+ // Init draw calls tracking system
+ //--------------------------------------------------------------------------------------------
+ batch.draws = (DrawCall *)RL_MALLOC(sizeof(DrawCall)*DEFAULT_BATCH_DRAWCALLS);
+
+ for (int i = 0; i < DEFAULT_BATCH_DRAWCALLS; i++)
+ {
+ batch.draws[i].mode = RL_QUADS;
+ batch.draws[i].vertexCount = 0;
+ batch.draws[i].vertexAlignment = 0;
+ //batch.draws[i].vaoId = 0;
+ //batch.draws[i].shaderId = 0;
+ batch.draws[i].textureId = RLGL.State.defaultTextureId;
+ //batch.draws[i].RLGL.State.projection = MatrixIdentity();
+ //batch.draws[i].RLGL.State.modelview = MatrixIdentity();
+ }
+
+ batch.drawsCounter = 1; // Reset draws counter
+ batch.currentDepth = -1.0f; // Reset depth value
+ //--------------------------------------------------------------------------------------------
+
+ return batch;
}
-// Update default internal buffers (VAOs/VBOs) with vertex array data
-// NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0)
-// TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (change flag required)
-static void UpdateBuffersDefault(void)
+// Draw render batch
+// NOTE: We require a pointer to reset batch and increase current buffer (multi-buffer)
+static void DrawRenderBatch(RenderBatch *batch)
{
- // Update vertex buffers data
- if (RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter > 0)
+ // Update batch vertex buffers
+ //------------------------------------------------------------------------------------------------------------
+ // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0)
+ // TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (change flag required)
+ if (batch->vertexBuffer[batch->currentBuffer].vCounter > 0)
{
// Activate elements VAO
- if (RLGL.ExtSupported.vao) glBindVertexArray(RLGL.State.vertexData[RLGL.State.currentBuffer].vaoId);
+ if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId);
// Vertex positions buffer
- glBindBuffer(GL_ARRAY_BUFFER, RLGL.State.vertexData[RLGL.State.currentBuffer].vboId[0]);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter, RLGL.State.vertexData[RLGL.State.currentBuffer].vertices);
- //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*MAX_BATCH_ELEMENTS, RLGL.State.vertexData[RLGL.State.currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer
+ glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[0]);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*batch->vertexBuffer[batch->currentBuffer].vCounter, batch->vertexBuffer[batch->currentBuffer].vertices);
+ //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementsCount, batch->vertexBuffer[batch->currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer
// Texture coordinates buffer
- glBindBuffer(GL_ARRAY_BUFFER, RLGL.State.vertexData[RLGL.State.currentBuffer].vboId[1]);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*2*RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter, RLGL.State.vertexData[RLGL.State.currentBuffer].texcoords);
- //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*MAX_BATCH_ELEMENTS, RLGL.State.vertexData[RLGL.State.currentBuffer].texcoords, GL_DYNAMIC_DRAW); // Update all buffer
+ glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[1]);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*2*batch->vertexBuffer[batch->currentBuffer].vCounter, batch->vertexBuffer[batch->currentBuffer].texcoords);
+ //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*batch->vertexBuffer[batch->currentBuffer].elementsCount, batch->vertexBuffer[batch->currentBuffer].texcoords, GL_DYNAMIC_DRAW); // Update all buffer
// Colors buffer
- glBindBuffer(GL_ARRAY_BUFFER, RLGL.State.vertexData[RLGL.State.currentBuffer].vboId[2]);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter, RLGL.State.vertexData[RLGL.State.currentBuffer].colors);
- //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*MAX_BATCH_ELEMENTS, RLGL.State.vertexData[RLGL.State.currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer
+ glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[2]);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*batch->vertexBuffer[batch->currentBuffer].vCounter, batch->vertexBuffer[batch->currentBuffer].colors);
+ //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementsCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer
// NOTE: glMapBuffer() causes sync issue.
// If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job.
@@ -4183,8 +4211,8 @@ static void UpdateBuffersDefault(void)
// Another option: map the buffer object into client's memory
// Probably this code could be moved somewhere else...
- // RLGL.State.vertexData[RLGL.State.currentBuffer].vertices = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
- // if (RLGL.State.vertexData[RLGL.State.currentBuffer].vertices)
+ // batch->vertexBuffer[batch->currentBuffer].vertices = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
+ // if (batch->vertexBuffer[batch->currentBuffer].vertices)
// {
// Update vertex data
// }
@@ -4193,11 +4221,10 @@ static void UpdateBuffersDefault(void)
// Unbind the current VAO
if (RLGL.ExtSupported.vao) glBindVertexArray(0);
}
-}
-
-// Draw default internal buffers vertex data
-static void DrawBuffersDefault(void)
-{
+ //------------------------------------------------------------------------------------------------------------
+
+ // Draw batch vertex buffers (considering VR stereo if required)
+ //------------------------------------------------------------------------------------------------------------
Matrix matProjection = RLGL.State.projection;
Matrix matModelView = RLGL.State.modelview;
@@ -4213,7 +4240,7 @@ static void DrawBuffersDefault(void)
#endif
// Draw buffers
- if (RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter > 0)
+ if (batch->vertexBuffer[batch->currentBuffer].vCounter > 0)
{
// Set current shader and upload current MVP matrix
glUseProgram(RLGL.State.currentShader.id);
@@ -4233,51 +4260,51 @@ static void DrawBuffersDefault(void)
int vertexOffset = 0;
- if (RLGL.ExtSupported.vao) glBindVertexArray(RLGL.State.vertexData[RLGL.State.currentBuffer].vaoId);
+ if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId);
else
{
// Bind vertex attrib: position (shader-location = 0)
- glBindBuffer(GL_ARRAY_BUFFER, RLGL.State.vertexData[RLGL.State.currentBuffer].vboId[0]);
+ glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[0]);
glVertexAttribPointer(RLGL.State.currentShader.locs[LOC_VERTEX_POSITION], 3, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(RLGL.State.currentShader.locs[LOC_VERTEX_POSITION]);
// Bind vertex attrib: texcoord (shader-location = 1)
- glBindBuffer(GL_ARRAY_BUFFER, RLGL.State.vertexData[RLGL.State.currentBuffer].vboId[1]);
+ glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[1]);
glVertexAttribPointer(RLGL.State.currentShader.locs[LOC_VERTEX_TEXCOORD01], 2, GL_FLOAT, 0, 0, 0);
glEnableVertexAttribArray(RLGL.State.currentShader.locs[LOC_VERTEX_TEXCOORD01]);
// Bind vertex attrib: color (shader-location = 3)
- glBindBuffer(GL_ARRAY_BUFFER, RLGL.State.vertexData[RLGL.State.currentBuffer].vboId[2]);
+ glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[2]);
glVertexAttribPointer(RLGL.State.currentShader.locs[LOC_VERTEX_COLOR], 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
glEnableVertexAttribArray(RLGL.State.currentShader.locs[LOC_VERTEX_COLOR]);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, RLGL.State.vertexData[RLGL.State.currentBuffer].vboId[3]);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[3]);
}
glActiveTexture(GL_TEXTURE0);
- for (int i = 0; i < RLGL.State.drawsCounter; i++)
+ for (int i = 0; i < batch->drawsCounter; i++)
{
- glBindTexture(GL_TEXTURE_2D, RLGL.State.draws[i].textureId);
+ glBindTexture(GL_TEXTURE_2D, batch->draws[i].textureId);
// TODO: Find some way to bind additional textures --> Use global texture IDs? Register them on draw[i]?
//if (RLGL.State.currentShader->locs[LOC_MAP_SPECULAR] > 0) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textureUnit1_id); }
//if (RLGL.State.currentShader->locs[LOC_MAP_SPECULAR] > 0) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, textureUnit2_id); }
- if ((RLGL.State.draws[i].mode == RL_LINES) || (RLGL.State.draws[i].mode == RL_TRIANGLES)) glDrawArrays(RLGL.State.draws[i].mode, vertexOffset, RLGL.State.draws[i].vertexCount);
+ if ((batch->draws[i].mode == RL_LINES) || (batch->draws[i].mode == RL_TRIANGLES)) glDrawArrays(batch->draws[i].mode, vertexOffset, batch->draws[i].vertexCount);
else
{
#if defined(GRAPHICS_API_OPENGL_33)
// We need to define the number of indices to be processed: quadsCount*6
// NOTE: The final parameter tells the GPU the offset in bytes from the
// start of the index buffer to the location of the first index to process
- glDrawElements(GL_TRIANGLES, RLGL.State.draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(sizeof(GLuint)*vertexOffset/4*6));
+ glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(sizeof(GLuint)*vertexOffset/4*6));
#elif defined(GRAPHICS_API_OPENGL_ES2)
- glDrawElements(GL_TRIANGLES, RLGL.State.draws[i].vertexCount/4*6, GL_UNSIGNED_SHORT, (GLvoid *)(sizeof(GLushort)*vertexOffset/4*6));
+ glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_SHORT, (GLvoid *)(sizeof(GLushort)*vertexOffset/4*6));
#endif
}
- vertexOffset += (RLGL.State.draws[i].vertexCount + RLGL.State.draws[i].vertexAlignment);
+ vertexOffset += (batch->draws[i].vertexCount + batch->draws[i].vertexAlignment);
}
if (!RLGL.ExtSupported.vao)
@@ -4293,36 +4320,40 @@ static void DrawBuffersDefault(void)
glUseProgram(0); // Unbind shader program
}
-
+ //------------------------------------------------------------------------------------------------------------
+
+ // Reset batch buffers
+ //------------------------------------------------------------------------------------------------------------
// Reset vertex counters for next frame
- RLGL.State.vertexData[RLGL.State.currentBuffer].vCounter = 0;
- RLGL.State.vertexData[RLGL.State.currentBuffer].tcCounter = 0;
- RLGL.State.vertexData[RLGL.State.currentBuffer].cCounter = 0;
+ batch->vertexBuffer[batch->currentBuffer].vCounter = 0;
+ batch->vertexBuffer[batch->currentBuffer].tcCounter = 0;
+ batch->vertexBuffer[batch->currentBuffer].cCounter = 0;
// Reset depth for next draw
- RLGL.State.currentDepth = -1.0f;
+ batch->currentDepth = -1.0f;
// Restore projection/modelview matrices
RLGL.State.projection = matProjection;
RLGL.State.modelview = matModelView;
- // Reset RLGL.State.draws array
- for (int i = 0; i < MAX_DRAWCALL_REGISTERED; i++)
+ // Reset RLGL.currentBatch->draws array
+ for (int i = 0; i < DEFAULT_BATCH_DRAWCALLS; i++)
{
- RLGL.State.draws[i].mode = RL_QUADS;
- RLGL.State.draws[i].vertexCount = 0;
- RLGL.State.draws[i].textureId = RLGL.State.defaultTextureId;
+ batch->draws[i].mode = RL_QUADS;
+ batch->draws[i].vertexCount = 0;
+ batch->draws[i].textureId = RLGL.State.defaultTextureId;
}
- RLGL.State.drawsCounter = 1;
+ batch->drawsCounter = 1;
+ //------------------------------------------------------------------------------------------------------------
- // Change to next buffer in the list
- RLGL.State.currentBuffer++;
- if (RLGL.State.currentBuffer >= MAX_BATCH_BUFFERING) RLGL.State.currentBuffer = 0;
+ // Change to next buffer in the list (in case of multi-buffering)
+ batch->currentBuffer++;
+ if (batch->currentBuffer >= batch->buffersCount) batch->currentBuffer = 0;
}
// Unload default internal buffers vertex data from CPU and GPU
-static void UnloadBuffersDefault(void)
+static void UnloadRenderBatch(RenderBatch batch)
{
// Unbind everything
if (RLGL.ExtSupported.vao) glBindVertexArray(0);
@@ -4333,23 +4364,42 @@ static void UnloadBuffersDefault(void)
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- for (int i = 0; i < MAX_BATCH_BUFFERING; i++)
+ // Unload all vertex buffers data
+ for (int i = 0; i < batch.buffersCount; i++)
{
// Delete VBOs from GPU (VRAM)
- glDeleteBuffers(1, &RLGL.State.vertexData[i].vboId[0]);
- glDeleteBuffers(1, &RLGL.State.vertexData[i].vboId[1]);
- glDeleteBuffers(1, &RLGL.State.vertexData[i].vboId[2]);
- glDeleteBuffers(1, &RLGL.State.vertexData[i].vboId[3]);
+ glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[0]);
+ glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[1]);
+ glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[2]);
+ glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[3]);
// Delete VAOs from GPU (VRAM)
- if (RLGL.ExtSupported.vao) glDeleteVertexArrays(1, &RLGL.State.vertexData[i].vaoId);
+ if (RLGL.ExtSupported.vao) glDeleteVertexArrays(1, &batch.vertexBuffer[i].vaoId);
// Free vertex arrays memory from CPU (RAM)
- RL_FREE(RLGL.State.vertexData[i].vertices);
- RL_FREE(RLGL.State.vertexData[i].texcoords);
- RL_FREE(RLGL.State.vertexData[i].colors);
- RL_FREE(RLGL.State.vertexData[i].indices);
+ RL_FREE(batch.vertexBuffer[i].vertices);
+ RL_FREE(batch.vertexBuffer[i].texcoords);
+ RL_FREE(batch.vertexBuffer[i].colors);
+ RL_FREE(batch.vertexBuffer[i].indices);
}
+
+ // Unload arrays
+ RL_FREE(batch.vertexBuffer);
+ RL_FREE(batch.draws);
+}
+
+// Set the active render batch for rlgl
+static void SetRenderBatchActive(RenderBatch *batch)
+{
+ DrawRenderBatch(RLGL.currentBatch);
+ RLGL.currentBatch = batch;
+}
+
+// Set default render batch for rlgl
+static void SetRenderBatchDefault(void)
+{
+ DrawRenderBatch(RLGL.currentBatch);
+ RLGL.currentBatch = &RLGL.defaultBatch;
}
// Renders a 1x1 XY quad in NDC