|
@@ -49,9 +49,9 @@
|
|
|
//----------------------------------------------------------------------------------
|
|
|
// Defines and Macros
|
|
|
//----------------------------------------------------------------------------------
|
|
|
-#define MATRIX_STACK_SIZE 16 // TODO: REVIEW: Matrix stack required?
|
|
|
+#define MATRIX_STACK_SIZE 16 // Matrix stack max size
|
|
|
#define MAX_DRAWS_BY_TEXTURE 256 // Draws are organized by texture changes
|
|
|
-#define TEMP_VERTEX_BUFFER_SIZE 1024 // Temporal Vertex Buffer (required for post-transformations)
|
|
|
+#define TEMP_VERTEX_BUFFER_SIZE 1024 // Temporal Vertex Buffer (required for vertex-transformations)
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
// Types and Structures Definition
|
|
@@ -67,7 +67,7 @@ typedef struct {
|
|
|
float *vertices; // 3 components per vertex
|
|
|
float *colors; // 4 components per vertex
|
|
|
} VertexPositionColorBuffer;
|
|
|
-
|
|
|
+/*
|
|
|
typedef struct {
|
|
|
int vCounter;
|
|
|
int tcCounter;
|
|
@@ -76,7 +76,17 @@ typedef struct {
|
|
|
float *texcoords; // 2 components per vertex
|
|
|
float *colors; // 4 components per vertex
|
|
|
} VertexPositionColorTextureBuffer;
|
|
|
-
|
|
|
+*/
|
|
|
+/*
|
|
|
+typedef struct {
|
|
|
+ int vCounter;
|
|
|
+ int tcCounter;
|
|
|
+ int nCounter;
|
|
|
+ float *vertices; // 3 components per vertex
|
|
|
+ float *texcoords; // 2 components per vertex
|
|
|
+ float *normals; // 3 components per vertex
|
|
|
+} VertexPositionTextureNormalBuffer;
|
|
|
+*/
|
|
|
typedef struct {
|
|
|
int vCounter;
|
|
|
int tcCounter;
|
|
@@ -108,8 +118,8 @@ static int currentMatrixMode;
|
|
|
static DrawMode currentDrawMode;
|
|
|
|
|
|
// Vertex arrays for lines, triangles and quads
|
|
|
-static VertexPositionColorBuffer lines;
|
|
|
-static VertexPositionColorTextureBuffer triangles;
|
|
|
+static VertexPositionColorBuffer lines; // No texture support
|
|
|
+static VertexPositionColorBuffer triangles; // No texture support
|
|
|
static VertexPositionColorTextureIndexBuffer quads;
|
|
|
|
|
|
// Vetex-Fragment Shader Program ID
|
|
@@ -614,6 +624,14 @@ void rlDeleteTextures(unsigned int id)
|
|
|
glDeleteTextures(1, &id);
|
|
|
}
|
|
|
|
|
|
+// Unload vertex data from GPU memory
|
|
|
+void rlDeleteVertexArrays(unsigned int id)
|
|
|
+{
|
|
|
+#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
|
|
|
+ glDeleteVertexArrays(1, &id);
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
// Clear color buffer with color
|
|
|
void rlClearColor(byte r, byte g, byte b, byte a)
|
|
|
{
|
|
@@ -655,10 +673,11 @@ void rlglInit()
|
|
|
|
|
|
if (glewIsSupported("GL_VERSION_3_3")) printf("OpenGL 3.3 initialized\n");
|
|
|
/*
|
|
|
+ // TODO: GLEW is a big library that loads ALL extensions, maybe using glad we can only load required ones...
|
|
|
if (!gladLoadGL())
|
|
|
{
|
|
|
- printf("Something went wrong!\n");
|
|
|
- exit(-1);
|
|
|
+ fprintf(stderr, printf("Failed to initialize glad.\n");
|
|
|
+ exit(1);
|
|
|
}
|
|
|
*/
|
|
|
// Set default draw mode
|
|
@@ -694,7 +713,7 @@ void rlglInit()
|
|
|
printf("Vendor: %s\n", glGetString(GL_VENDOR));
|
|
|
printf("Renderer: %s\n", glGetString(GL_RENDERER));
|
|
|
printf("Version: %s\n", glGetString(GL_VERSION));
|
|
|
- printf("GLSL: %s\n\n", glGetString(0x8B8C)); // GL_SHADING_LANGUAGE_VERSION
|
|
|
+ printf("GLSL: %s\n\n", glGetString(0x8B8C)); //GL_SHADING_LANGUAGE_VERSION
|
|
|
|
|
|
InitializeBuffers(); // Init vertex arrays
|
|
|
InitializeVAOs(); // Init VBO and VAO
|
|
@@ -707,7 +726,7 @@ void rlglInit()
|
|
|
// Create default white texture for plain colors (required by shader)
|
|
|
unsigned char pixels[4] = { 255, 255, 255, 255 }; // 1 pixel RGBA (4 bytes)
|
|
|
|
|
|
- whiteTexture = rlglTexture(1, 1, pixels);
|
|
|
+ whiteTexture = rlglLoadTexture(1, 1, pixels);
|
|
|
|
|
|
// Init draw calls tracking system
|
|
|
draws = (DrawCall *)malloc(sizeof(DrawCall)*MAX_DRAWS_BY_TEXTURE);
|
|
@@ -794,8 +813,12 @@ void rlglDraw()
|
|
|
|
|
|
if (triangles.vCounter > 0)
|
|
|
{
|
|
|
+ glBindTexture(GL_TEXTURE_2D, whiteTexture);
|
|
|
+
|
|
|
glBindVertexArray(vaoTriangles);
|
|
|
glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter);
|
|
|
+
|
|
|
+ glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
}
|
|
|
|
|
|
if (quads.vCounter > 0)
|
|
@@ -830,8 +853,6 @@ void rlglDraw()
|
|
|
glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_INT, (GLvoid*) (sizeof(GLuint) * indicesOffset));
|
|
|
|
|
|
indicesOffset += draws[i].vCount/4*6;
|
|
|
-
|
|
|
- //printf("-------Next vertex offset: %i\n", indicesOffset/6*4);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -849,7 +870,7 @@ void rlglDraw()
|
|
|
lines.cCounter = 0;
|
|
|
|
|
|
triangles.vCounter = 0;
|
|
|
- triangles.vCounter = 0;
|
|
|
+ triangles.cCounter = 0;
|
|
|
|
|
|
quads.vCounter = 0;
|
|
|
quads.tcCounter = 0;
|
|
@@ -861,6 +882,58 @@ void rlglDraw()
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+void rlglDrawModel(Model model, bool wires)
|
|
|
+{
|
|
|
+ if (wires) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
|
+
|
|
|
+#ifdef USE_OPENGL_11
|
|
|
+ // NOTE: For models we use Vertex Arrays (OpenGL 1.1)
|
|
|
+ glEnableClientState(GL_VERTEX_ARRAY); // Enable vertex array
|
|
|
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Enable texture coords array
|
|
|
+ glEnableClientState(GL_NORMAL_ARRAY); // Enable normals array
|
|
|
+
|
|
|
+ glVertexPointer(3, GL_FLOAT, 0, model.vertices); // Pointer to vertex coords array
|
|
|
+ glTexCoordPointer(2, GL_FLOAT, 0, model.texcoords); // Pointer to texture coords array
|
|
|
+ glNormalPointer(GL_FLOAT, 0, model.normals); // Pointer to normals array
|
|
|
+ //glColorPointer(4, GL_UNSIGNED_BYTE, 0, model.colors); // Pointer to colors array (NOT USED)
|
|
|
+
|
|
|
+ rlPushMatrix();
|
|
|
+ rlTranslatef(position.x, position.y, position.z);
|
|
|
+ //glRotatef(rotation * GetFrameTime(), 0, 1, 0);
|
|
|
+ rlScalef(scale, scale, scale);
|
|
|
+
|
|
|
+ rlColor4ub(color.r, color.g, color.b, color.a);
|
|
|
+
|
|
|
+ glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
|
|
|
+ rlPopMatrix();
|
|
|
+
|
|
|
+ glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex array
|
|
|
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Disable texture coords array
|
|
|
+ glDisableClientState(GL_NORMAL_ARRAY); // Disable normals array
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef USE_OPENGL_33
|
|
|
+ glUseProgram(shaderProgram); // Use our shader
|
|
|
+
|
|
|
+ Matrix modelview2 = MatrixMultiply(model.transform, modelview);
|
|
|
+
|
|
|
+ // NOTE: Drawing in OpenGL 3.3+, transform is passed to shader
|
|
|
+ glUniformMatrix4fv(projectionMatrixLoc, 1, false, GetMatrixVector(projection));
|
|
|
+ glUniformMatrix4fv(modelviewMatrixLoc, 1, false, GetMatrixVector(modelview2));
|
|
|
+ glUniform1i(textureLoc, 0);
|
|
|
+
|
|
|
+ glBindVertexArray(model.vaoId);
|
|
|
+ //glBindTexture(GL_TEXTURE_2D, model.textureId);
|
|
|
+
|
|
|
+ glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
|
|
|
+
|
|
|
+ //glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures
|
|
|
+ glBindVertexArray(0); // Unbind VAO
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (wires) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
+}
|
|
|
+
|
|
|
#endif
|
|
|
|
|
|
// Initialize Graphics Device (OpenGL stuff)
|
|
@@ -909,7 +982,7 @@ void rlglInitGraphicsDevice(int fbWidth, int fbHeight)
|
|
|
|
|
|
// Convert image data to OpenGL texture (returns OpenGL valid Id)
|
|
|
// NOTE: Image is not unloaded, it should be done manually...
|
|
|
-unsigned int rlglTexture(int width, int height, unsigned char *pixels)
|
|
|
+unsigned int rlglLoadTexture(int width, int height, unsigned char *pixels)
|
|
|
{
|
|
|
glBindTexture(GL_TEXTURE_2D,0); // Free any old binding
|
|
|
|
|
@@ -926,7 +999,7 @@ unsigned int rlglTexture(int width, int height, unsigned char *pixels)
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
|
|
|
|
|
|
#ifdef USE_OPENGL_33
|
|
|
- // Trilinear filtering!
|
|
|
+ // Trilinear filtering
|
|
|
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate use of mipmaps (must be available)
|
|
|
//glGenerateMipmap(GL_TEXTURE_2D); // OpenGL 3.3!
|
|
@@ -947,6 +1020,39 @@ unsigned int rlglTexture(int width, int height, unsigned char *pixels)
|
|
|
return id;
|
|
|
}
|
|
|
|
|
|
+#ifdef USE_OPENGL_33
|
|
|
+unsigned int rlglLoadModel(VertexData data)
|
|
|
+{
|
|
|
+ GLuint vaoModel; // Vertex Array Objects (VAO)
|
|
|
+ GLuint vertexBuffer[3]; // Vertex Buffer Objects (VBO)
|
|
|
+
|
|
|
+ // Initialize Quads VAO (Buffer A)
|
|
|
+ glGenVertexArrays(1, &vaoModel);
|
|
|
+ glBindVertexArray(vaoModel);
|
|
|
+
|
|
|
+ // Create buffers for our vertex data (positions, texcoords, normals)
|
|
|
+ glGenBuffers(3, vertexBuffer);
|
|
|
+
|
|
|
+ // Enable vertex attributes
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]);
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*data.numVertices, data.vertices, GL_STATIC_DRAW);
|
|
|
+ glEnableVertexAttribArray(vertexLoc);
|
|
|
+ glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0);
|
|
|
+
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[1]);
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*data.numVertices, data.texcoords, GL_STATIC_DRAW);
|
|
|
+ glEnableVertexAttribArray(texcoordLoc);
|
|
|
+ glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, 0, 0, 0);
|
|
|
+
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[2]);
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*data.numVertices, data.normals, GL_STATIC_DRAW);
|
|
|
+ //glEnableVertexAttribArray(normalLoc);
|
|
|
+ //glVertexAttribPointer(normalLoc, 3, GL_FLOAT, 0, 0, 0);
|
|
|
+
|
|
|
+ return vaoModel;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
// Read screen pixel data (color buffer)
|
|
|
unsigned char *rlglReadScreenPixels(int width, int height)
|
|
|
{
|
|
@@ -1303,11 +1409,13 @@ static void UpdateBuffers()
|
|
|
|
|
|
// Triangles - vertex positions buffer
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, trianglesBuffer[0]);
|
|
|
- glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*3*MAX_TRIANGLES_BATCH, triangles.vertices, GL_DYNAMIC_DRAW);
|
|
|
-
|
|
|
+ //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*3*MAX_TRIANGLES_BATCH, triangles.vertices, GL_DYNAMIC_DRAW);
|
|
|
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*3*triangles.vCounter, triangles.vertices);
|
|
|
+
|
|
|
// Triangles - colors buffer
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, trianglesBuffer[1]);
|
|
|
- glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*3*MAX_TRIANGLES_BATCH, triangles.colors, GL_DYNAMIC_DRAW);
|
|
|
+ //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*3*MAX_TRIANGLES_BATCH, triangles.colors, GL_DYNAMIC_DRAW);
|
|
|
+ glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*4*triangles.cCounter, triangles.colors);
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
|
@@ -1355,6 +1463,12 @@ static void UpdateBuffers()
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*4*quads.vCounter, quads.colors);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ // Another option would be using buffer mapping...
|
|
|
+ //triangles.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
|
|
|
+ // Now we can modify vertices
|
|
|
+ //glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
|
+
|
|
|
//--------------------------------------------------------------
|
|
|
|
|
|
// Unbind the current VAO
|