From e94acf86f8125edfb6534a45c86493be298fea68 Mon Sep 17 00:00:00 2001 From: raysan5 <raysan5@gmail.com> Date: Tue, 3 May 2016 17:54:50 +0200 Subject: [PATCH 1/4] Reorganized internal funcs --- src/text.c | 98 +++++++++++++++++++++++------------------------------- 1 file changed, 41 insertions(+), 57 deletions(-) diff --git a/src/text.c b/src/text.c index f89d5e4ea..7bb06f442 100644 --- a/src/text.c +++ b/src/text.c @@ -69,8 +69,7 @@ static SpriteFont defaultFont; // Default font provided by raylib //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static bool PixelIsMagenta(Color p); // Check if a pixel is magenta -static int ParseImageData(Image image, int **charValues, Rectangle **charSet); // Parse image pixel data to obtain characters data +static SpriteFont LoadImageFont(Image image, Color key, int firstChar); // Load a Image font file (XNA style) static SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font) static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file) static SpriteFont LoadTTF(const char *fileName, int fontSize); // Generate a sprite font image from TTF data (font size required) @@ -210,7 +209,7 @@ extern void LoadDefaultFont(void) if (testPosX >= defaultFont.texture.width) { currentLine++; - currentPosX = 2 * charsDivisor + charsWidth[i]; + currentPosX = 2*charsDivisor + charsWidth[i]; testPosX = currentPosX; defaultFont.charRecs[i].x = charsDivisor; @@ -246,7 +245,7 @@ SpriteFont GetDefaultFont() // Load a SpriteFont image into GPU memory SpriteFont LoadSpriteFont(const char *fileName) { - SpriteFont spriteFont; + SpriteFont spriteFont = { 0 }; // Check file extension if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName); @@ -255,36 +254,7 @@ SpriteFont LoadSpriteFont(const char *fileName) else { Image image = LoadImage(fileName); - - if (image.data != NULL) - { - // Process bitmap font pixel data to get characters measures - // spriteFont chars data is filled inside the function and memory is allocated! - int numChars = ParseImageData(image, &spriteFont.charValues, &spriteFont.charRecs); - - TraceLog(DEBUG, "[%s] SpriteFont data parsed correctly", fileName); - TraceLog(DEBUG, "[%s] SpriteFont num chars detected: %i", fileName, numChars); - - spriteFont.numChars = numChars; - spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture - spriteFont.size = spriteFont.charRecs[0].height; - - spriteFont.charOffsets = (Vector2 *)malloc(spriteFont.numChars*sizeof(Vector2)); - spriteFont.charAdvanceX = (int *)malloc(spriteFont.numChars*sizeof(int)); - - for (int i = 0; i < spriteFont.numChars; i++) - { - // NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0) - spriteFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f }; - spriteFont.charAdvanceX[i] = 0; - } - } - else - { - TraceLog(WARNING, "[%s] SpriteFont could not be loaded, using default font", fileName); - spriteFont = GetDefaultFont(); - } - + if (image.data != NULL) spriteFont = LoadImageFont(image, MAGENTA, 32); UnloadImage(image); } @@ -309,7 +279,7 @@ void UnloadSpriteFont(SpriteFont spriteFont) free(spriteFont.charOffsets); free(spriteFont.charAdvanceX); - TraceLog(INFO, "Unloaded sprite font data"); + TraceLog(DEBUG, "Unloaded sprite font data"); } } @@ -517,15 +487,11 @@ void DrawFPS(int posX, int posY) // Module specific Functions Definition //---------------------------------------------------------------------------------- -// Check if a pixel is magenta -static bool PixelIsMagenta(Color p) -{ - return ((p.r == 255) && (p.g == 0) && (p.b == 255) && (p.a == 255)); -} - -// Parse image pixel data to obtain characters data (measures) -static int ParseImageData(Image image, int **charValues, Rectangle **charRecs) +// Load a Image font file (XNA style) +static SpriteFont LoadImageFont(Image image, Color key, int firstChar) { + #define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a)) + int charSpacing = 0; int lineSpacing = 0; @@ -539,13 +505,14 @@ static int ParseImageData(Image image, int **charValues, Rectangle **charRecs) Color *pixels = GetImageData(image); + // Parse image data to get charSpacing and lineSpacing for(y = 0; y < image.height; y++) { for(x = 0; x < image.width; x++) { - if (!PixelIsMagenta(pixels[y*image.width + x])) break; + if (!COLOR_EQUAL(pixels[y*image.width + x], key)) break; } - if (!PixelIsMagenta(pixels[y*image.width + x])) break; + if (!COLOR_EQUAL(pixels[y*image.width + x], key)) break; } charSpacing = x; @@ -554,7 +521,7 @@ static int ParseImageData(Image image, int **charValues, Rectangle **charRecs) int charHeight = 0; int j = 0; - while(!PixelIsMagenta(pixels[(lineSpacing + j)*image.width + charSpacing])) j++; + while(!COLOR_EQUAL(pixels[(lineSpacing + j)*image.width + charSpacing], key)) j++; charHeight = j; @@ -563,12 +530,13 @@ static int ParseImageData(Image image, int **charValues, Rectangle **charRecs) int lineToRead = 0; int xPosToRead = charSpacing; + // Parse image data to get rectangle sizes while((lineSpacing + lineToRead * (charHeight + lineSpacing)) < image.height) { while((xPosToRead < image.width) && - !PixelIsMagenta((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead]))) + !COLOR_EQUAL((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead]), key)) { - tempCharValues[index] = FONT_FIRST_CHAR + index; + tempCharValues[index] = firstChar + index; tempCharRecs[index].x = xPosToRead; tempCharRecs[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing); @@ -576,7 +544,7 @@ static int ParseImageData(Image image, int **charValues, Rectangle **charRecs) int charWidth = 0; - while(!PixelIsMagenta(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth])) charWidth++; + while(!COLOR_EQUAL(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth], key)) charWidth++; tempCharRecs[index].width = charWidth; @@ -590,20 +558,35 @@ static int ParseImageData(Image image, int **charValues, Rectangle **charRecs) } free(pixels); + + TraceLog(DEBUG, "SpriteFont data parsed correctly from image"); + + // Create spritefont with all data parsed from image + SpriteFont spriteFont = { 0 }; + + spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture + spriteFont.numChars = index; // We got tempCharValues and tempCharsRecs populated with chars data - // Now we move temp data to sized charValues and charRecs arrays (passed as parameter to the function) - // NOTE: This memory should be freed! - (*charRecs) = (Rectangle *)malloc(index*sizeof(Rectangle)); - (*charValues) = (int *)malloc(index*sizeof(int)); + // Now we move temp data to sized charValues and charRecs arrays + spriteFont.charRecs = (Rectangle *)malloc(spriteFont.numChars*sizeof(Rectangle)); + spriteFont.charValues = (int *)malloc(spriteFont.numChars*sizeof(int)); + spriteFont.charOffsets = (Vector2 *)malloc(spriteFont.numChars*sizeof(Vector2)); + spriteFont.charAdvanceX = (int *)malloc(spriteFont.numChars*sizeof(int)); - for (int i = 0; i < index; i++) + for (int i = 0; i < spriteFont.numChars; i++) { - (*charValues)[i] = tempCharValues[i]; - (*charRecs)[i] = tempCharRecs[i]; + spriteFont.charValues[i] = tempCharValues[i]; + spriteFont.charRecs[i] = tempCharRecs[i]; + + // NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0) + spriteFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f }; + spriteFont.charAdvanceX[i] = 0; } + + spriteFont.size = spriteFont.charRecs[0].height; - return index; + return spriteFont; } // Load a rBMF font file (raylib BitMap Font) @@ -687,6 +670,7 @@ static SpriteFont LoadRBMF(const char *fileName) TraceLog(DEBUG, "[%s] Image reconstructed correctly, now converting it to texture", fileName); + // Create spritefont with all data read from rbmf file spriteFont.texture = LoadTextureFromImage(image); UnloadImage(image); // Unload image data From 5f73850fa675530d6933d85a6d80684106beff69 Mon Sep 17 00:00:00 2001 From: raysan5 <raysan5@gmail.com> Date: Tue, 3 May 2016 18:04:21 +0200 Subject: [PATCH 2/4] Renamed functions for consistency --- src/audio.c | 4 ++-- src/audio.h | 4 ++-- src/raylib.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/audio.c b/src/audio.c index 39d1ee8b0..09c917854 100644 --- a/src/audio.c +++ b/src/audio.c @@ -585,7 +585,7 @@ void StopSound(Sound sound) } // Check if a sound is playing -bool SoundIsPlaying(Sound sound) +bool IsSoundPlaying(Sound sound) { bool playing = false; ALint state; @@ -764,7 +764,7 @@ void ResumeMusicStream(void) } // Check if music is playing -bool MusicIsPlaying(void) +bool IsMusicPlaying(void) { bool playing = false; ALint state; diff --git a/src/audio.h b/src/audio.h index 9c681044b..73f60ab1c 100644 --- a/src/audio.h +++ b/src/audio.h @@ -96,7 +96,7 @@ void UnloadSound(Sound sound); // Unload sound void PlaySound(Sound sound); // Play a sound void PauseSound(Sound sound); // Pause a sound void StopSound(Sound sound); // Stop playing a sound -bool SoundIsPlaying(Sound sound); // Check if a sound is currently playing +bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level) void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level) @@ -105,7 +105,7 @@ void UpdateMusicStream(void); // Updates buffe void StopMusicStream(void); // Stop music playing (close stream) void PauseMusicStream(void); // Pause music playing void ResumeMusicStream(void); // Resume playing paused music -bool MusicIsPlaying(void); // Check if music is playing +bool IsMusicPlaying(void); // Check if music is playing void SetMusicVolume(float volume); // Set volume for music (1.0 is max level) float GetMusicTimeLength(void); // Get music time length (in seconds) float GetMusicTimePlayed(void); // Get current music time played (in seconds) diff --git a/src/raylib.h b/src/raylib.h index 337b98134..bc98181b2 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -882,7 +882,7 @@ void UnloadSound(Sound sound); // Unload sound void PlaySound(Sound sound); // Play a sound void PauseSound(Sound sound); // Pause a sound void StopSound(Sound sound); // Stop playing a sound -bool SoundIsPlaying(Sound sound); // Check if a sound is currently playing +bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level) void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level) @@ -891,7 +891,7 @@ void UpdateMusicStream(void); // Updates buffe void StopMusicStream(void); // Stop music playing (close stream) void PauseMusicStream(void); // Pause music playing void ResumeMusicStream(void); // Resume playing paused music -bool MusicIsPlaying(void); // Check if music is playing +bool IsMusicPlaying(void); // Check if music is playing void SetMusicVolume(float volume); // Set volume for music (1.0 is max level) float GetMusicTimeLength(void); // Get current music time length (in seconds) float GetMusicTimePlayed(void); // Get current music time played (in seconds) From 8301980ba8f917dd445b346332c48ec3b2447511 Mon Sep 17 00:00:00 2001 From: raysan5 <raysan5@gmail.com> Date: Tue, 3 May 2016 19:20:25 +0200 Subject: [PATCH 3/4] Clean up and consistency review - Renamed some functions for consistency (default buffers) - Removed mystrdup() function (implemented inline) - Renamed TextFileRead() to ReadTextFile() --- src/rlgl.c | 299 +++++++++++++++++++++++++++-------------------------- src/rlgl.h | 16 +-- 2 files changed, 158 insertions(+), 157 deletions(-) diff --git a/src/rlgl.c b/src/rlgl.c index e021e7260..9112e47e2 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -196,23 +196,20 @@ static DrawMode currentDrawMode; static float currentDepth = -1.0f; -// Vertex arrays for lines, triangles and quads +// Default vertex buffers for lines, triangles and quads static VertexPositionColorBuffer lines; // No texture support static VertexPositionColorBuffer triangles; // No texture support static VertexPositionColorTextureIndexBuffer quads; -// Shader Programs -static Shader defaultShader; -static Shader currentShader; // By default, defaultShader - -// Vertex Array Objects (VAO) +// Default vertex buffers VAOs (if supported) static GLuint vaoLines, vaoTriangles, vaoQuads; -// Vertex Buffer Objects (VBO) -static GLuint linesBuffer[2]; -static GLuint trianglesBuffer[2]; -static GLuint quadsBuffer[4]; +// Default vertex buffers VBOs +static GLuint linesBuffer[2]; // Lines buffers (position, color) +static GLuint trianglesBuffer[2]; // Triangles buffers (position, color) +static GLuint quadsBuffer[4]; // Quads buffers (position, texcoord, color, index) +// Default buffers draw calls static DrawCall *draws; static int drawsCounter; @@ -221,11 +218,14 @@ static Vector3 *tempBuffer; static int tempBufferCount = 0; static bool useTempBuffer = false; +// Shader Programs +static Shader defaultShader; +static Shader currentShader; // By default, defaultShader + // Flags for supported extensions static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support VAO extension) // Compressed textures support flags -//static bool texCompDXTSupported = false; // DDS texture compression support static bool texCompETC1Supported = false; // ETC1 texture compression support static bool texCompETC2Supported = false; // ETC2/EAC texture compression support static bool texCompPVRTSupported = false; // PVR texture compression support @@ -233,8 +233,8 @@ static bool texCompASTCSupported = false; // ASTC texture compression support #endif // Compressed textures support flags -static bool texCompDXTSupported = false; // DDS texture compression support -static bool npotSupported = false; // NPOT textures full support +static bool texCompDXTSupported = false; // DDS texture compression support +static bool npotSupported = false; // NPOT textures full support #if defined(GRAPHICS_API_OPENGL_ES2) // NOTE: VAO functionality is exposed through extensions (OES) @@ -254,14 +254,17 @@ unsigned int whiteTexture; // Module specific Functions Declaration //---------------------------------------------------------------------------------- #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +static void LoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int compressedFormat); + static Shader LoadDefaultShader(void); static void LoadDefaultShaderLocations(Shader *shader); -static void InitializeBuffers(void); -static void InitializeBuffersGPU(void); -static void UpdateBuffers(void); -static char *TextFileRead(char *fn); +static void UnloadDefaultShader(void); -static void LoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int compressedFormat); +static void LoadDefaultBuffers(void); +static void UpdateDefaultBuffers(void); +static void UnloadDefaultBuffers(void); + +static char *ReadTextFile(const char *fileName); #endif #if defined(GRAPHICS_API_OPENGL_11) @@ -274,20 +277,6 @@ static void TraceLog(int msgType, const char *text, ...); float *MatrixToFloat(Matrix mat); // Converts Matrix to float array #endif -#if defined(GRAPHICS_API_OPENGL_ES2) -// NOTE: strdup() functions replacement (not C99, POSIX function, not available on emscripten) -// Duplicates a string, returning an identical malloc'd string -char *mystrdup(const char *str) -{ - size_t len = strlen(str) + 1; - void *newstr = malloc(len); - - if (newstr == NULL) return NULL; - - return (char *)memcpy(newstr, str, len); -} -#endif - //---------------------------------------------------------------------------------- // Module Functions Definition - Matrix operations //---------------------------------------------------------------------------------- @@ -919,13 +908,18 @@ void rlglInit(void) // NOTE: We have to duplicate string because glGetString() returns a const value // If not duplicated, it fails in some systems (Raspberry Pi) - char *extensionsDup = mystrdup(extensions); + // Equivalent to function: char *strdup(const char *str) + char *extensionsDup; + size_t len = strlen(extensions) + 1; + void *newstr = malloc(len); + if (newstr == NULL) extensionsDup = NULL; + extensionsDup = (char *)memcpy(newstr, extensions, len); // NOTE: String could be splitted using strtok() function (string.h) // NOTE: strtok() modifies the received string, it can not be const char *extList[512]; // Allocate 512 strings pointers (2 KB) - + extList[numExt] = strtok(extensionsDup, " "); while (extList[numExt] != NULL) @@ -1024,12 +1018,9 @@ void rlglInit(void) // Init default Shader (customized for GL 3.3 and ES2) defaultShader = LoadDefaultShader(); - //customShader = LoadShader("custom.vs", "custom.fs"); // Works ok - currentShader = defaultShader; - InitializeBuffers(); // Init vertex arrays - InitializeBuffersGPU(); // Init VBO and VAO + LoadDefaultBuffers(); // Initialize default vertex arrays buffers (lines, triangles, quads) // Init temp vertex buffer, used when transformation required (translate, rotate, scale) tempBuffer = (Vector3 *)malloc(sizeof(Vector3)*TEMP_VERTEX_BUFFER_SIZE); @@ -1054,54 +1045,10 @@ void rlglInit(void) void rlglClose(void) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - // Unbind everything - if (vaoSupported) glBindVertexArray(0); - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - glDisableVertexAttribArray(2); - glDisableVertexAttribArray(3); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - glUseProgram(0); - - // Delete VBOs - glDeleteBuffers(1, &linesBuffer[0]); - glDeleteBuffers(1, &linesBuffer[1]); - glDeleteBuffers(1, &trianglesBuffer[0]); - glDeleteBuffers(1, &trianglesBuffer[1]); - glDeleteBuffers(1, &quadsBuffer[0]); - glDeleteBuffers(1, &quadsBuffer[1]); - glDeleteBuffers(1, &quadsBuffer[2]); - glDeleteBuffers(1, &quadsBuffer[3]); - - if (vaoSupported) - { - // Delete VAOs - glDeleteVertexArrays(1, &vaoLines); - glDeleteVertexArrays(1, &vaoTriangles); - glDeleteVertexArrays(1, &vaoQuads); - } - - //glDetachShader(defaultShaderProgram, vertexShader); - //glDetachShader(defaultShaderProgram, fragmentShader); - //glDeleteShader(vertexShader); // Already deleted on shader compilation - //glDeleteShader(fragmentShader); // Already deleted on sahder compilation - glDeleteProgram(defaultShader.id); - - // Free vertex arrays memory - free(lines.vertices); - free(lines.colors); - - free(triangles.vertices); - free(triangles.colors); - - free(quads.vertices); - free(quads.texcoords); - free(quads.colors); - free(quads.indices); - - // Free GPU texture + UnloadDefaultShader(); + UnloadDefaultBuffers(); + + // Delete default white texture glDeleteTextures(1, &whiteTexture); TraceLog(INFO, "[TEX ID %i] Unloaded texture data (base white texture) from VRAM", whiteTexture); @@ -1113,7 +1060,7 @@ void rlglClose(void) void rlglDraw(void) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - UpdateBuffers(); + UpdateDefaultBuffers(); if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) { @@ -1846,7 +1793,9 @@ void rlglGenerateMipmaps(Texture2D texture) // NOTE: Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data free(data); -#elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) +#endif + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically", texture.id); @@ -2116,8 +2065,8 @@ Shader LoadShader(char *vsFileName, char *fsFileName) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Shaders loading from external text file - char *vShaderStr = TextFileRead(vsFileName); - char *fShaderStr = TextFileRead(fsFileName); + char *vShaderStr = ReadTextFile(vsFileName); + char *fShaderStr = ReadTextFile(fsFileName); if ((vShaderStr != NULL) && (fShaderStr != NULL)) { @@ -2418,7 +2367,7 @@ static void LoadCompressedTexture(unsigned char *data, int width, int height, in } } -// Load Shader (Vertex and Fragment) +// Load default shader (Vertex and Fragment) // NOTE: This shader program is used for batch buffers (lines, triangles, quads) static Shader LoadDefaultShader(void) { @@ -2503,43 +2452,24 @@ static void LoadDefaultShaderLocations(Shader *shader) shader->mapSpecularLoc = glGetUniformLocation(shader->id, "texture2"); } -// Read text file -// NOTE: text chars array should be freed manually -static char *TextFileRead(char *fileName) +// Unload default shader +static void UnloadDefaultShader(void) { - FILE *textFile; - char *text = NULL; - - int count = 0; - - if (fileName != NULL) - { - textFile = fopen(fileName,"rt"); - - if (textFile != NULL) - { - fseek(textFile, 0, SEEK_END); - count = ftell(textFile); - rewind(textFile); - - if (count > 0) - { - text = (char *)malloc(sizeof(char)*(count + 1)); - count = fread(text, sizeof(char), count, textFile); - text[count] = '\0'; - } - - fclose(textFile); - } - else TraceLog(WARNING, "[%s] Text file could not be opened", fileName); - } + glUseProgram(0); - return text; + //glDetachShader(defaultShaderProgram, vertexShader); + //glDetachShader(defaultShaderProgram, fragmentShader); + //glDeleteShader(vertexShader); // Already deleted on shader compilation + //glDeleteShader(fragmentShader); // Already deleted on sahder compilation + glDeleteProgram(defaultShader.id); } -// Allocate and initialize float array buffers to store vertex data (lines, triangles, quads) -static void InitializeBuffers(void) +// Load default internal buffers (lines, triangles, quads) +static void LoadDefaultBuffers(void) { + // [CPU] Allocate and initialize float array buffers to store vertex data (lines, triangles, quads) + //-------------------------------------------------------------------------------------------- + // Initialize lines arrays (vertex position and color data) lines.vertices = (float *)malloc(sizeof(float)*3*2*MAX_LINES_BATCH); // 3 float by vertex, 2 vertex by line lines.colors = (unsigned char *)malloc(sizeof(unsigned char)*4*2*MAX_LINES_BATCH); // 4 float by color, 2 colors by line @@ -2593,13 +2523,14 @@ static void InitializeBuffers(void) quads.tcCounter = 0; quads.cCounter = 0; - TraceLog(INFO, "CPU buffers (lines, triangles, quads) initialized successfully"); -} - -// Initialize Vertex Array Objects (Contain VBO) -// NOTE: lines, triangles and quads buffers use currentShader -static void InitializeBuffersGPU(void) -{ + TraceLog(INFO, "Default buffers initialized successfully in CPU (lines, triangles, quads)"); + //-------------------------------------------------------------------------------------------- + + // [GPU] Upload vertex data and initialize VAOs/VBOs (lines, triangles, quads) + // NOTE: Default buffers are linked to use currentShader (defaultShader) + //-------------------------------------------------------------------------------------------- + + // Upload and link lines vertex buffers if (vaoSupported) { // Initialize Lines VAO @@ -2622,10 +2553,10 @@ static void InitializeBuffersGPU(void) glEnableVertexAttribArray(currentShader.colorLoc); glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Lines VAO initialized successfully", vaoLines); - else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Lines VBOs initialized successfully", linesBuffer[0], linesBuffer[1]); - //-------------------------------------------------------------- + if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers (lines) VAO initialized successfully", vaoLines); + else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers (lines) VBOs initialized successfully", linesBuffer[0], linesBuffer[1]); + // Upload and link triangles vertex buffers if (vaoSupported) { // Initialize Triangles VAO @@ -2647,10 +2578,10 @@ static void InitializeBuffersGPU(void) glEnableVertexAttribArray(currentShader.colorLoc); glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Triangles VAO initialized successfully", vaoTriangles); - else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Triangles VBOs initialized successfully", trianglesBuffer[0], trianglesBuffer[1]); - //-------------------------------------------------------------- + if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers (triangles) VAO initialized successfully", vaoTriangles); + else TraceLog(INFO, "[VBO ID %i][VBO ID %i] Default buffers (triangles) VBOs initialized successfully", trianglesBuffer[0], trianglesBuffer[1]); + // Upload and link quads vertex buffers if (vaoSupported) { // Initialize Quads VAO @@ -2685,18 +2616,20 @@ static void InitializeBuffersGPU(void) glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(short)*6*MAX_QUADS_BATCH, quads.indices, GL_STATIC_DRAW); #endif - if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Quads VAO initialized successfully", vaoQuads); - else TraceLog(INFO, "[VBO ID %i][VBO ID %i][VBO ID %i][VBO ID %i] Quads VBOs initialized successfully", quadsBuffer[0], quadsBuffer[1], quadsBuffer[2], quadsBuffer[3]); + if (vaoSupported) TraceLog(INFO, "[VAO ID %i] Default buffers (quads) VAO initialized successfully", vaoQuads); + else TraceLog(INFO, "[VBO ID %i][VBO ID %i][VBO ID %i][VBO ID %i] Default buffers (quads) VBOs initialized successfully", quadsBuffer[0], quadsBuffer[1], quadsBuffer[2], quadsBuffer[3]); // Unbind the current VAO if (vaoSupported) glBindVertexArray(0); + //-------------------------------------------------------------------------------------------- } -// Update VBOs with vertex array data +// Update default 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 update GPU arrays (change flag required) -static void UpdateBuffers(void) +// TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (change flag required) +static void UpdateDefaultBuffers(void) { + // Update lines vertex buffers if (lines.vCounter > 0) { // Activate Lines VAO @@ -2712,8 +2645,8 @@ static void UpdateBuffers(void) //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*2*MAX_LINES_BATCH, lines.colors, GL_DYNAMIC_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*lines.cCounter, lines.colors); } - //-------------------------------------------------------------- + // Update triangles vertex buffers if (triangles.vCounter > 0) { // Activate Triangles VAO @@ -2729,8 +2662,8 @@ static void UpdateBuffers(void) //glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*3*MAX_TRIANGLES_BATCH, triangles.colors, GL_DYNAMIC_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*triangles.cCounter, triangles.colors); } - //-------------------------------------------------------------- + // Update quads vertex buffers if (quads.vCounter > 0) { // Activate Quads VAO @@ -2752,7 +2685,7 @@ static void UpdateBuffers(void) glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(unsigned char)*4*quads.vCounter, quads.colors); // Another option would be using buffer mapping... - //triangles.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); + //quads.vertices = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); // Now we can modify vertices //glUnmapBuffer(GL_ARRAY_BUFFER); } @@ -2761,6 +2694,83 @@ static void UpdateBuffers(void) // Unbind the current VAO if (vaoSupported) glBindVertexArray(0); } + +// Unload default buffers vertex data from CPU and GPU +static void UnloadDefaultBuffers(void) +{ + // Unbind everything + if (vaoSupported) glBindVertexArray(0); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); + glDisableVertexAttribArray(3); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + // Delete VBOs from GPU (VRAM) + glDeleteBuffers(1, &linesBuffer[0]); + glDeleteBuffers(1, &linesBuffer[1]); + glDeleteBuffers(1, &trianglesBuffer[0]); + glDeleteBuffers(1, &trianglesBuffer[1]); + glDeleteBuffers(1, &quadsBuffer[0]); + glDeleteBuffers(1, &quadsBuffer[1]); + glDeleteBuffers(1, &quadsBuffer[2]); + glDeleteBuffers(1, &quadsBuffer[3]); + + if (vaoSupported) + { + // Delete VAOs from GPU (VRAM) + glDeleteVertexArrays(1, &vaoLines); + glDeleteVertexArrays(1, &vaoTriangles); + glDeleteVertexArrays(1, &vaoQuads); + } + + // Free vertex arrays memory from CPU (RAM) + free(lines.vertices); + free(lines.colors); + + free(triangles.vertices); + free(triangles.colors); + + free(quads.vertices); + free(quads.texcoords); + free(quads.colors); + free(quads.indices); +} + +// Read text data from file +// NOTE: text chars array should be freed manually +static char *ReadTextFile(const char *fileName) +{ + FILE *textFile; + char *text = NULL; + + int count = 0; + + if (fileName != NULL) + { + textFile = fopen(fileName,"rt"); + + if (textFile != NULL) + { + fseek(textFile, 0, SEEK_END); + count = ftell(textFile); + rewind(textFile); + + if (count > 0) + { + text = (char *)malloc(sizeof(char)*(count + 1)); + count = fread(text, sizeof(char), count, textFile); + text[count] = '\0'; + } + + fclose(textFile); + } + else TraceLog(WARNING, "[%s] Text file could not be opened", fileName); + } + + return text; +} #endif //defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_11) @@ -2891,7 +2901,6 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight) #endif #if defined(RLGL_STANDALONE) - // Output a trace log message // NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning static void TraceLog(int msgType, const char *text, ...) diff --git a/src/rlgl.h b/src/rlgl.h index 714961e11..cd8e6d1db 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -292,11 +292,6 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world unsigned char *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer) void *rlglReadTexturePixels(Texture2D texture); // Read texture pixel data -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) -void PrintProjectionMatrix(void); // DEBUG: Print projection matrix -void PrintModelviewMatrix(void); // DEBUG: Print modelview matrix -#endif - #if defined(RLGL_STANDALONE) //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) @@ -309,13 +304,10 @@ void SetCustomShader(Shader shader); // Set custo void SetDefaultShader(void); // Set default shader to be used in batch draw void SetModelShader(Model *model, Shader shader); // Link a shader to a model -int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location -void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float) -void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int) -void SetShaderMapDiffuse(Shader *shader, Texture2D texture); // Default diffuse shader map texture assignment -void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture); // Normal map texture shader assignment -void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture); // Specular map texture shader assignment -void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit); // TODO: Generic shader map assignment +int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location +void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float) +void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int) +void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4) void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied) #endif From fd67e31f630476980eb09e49177958703db5b3d3 Mon Sep 17 00:00:00 2001 From: raysan5 <raysan5@gmail.com> Date: Tue, 3 May 2016 19:27:06 +0200 Subject: [PATCH 4/4] Renamed function for consistency --- examples/core_world_screen.c | 2 +- src/core.c | 4 ++-- src/raylib.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/core_world_screen.c b/examples/core_world_screen.c index d89a296bf..f3798830d 100644 --- a/examples/core_world_screen.c +++ b/examples/core_world_screen.c @@ -43,7 +43,7 @@ int main() UpdateCamera(&camera); // Update internal camera and our camera // Calculate cube screen space position (with a little offset to be in top) - cubeScreenPosition = WorldToScreen((Vector3){cubePosition.x, cubePosition.y + 2.5f, cubePosition.z}, camera); + cubeScreenPosition = GetWorldToScreen((Vector3){cubePosition.x, cubePosition.y + 2.5f, cubePosition.z}, camera); //---------------------------------------------------------------------------------- // Draw diff --git a/src/core.c b/src/core.c index b27712a72..669010f95 100644 --- a/src/core.c +++ b/src/core.c @@ -905,7 +905,7 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera) Vector3 farPoint = rlglUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 1.0f }, matProj, matView); #else // OPTION 2: Compute unprojection directly here - + // Calculate unproject matrix (multiply projection matrix and view matrix) and invert it Matrix matProjView = MatrixMultiply(matProj, matView); MatrixInvert(&matProjView); @@ -935,7 +935,7 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera) } // Returns the screen space position from a 3d world space position -Vector2 WorldToScreen(Vector3 position, Camera camera) +Vector2 GetWorldToScreen(Vector3 position, Camera camera) { // Calculate projection matrix (from perspective instead of frustum Matrix matProj = MatrixPerspective(camera.fovy, (double)GetScreenWidth()/(double)GetScreenHeight(), 0.01, 1000.0); diff --git a/src/raylib.h b/src/raylib.h index bc98181b2..8af7d2fb8 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -586,7 +586,7 @@ void BeginTextureMode(RenderTexture2D target); // Initializes rende void EndTextureMode(void); // Ends drawing to render texture Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position -Vector2 WorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position +Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) void SetTargetFPS(int fps); // Set target FPS (maximum)