REDESIGNED: Simplify vertex data recording

Instead of registering vertex texcoords and colors on every call, we keep the last defined value and we record everything on `glVertex*()`. Actually that behavior is aligned with OpenGL 1.1 standard.
This commit is contained in:
Ray 2021-10-06 01:17:20 +02:00
parent 7439c7547b
commit 9a4fb25285

View File

@ -288,10 +288,6 @@ typedef enum {
typedef struct rlVertexBuffer {
int elementCount; // 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)
@ -851,11 +847,16 @@ typedef struct rlglData {
rlRenderBatch defaultBatch; // Default internal render batch
struct {
int vertexCounter; // Vertex counter to process (and draw) from full buffer
float texcoordx, texcoordy; // Current active texture coordinate
float normalx, normaly, normalz; // Current active normal
unsigned char colorr, colorg, colorb, colora; // Current active color
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
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 transformRequired; // Require transform matrix application to current draw-call vertex (if required)
Matrix stack[RL_MAX_MATRIX_STACK_SIZE];// Matrix stack for push/pop
int stackCounter; // Matrix stack counter
@ -870,8 +871,8 @@ typedef struct rlglData {
int *currentShaderLocs; // Current shader locations pointer to be used on rendering (by default, defaultShaderLocs)
bool stereoRender; // Stereo rendering flag
Matrix projectionStereo[2]; // VR stereo rendering eyes projection matrices
Matrix viewOffsetStereo[2]; // VR stereo rendering eyes view offset matrices
Matrix projectionStereo[2]; // VR stereo rendering eyes projection matrices
Matrix viewOffsetStereo[2]; // VR stereo rendering eyes view offset matrices
int currentBlendMode; // Blending mode active
int glBlendSrcFactor; // Blending source factor
@ -1232,10 +1233,7 @@ void rlBegin(int mode)
if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment))
{
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.State.vertexCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->drawCounter++;
}
}
@ -1251,39 +1249,6 @@ void rlBegin(int mode)
// Finish vertex providing
void rlEnd(void)
{
// Make sure vertexCount is the same for vertices, texcoords, colors and normals
// 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.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter != RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->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.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.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter != RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->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.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++;
}
}
// TODO: Make sure normals count match vertex count... if normals support is added in a future... :P
// 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)
@ -1291,8 +1256,7 @@ void rlEnd(void)
// Verify internal buffers limits
// NOTE: This check is combined with usage of rlCheckRenderBatchLimit()
if ((RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter) >=
(RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4))
if (RLGL.State.vertexCounter >= (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4))
{
// WARNING: If we are between rlPushMatrix() and rlPopMatrix() and we need to force a rlDrawRenderBatch(),
// we need to call rlPopMatrix() before to recover *RLGL.State.currentMatrix (RLGL.State.modelview) for the next forced draw call!
@ -1319,13 +1283,28 @@ void rlVertex3f(float x, float y, float z)
}
// 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].elementCount*4))
if (RLGL.State.vertexCounter < (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4))
{
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter] = tx;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter + 1] = ty;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter + 2] = tz;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter++;
// Add vertices
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter] = tx;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 1] = ty;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.State.vertexCounter + 2] = tz;
// Add current texcoord
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter] = RLGL.State.texcoordx;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].texcoords[2*RLGL.State.vertexCounter + 1] = RLGL.State.texcoordy;
// Add current normal
// TODO.
// Add current color
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter] = RLGL.State.colorr;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 1] = RLGL.State.colorg;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 2] = RLGL.State.colorb;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].colors[4*RLGL.State.vertexCounter + 3] = RLGL.State.colora;
RLGL.State.vertexCounter++;
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount++;
}
else TRACELOG(RL_LOG_ERROR, "RLGL: Batch elements overflow");
@ -1347,26 +1326,26 @@ void rlVertex2i(int x, int y)
// NOTE: Texture coordinates are limited to QUADS only
void rlTexCoord2f(float x, float y)
{
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++;
RLGL.State.texcoordx = x;
RLGL.State.texcoordy = y;
}
// Define one vertex (normal)
// NOTE: Normals limited to TRIANGLES only?
void rlNormal3f(float x, float y, float z)
{
// TODO: Normals usage...
RLGL.State.normalx = x;
RLGL.State.normaly = y;
RLGL.State.normalz = z;
}
// Define one vertex (color)
void rlColor4ub(unsigned char x, unsigned char y, unsigned char z, unsigned char w)
{
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++;
RLGL.State.colorr = x;
RLGL.State.colorg = y;
RLGL.State.colorb = z;
RLGL.State.colora = w;
}
// Define one vertex (color)
@ -1396,7 +1375,7 @@ void rlSetTexture(unsigned int 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 >=
if (RLGL.State.vertexCounter >=
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4)
{
rlDrawRenderBatch(RLGL.currentBatch);
@ -1423,9 +1402,7 @@ void rlSetTexture(unsigned int id)
if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment))
{
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.State.vertexCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->drawCounter++;
}
@ -2207,9 +2184,7 @@ rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements)
k++;
}
batch.vertexBuffer[i].vCounter = 0;
batch.vertexBuffer[i].tcCounter = 0;
batch.vertexBuffer[i].cCounter = 0;
RLGL.State.vertexCounter = 0;
}
TRACELOG(RL_LOG_INFO, "RLGL: Render batch vertex buffers loaded successfully in RAM (CPU)");
@ -2337,24 +2312,24 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
//------------------------------------------------------------------------------------------------------------
// 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)
if (RLGL.State.vertexCounter > 0)
{
// Activate elements VAO
if (RLGL.ExtSupported.vao) glBindVertexArray(batch->vertexBuffer[batch->currentBuffer].vaoId);
// Vertex positions buffer
glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, batch->vertexBuffer[batch->currentBuffer].vCounter*3*sizeof(float), batch->vertexBuffer[batch->currentBuffer].vertices);
glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*3*sizeof(float), batch->vertexBuffer[batch->currentBuffer].vertices);
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer
// Texture coordinates buffer
glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, batch->vertexBuffer[batch->currentBuffer].vCounter*2*sizeof(float), batch->vertexBuffer[batch->currentBuffer].texcoords);
glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*2*sizeof(float), batch->vertexBuffer[batch->currentBuffer].texcoords);
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].texcoords, GL_DYNAMIC_DRAW); // Update all buffer
// Colors buffer
glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[2]);
glBufferSubData(GL_ARRAY_BUFFER, 0, batch->vertexBuffer[batch->currentBuffer].vCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors);
glBufferSubData(GL_ARRAY_BUFFER, 0, RLGL.State.vertexCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors);
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer
// NOTE: glMapBuffer() causes sync issue.
@ -2399,7 +2374,7 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
}
// Draw buffers
if (batch->vertexBuffer[batch->currentBuffer].vCounter > 0)
if (RLGL.State.vertexCounter > 0)
{
// Set current shader and upload current MVP matrix
glUseProgram(RLGL.State.currentShaderId);
@ -2494,9 +2469,7 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
// Reset batch buffers
//------------------------------------------------------------------------------------------------------------
// Reset vertex counters for next frame
batch->vertexBuffer[batch->currentBuffer].vCounter = 0;
batch->vertexBuffer[batch->currentBuffer].tcCounter = 0;
batch->vertexBuffer[batch->currentBuffer].cCounter = 0;
RLGL.State.vertexCounter = 0;
// Reset depth for next draw
batch->currentDepth = -1.0f;
@ -2552,7 +2525,7 @@ bool rlCheckRenderBatchLimit(int vCount)
bool overflow = false;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if ((RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter + vCount) >=
if ((RLGL.State.vertexCounter + vCount) >=
(RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4))
{
int currentMode = RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode;