aboutsummaryrefslogtreecommitdiff
path: root/src/rlgl.c
diff options
context:
space:
mode:
authorraysan5 <raysan5@gmail.com>2014-04-09 20:25:26 +0200
committerraysan5 <raysan5@gmail.com>2014-04-09 20:25:26 +0200
commite6b82cb111c3485c5e6131fe29791f938305bce3 (patch)
tree01f1a6968b784d07d63f6bf741c1527145cea25c /src/rlgl.c
parentc04f37d0f5f75c3e112d71444e589513396c9d0f (diff)
downloadraylib-e6b82cb111c3485c5e6131fe29791f938305bce3.tar.gz
raylib-e6b82cb111c3485c5e6131fe29791f938305bce3.zip
Lots of changes, most of them under testing-review
Added a Tracing/Log system Added OGG stream music support (DOESN'T WORK) Added Compressed textures support * This update is probably very buggy...
Diffstat (limited to 'src/rlgl.c')
-rw-r--r--src/rlgl.c198
1 files changed, 146 insertions, 52 deletions
diff --git a/src/rlgl.c b/src/rlgl.c
index e25e72be..8a758a22 100644
--- a/src/rlgl.c
+++ b/src/rlgl.c
@@ -31,7 +31,7 @@
#include <stdio.h> // Standard input / output lib
#include <stdlib.h> // Declares malloc() and free() for memory management, rand()
-#include "raymath.h" // Required for data type Matrix and Matrix functions
+// TODO: Security check in case multiple USE_OPENGL_* defined
#ifdef USE_OPENGL_11
#include <GL/gl.h> // Extensions loading lib
@@ -51,7 +51,7 @@
//----------------------------------------------------------------------------------
#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 vertex-transformations)
+#define TEMP_VERTEX_BUFFER_SIZE 4096 // Temporal Vertex Buffer (required for vertex-transformations)
//----------------------------------------------------------------------------------
// Types and Structures Definition
@@ -226,9 +226,7 @@ void rlPushMatrix()
{
if (stackCounter == MATRIX_STACK_SIZE - 1)
{
- printf("ERROR: Stack Buffer Overflow! (MAX 16 MATRIX)");
-
- exit(1);
+ TraceLog(ERROR, "Stack Buffer Overflow (MAX %i Matrix)", MATRIX_STACK_SIZE);
}
stack[stackCounter] = *currentMatrix;
@@ -667,17 +665,22 @@ void rlglInit()
if (error != GLEW_OK)
{
- fprintf(stderr, "Failed to initialize GLEW - Error: %s\n", glewGetErrorString(error));
- exit(1);
+ TraceLog(ERROR, "Failed to initialize GLEW - Error Code: %s\n", glewGetErrorString(error));
}
- if (glewIsSupported("GL_VERSION_3_3")) printf("OpenGL 3.3 initialized\n");
+ if (glewIsSupported("GL_VERSION_3_3")) TraceLog(INFO, "OpenGL 3.3 initialized\n");
+
+ // Print OpenGL and GLSL version
+ TraceLog(INFO, "Vendor: %s", glGetString(GL_VENDOR));
+ TraceLog(INFO, "Renderer: %s", glGetString(GL_RENDERER));
+ TraceLog(INFO, "Version: %s", glGetString(GL_VERSION));
+ TraceLog(INFO, "GLSL: %s\n", glGetString(0x8B8C)); //GL_SHADING_LANGUAGE_VERSION
+
/*
// TODO: GLEW is a big library that loads ALL extensions, maybe using glad we can only load required ones...
if (!gladLoadGL())
{
- fprintf(stderr, printf("Failed to initialize glad.\n");
- exit(1);
+ TraceLog("ERROR: Failed to initialize glad\n");
}
*/
// Set default draw mode
@@ -707,13 +710,7 @@ void rlglInit()
// Get handles to GLSL uniform vars locations (fragment-shader)
textureLoc = glGetUniformLocation(shaderProgram, "texture0");
- printf("Default shaders loaded\n\n");
-
- // Print OpenGL and GLSL version
- 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
+ TraceLog(INFO, "Default shader loaded");
InitializeBuffers(); // Init vertex arrays
InitializeVAOs(); // Init VBO and VAO
@@ -726,7 +723,10 @@ 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 = rlglLoadTexture(1, 1, pixels);
+ whiteTexture = rlglLoadTexture(1, 1, pixels);
+
+ if (whiteTexture != 0) TraceLog(INFO, "Base white texture successfully created, id: %i", whiteTexture);
+ else TraceLog(WARNING, "Base white texture could not be created");
// Init draw calls tracking system
draws = (DrawCall *)malloc(sizeof(DrawCall)*MAX_DRAWS_BY_TEXTURE);
@@ -836,16 +836,14 @@ void rlglDraw()
glBindVertexArray(vaoQuads);
}
- //printf("\nRequired Draws: %i\n", drawsCounter);
+ //TraceLog(INFO, "Draws required per frame: %i", drawsCounter);
for (int i = 0; i < drawsCounter; i++)
{
numQuads = draws[i].vCount/4;
numIndicesToProcess = numQuads*6; // Get number of Quads * 6 index by Quad
- //printf("Quads to render: %i - ", numQuads);
- //printf("Vertex Count: %i - ", draws[i].vCount);
- //printf("Binding texture: %i\n", draws[i].texId);
+ //TraceLog(INFO, "Quads to render: %i - Vertex Count: %i", numQuads, draws[i].vCount);
glBindTexture(GL_TEXTURE_2D, draws[i].texId);
@@ -882,7 +880,10 @@ void rlglDraw()
#endif
}
-void rlglDrawModel(Model model, bool wires)
+#endif // End for OpenGL 3.3+ and ES2 only functions
+
+// Draw a 3d model
+void rlglDrawModel(Model model, Vector3 position, float scale, bool wires)
{
if (wires) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -892,19 +893,19 @@ void rlglDrawModel(Model model, bool wires)
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
+ glVertexPointer(3, GL_FLOAT, 0, model.data.vertices); // Pointer to vertex coords array
+ glTexCoordPointer(2, GL_FLOAT, 0, model.data.texcoords); // Pointer to texture coords array
+ glNormalPointer(GL_FLOAT, 0, model.data.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);
+ //rlRotatef(rotation * GetFrameTime(), 0, 1, 0);
rlScalef(scale, scale, scale);
- rlColor4ub(color.r, color.g, color.b, color.a);
+ rlColor4ub(1.0f, 1.0f, 1.0f, 1.0f);
- glDrawArrays(GL_TRIANGLES, 0, model.numVertices);
+ glDrawArrays(GL_TRIANGLES, 0, model.data.numVertices);
rlPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY); // Disable vertex array
@@ -912,7 +913,7 @@ void rlglDrawModel(Model model, bool wires)
glDisableClientState(GL_NORMAL_ARRAY); // Disable normals array
#endif
-#ifdef USE_OPENGL_33
+#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
glUseProgram(shaderProgram); // Use our shader
Matrix modelview2 = MatrixMultiply(model.transform, modelview);
@@ -934,8 +935,6 @@ void rlglDrawModel(Model model, bool wires)
if (wires) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
-#endif
-
// Initialize Graphics Device (OpenGL stuff)
void rlglInitGraphicsDevice(int fbWidth, int fbHeight)
{
@@ -968,7 +967,7 @@ void rlglInitGraphicsDevice(int fbWidth, int fbHeight)
rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
- // TODO: Review all shapes/models are drawn CCW and enable backface culling
+ // NOTE: All shapes/models triangles are drawn CCW
glEnable(GL_CULL_FACE); // Enable backface culling (Disabled by default)
//glCullFace(GL_BACK); // Cull the Back face (default)
@@ -978,11 +977,13 @@ void rlglInitGraphicsDevice(int fbWidth, int fbHeight)
glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation) (Deprecated on OpenGL 3.3+)
// Possible options: GL_SMOOTH (Color interpolation) or GL_FLAT (no interpolation)
#endif
+
+ TraceLog(INFO, "OpenGL graphics device initialized");
}
// Convert image data to OpenGL texture (returns OpenGL valid Id)
// NOTE: Image is not unloaded, it should be done manually...
-unsigned int rlglLoadTexture(int width, int height, unsigned char *pixels)
+unsigned int rlglLoadTexture(int width, int height, unsigned char *data)
{
glBindTexture(GL_TEXTURE_2D,0); // Free any old binding
@@ -998,7 +999,7 @@ unsigned int rlglLoadTexture(int width, int height, unsigned char *pixels)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // Filter for pixel-perfect drawing, alternative: GL_LINEAR
-#ifdef USE_OPENGL_33
+#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
// 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)
@@ -1008,20 +1009,84 @@ unsigned int rlglLoadTexture(int width, int height, unsigned char *pixels)
// NOTE: Not using mipmappings (texture for 2D drawing)
// At this point we have the image converted to texture and uploaded to GPU
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
// At this point we have the image converted to texture and uploaded to GPU
// Unbind current texture
glBindTexture(GL_TEXTURE_2D, 0);
- printf("New texture created, id: %i (%i x %i)\n", id, width, height);
+ TraceLog(INFO, "New texture created, id: %i (%i x %i)", id, width, height);
return id;
}
-#ifdef USE_OPENGL_33
-unsigned int rlglLoadModel(VertexData data)
+
+#ifdef USE_OPENGL_33
+
+#define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
+#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
+#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
+
+// Convert image data to OpenGL texture (returns OpenGL valid Id)
+// NOTE: Expected compressed data from DDS file
+unsigned int rlglLoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int format)
+{
+ // Create one OpenGL texture
+ GLuint id;
+ int compFormat = 0;
+
+ TraceLog(DEBUG, "Compressed texture width: %i", width);
+ TraceLog(DEBUG, "Compressed texture height: %i", height);
+ TraceLog(DEBUG, "Compressed texture mipmap levels: %i", mipmapCount);
+ TraceLog(DEBUG, "Compressed texture format: 0x%x", format);
+
+ switch(format)
+ {
+ case FOURCC_DXT1: compFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
+ case FOURCC_DXT3: compFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
+ case FOURCC_DXT5: compFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
+ default: compFormat = -1; break;
+ }
+
+ if (compFormat == -1)
+ {
+ TraceLog(WARNING, "Texture compressed format not recognized");
+ id = 0;
+ }
+ else
+ {
+ glGenTextures(1, &id);
+
+ // Bind the texture
+ glBindTexture(GL_TEXTURE_2D, id);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ unsigned int blockSize = (compFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
+ unsigned int offset = 0;
+
+ // Load the mipmaps
+ for (int level = 0; level < mipmapCount && (width || height); level++)
+ {
+ unsigned int size = ((width+3)/4)*((height+3)/4)*blockSize;
+
+ glCompressedTexImage2D(GL_TEXTURE_2D, level, compFormat, width, height, 0, size, data + offset);
+
+ offset += size;
+ width /= 2;
+ height /= 2;
+
+ // Security check for NPOT textures
+ if (width < 1) width = 1;
+ if (height < 1) height = 1;
+ }
+ }
+
+ return id;
+}
+
+// Load vertex data into a VAO
+unsigned int rlglLoadModel(VertexData mesh)
{
GLuint vaoModel; // Vertex Array Objects (VAO)
GLuint vertexBuffer[3]; // Vertex Buffer Objects (VBO)
@@ -1035,17 +1100,17 @@ unsigned int rlglLoadModel(VertexData data)
// Enable vertex attributes
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*data.numVertices, data.vertices, GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh.numVertices, mesh.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);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*mesh.numVertices, mesh.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);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*mesh.numVertices, mesh.normals, GL_STATIC_DRAW);
//glEnableVertexAttribArray(normalLoc);
//glVertexAttribPointer(normalLoc, 3, GL_FLOAT, 0, 0, 0);
@@ -1077,7 +1142,7 @@ unsigned char *rlglReadScreenPixels(int width, int height)
return imgData; // NOTE: image data should be freed
}
-#ifdef USE_OPENGL_33
+#if defined(USE_OPENGL_33) || defined(USE_OPENGL_ES2)
void PrintProjectionMatrix()
{
@@ -1154,7 +1219,7 @@ static GLuint LoadDefaultShaders()
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
- return(program);
+ return program;
}
@@ -1191,14 +1256,14 @@ static GLuint LoadShaders(char *vertexFileName, char *fragmentFileName)
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
- return(program);
+ return program;
}
// Read shader text file
static char *TextFileRead(char *fn)
{
FILE *fp;
- char *content = NULL;
+ char *text = NULL;
int count=0;
@@ -1214,15 +1279,15 @@ static char *TextFileRead(char *fn)
if (count > 0)
{
- content = (char *)malloc(sizeof(char) * (count+1));
- count = fread(content, sizeof(char), count, fp);
- content[count] = '\0';
+ text = (char *)malloc(sizeof(char) * (count+1));
+ count = fread(text, sizeof(char), count, fp);
+ text[count] = '\0';
}
fclose(fp);
}
}
- return content;
+ return text;
}
// Allocate and initialize float array buffers to store vertex data (lines, triangles, quads)
@@ -1377,10 +1442,10 @@ static void InitializeVAOs()
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quadsBufferB[3]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*6*MAX_QUADS_BATCH, quads.indices, GL_STATIC_DRAW);
- printf("Using VBO double buffering\n");
+ TraceLog(INFO, "Using VBO double buffering");
#endif
- printf("Vertex buffers initialized (lines, triangles, quads)\n\n");
+ TraceLog(INFO, "Vertex buffers successfully initialized (lines, triangles, quads)\n");
// Unbind the current VAO
glBindVertexArray(0);
@@ -1475,4 +1540,33 @@ static void UpdateBuffers()
glBindVertexArray(0);
}
+#endif
+
+#ifdef RLGL_STANDALONE
+
+typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
+
+// Output a trace log message
+// NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning
+void TraceLog(int msgType, const char *text, ...)
+{
+ va_list args;
+ va_start(args, text);
+
+ switch(msgType)
+ {
+ case 0: fprintf(stdout, "INFO: "); break;
+ case 1: fprintf(stdout, "ERROR: "); break;
+ case 2: fprintf(stdout, "WARNING: "); break;
+ case 3: fprintf(logstream, "DEBUG: "); break;
+ default: break;
+ }
+
+ vfprintf(stdout, text, args);
+ fprintf(stdout, "\n");
+
+ va_end(args);
+
+ if (msgType == 1) exit(1);
+}
#endif \ No newline at end of file