From 2be8753788d99cc089f2f26e19d5dd3159ee431f Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 5 Jul 2015 18:19:18 +0200 Subject: [PATCH 01/12] Functions renaming for better consistency --- src/camera.c | 101 +++++++++++++++++++++++-------------------------- src/gestures.c | 22 ++++++----- 2 files changed, 60 insertions(+), 63 deletions(-) diff --git a/src/camera.c b/src/camera.c index cb99ba6b9..1aa39ca81 100644 --- a/src/camera.c +++ b/src/camera.c @@ -93,15 +93,6 @@ static int cameraMode = CAMERA_CUSTOM; // Module specific Functions Declaration //---------------------------------------------------------------------------------- static void ProcessCamera(Camera *camera, Vector3 *playerPosition); -/* -static void SetCameraControls(int front, int left, int back, right, up, down); -static void SetMouseSensitivity(int sensitivity); -static void SetResetPosition(Vector3 resetPosition); -static void SetResetControl(int resetKey); -static void SetPawnControl(int pawnControlKey); -static void SetFnControl(int fnControlKey); -static void SetSmoothZoomControl(int smoothZoomControlKey); -*/ //---------------------------------------------------------------------------------- // Module Functions Definition @@ -153,6 +144,53 @@ Camera UpdateCamera(Vector3 *position) return internalCamera; } + +void SetCameraControls(int frontKey, int leftKey, int backKey, int rightKey, int upKey, int downKey) +{ + cameraMovementController[0] = frontKey; + cameraMovementController[1] = leftKey; + cameraMovementController[2] = backKey; + cameraMovementController[3] = rightKey; + cameraMovementController[4] = upKey; + cameraMovementController[5] = downKey; +} + +void SetCameraMouseSensitivity(float sensitivity) +{ + mouseSensitivity = (sensitivity / 10000.0); +} + +void SetCameraResetPosition(Vector3 resetPosition) +{ + resetingPosition = resetPosition; +} + +void SetCameraResetControl(int resetKey) +{ + resetingKey = resetKey; +} + +void SetCameraPawnControl(int pawnControlKey) +{ + pawnControllingKey = pawnControlKey; +} + +void SetCameraFnControl(int fnControlKey) +{ + fnControllingKey = fnControlKey; +} + +void SetCameraSmoothZoomControl(int smoothZoomControlKey) +{ + smoothZoomControllingKey = smoothZoomControlKey; +} + +void SetCameraOrbitalTarget(Vector3 target) +{ + internalCamera.target = target; +} + + //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- @@ -408,48 +446,3 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) } #endif } - -void SetCameraControls(int frontKey, int leftKey, int backKey, int rightKey, int upKey, int downKey) -{ - cameraMovementController[0] = frontKey; - cameraMovementController[1] = leftKey; - cameraMovementController[2] = backKey; - cameraMovementController[3] = rightKey; - cameraMovementController[4] = upKey; - cameraMovementController[5] = downKey; -} - -void SetMouseSensitivity(float sensitivity) -{ - mouseSensitivity = (sensitivity / 10000.0); -} - -void SetResetPosition(Vector3 resetPosition) -{ - resetingPosition = resetPosition; -} - -void SetResetControl(int resetKey) -{ - resetingKey = resetKey; -} - -void SetPawnControl(int pawnControlKey) -{ - pawnControllingKey = pawnControlKey; -} - -void SetFnControl(int fnControlKey) -{ - fnControllingKey = fnControlKey; -} - -void SetSmoothZoomControl(int smoothZoomControlKey) -{ - smoothZoomControllingKey = smoothZoomControlKey; -} - -void SetOrbitalTarget(Vector3 target) -{ - internalCamera.target = target; -} diff --git a/src/gestures.c b/src/gestures.c index 13209b328..5b62cbff8 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -24,7 +24,6 @@ **********************************************************************************************/ #include "raylib.h" -#include "raymath.h" #include "utils.h" #include // malloc(), free() @@ -126,6 +125,7 @@ static float pinchDelta = 0; // Detected gesture static int currentGesture = GESTURE_NONE; +unsigned int enabledGestures = 0; // TODO: Currently not in use... static Vector2 touchPosition; @@ -185,40 +185,45 @@ int GetGestureType(void) return currentGesture; } +void SetGesturesEnabled(unsigned int gestureFlags) +{ + enabledGestures = gestureFlags; +} + // Get drag intensity (pixels per frame) -float GetDragIntensity(void) +float GetGestureDragIntensity(void) { return intensity; } // Get drag angle // NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise -float GetDragAngle(void) +float GetGestureDragAngle(void) { return angle; } // Get drag vector (between initial and final position) -Vector2 GetDragVector(void) +Vector2 GetGestureDragVector(void) { return dragVector; } // Hold time measured in frames -int GetHoldDuration(void) +int GetGestureHoldDuration(void) { return 0; } // Get magnitude between two pinch points -float GetPinchDelta(void) +float GetGesturePinchDelta(void) { return pinchDelta; } -// Get angle beween two pinch points +// Get angle beween two pinch points // NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise -float GetPinchAngle(void) +float GetGesturePinchAngle(void) { return 0; } @@ -417,7 +422,6 @@ extern void ProcessMotionEvent(GestureEvent event) //-------------------------------------------------------------------- } - static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, float magnitude) { float angle; From 84befaea2467879e9fd01b0728e328f7d2497405 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 5 Jul 2015 18:19:49 +0200 Subject: [PATCH 02/12] Corrected bug on GetHexValue() function --- src/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core.c b/src/core.c index 7bbe3892a..301d9e6e0 100644 --- a/src/core.c +++ b/src/core.c @@ -606,7 +606,7 @@ Color GetColor(int hexValue) // Returns hexadecimal value for a Color int GetHexValue(Color color) { - return ((color.a << 24) + (color.r << 16) + (color.g << 8) + color.b); + return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a); } // Returns a random value between min and max (both included) From c944d62374859707404ff3ac5f2c6b3babfafa9f Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 5 Jul 2015 18:21:01 +0200 Subject: [PATCH 03/12] Improved mipmaps support and image loading --- src/raylib.h | 63 +++++---- src/rlgl.c | 174 ++++++++++++++++------- src/rlgl.h | 9 +- src/text.c | 16 ++- src/textures.c | 378 +++++++++++++++++++++++++++++++------------------ 5 files changed, 413 insertions(+), 227 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 6800b2602..e03fc9b21 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -358,18 +358,19 @@ typedef enum { } TextureFormat; // Gestures type +// NOTE: It could be used as flags to enable only some gestures typedef enum { - GESTURE_NONE = 0, - GESTURE_TAP, - GESTURE_DOUBLETAP, - GESTURE_HOLD, - GESTURE_DRAG, - GESTURE_SWIPE_RIGHT, - GESTURE_SWIPE_LEFT, - GESTURE_SWIPE_UP, - GESTURE_SWIPE_DOWN, - GESTURE_PINCH_IN, - GESTURE_PINCH_OUT + GESTURE_NONE = 1, + GESTURE_TAP = 2, + GESTURE_DOUBLETAP = 4, + GESTURE_HOLD = 8, + GESTURE_DRAG = 16, + GESTURE_SWIPE_RIGHT = 32, + GESTURE_SWIPE_LEFT = 64, + GESTURE_SWIPE_UP = 128, + GESTURE_SWIPE_DOWN = 256, + GESTURE_PINCH_IN = 512, + GESTURE_PINCH_OUT = 1024 } Gestures; #ifdef __cplusplus @@ -431,14 +432,15 @@ void SetCameraMode(int mode); // Select camera mod Camera UpdateCamera(Vector3 *position); // Update camera with position void SetCameraControls(int front, int left, int back, int right, int up, int down); -void SetMouseSensitivity(float sensitivity); -void SetResetPosition(Vector3 resetPosition); -void SetResetControl(int resetKey); -void SetPawnControl(int pawnControlKey); -void SetFnControl(int fnControlKey); -void SetSmoothZoomControl(int smoothZoomControlKey); -void SetOrbitalTarget(Vector3 target); +void SetCameraMouseSensitivity(float sensitivity); +void SetCameraResetPosition(Vector3 resetPosition); +void SetCameraResetControl(int resetKey); +void SetCameraPawnControl(int pawnControlKey); +void SetCameraFnControl(int fnControlKey); +void SetCameraSmoothZoomControl(int smoothZoomControlKey); +void SetCameraOrbitalTarget(Vector3 target); +// Shaders control functions int GetShaderLocation(Shader shader, const char *uniformName); void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); @@ -488,12 +490,14 @@ Vector2 GetTouchPosition(void); // Returns touch positio // Gestures System (module: gestures) bool IsGestureDetected(void); int GetGestureType(void); -float GetDragIntensity(void); -float GetDragAngle(void); -Vector2 GetDragVector(void); -int GetHoldDuration(void); // Hold time in frames -float GetPinchDelta(void); -float GetPinchAngle(void); +void SetGesturesEnabled(unsigned int gestureFlags); + +float GetGestureDragIntensity(void); +float GetGestureDragAngle(void); +Vector2 GetGestureDragVector(void); +int GetGestureHoldDuration(void); // Hold time in frames +float GetGesturePinchDelta(void); +float GetGesturePinchAngle(void); #endif //------------------------------------------------------------------------------------ @@ -530,16 +534,19 @@ bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 // Texture Loading and Drawing Functions (Module: textures) //------------------------------------------------------------------------------------ Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) +Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit) Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource) -Image LoadImageFromData(Color *pixels, int width, int height, int format); // Load image from Color array data Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory -Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps); // Load a texture from raw data into GPU memory +Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount); // Load a texture from raw data into GPU memory Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource) -Texture2D LoadTextureFromImage(Image image, bool genMipmaps); // Load a texture from image data (and generate mipmaps) +Texture2D LoadTextureFromImage(Image image); // Load a texture from image data (and generate mipmaps) void UnloadImage(Image image); // Unload image from CPU memory (RAM) void UnloadTexture(Texture2D texture); // Unload texture from GPU memory -void ConvertToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two) +void ImageConvertToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two) +void ImageConvertFormat(Image *image, int newFormat); // Convert image data to desired format Color *GetPixelData(Image image); // Get pixel data from image as a Color struct array +Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image +void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2 diff --git a/src/rlgl.c b/src/rlgl.c index 157d8f20e..4ff652b0a 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -221,7 +221,7 @@ static bool vaoSupported = false; // VAO support (OpenGL ES2 could not support static bool npotSupported = false; // NPOT textures full support // Compressed textures support flags -static bool texCompDXTSupported = false; // DDS texture compression support +//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 @@ -232,6 +232,9 @@ static GLuint fbo, fboColorTexture, fboDepthTexture; static Model postproQuad; #endif +// Compressed textures support flags +static bool texCompDXTSupported = false; // DDS texture compression support + #if defined(GRAPHICS_API_OPENGL_ES2) // NOTE: VAO functionality is exposed through extensions (OES) static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays; @@ -263,7 +266,9 @@ static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight); static pixel *GenNextMipmap(pixel *srcData, int srcWidth, int srcHeight); #endif +#if defined(GRAPHICS_API_OPENGL_ES2) static char** StringSplit(char *baseString, const char delimiter, int *numExt); +#endif //---------------------------------------------------------------------------------- // Module Functions Definition - Matrix operations @@ -967,7 +972,7 @@ void rlglInit(void) // 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(pixels, 1, 1, UNCOMPRESSED_R8G8B8A8, 1, false); + whiteTexture = rlglLoadTexture(pixels, 1, 1, UNCOMPRESSED_R8G8B8A8, 1); if (whiteTexture != 0) TraceLog(INFO, "[TEX ID %i] Base white texture loaded successfully", whiteTexture); else TraceLog(WARNING, "Base white texture could not be loaded"); @@ -1623,7 +1628,7 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view) } // Convert image data to OpenGL texture (returns OpenGL valid Id) -unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps) +unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount) { glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding @@ -1642,7 +1647,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma TraceLog(WARNING, "DXT compressed texture format not supported"); return id; } - +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) if ((!texCompETC1Supported) && (textureFormat == COMPRESSED_ETC1_RGB)) { TraceLog(WARNING, "ETC1 compressed texture format not supported"); @@ -1666,7 +1671,8 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma TraceLog(WARNING, "ASTC compressed texture format not supported"); return id; } - +#endif + glGenTextures(1, &id); // Generate Pointer to the texture #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) @@ -1755,23 +1761,63 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma } #endif + // Texture parameters configuration + // NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used +#if defined(GRAPHICS_API_OPENGL_ES2) + // NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // Set texture to clamp on x-axis + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Set texture to clamp on y-axis +#else + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis +#endif + + // Magnification and minification filters + 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 + +#if defined(GRAPHICS_API_OPENGL_33) + if (mipmapCount > 1) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate Trilinear filtering for mipmaps (must be available) + } +#endif + + // At this point we have the texture loaded in GPU and texture parameters configured + + // NOTE: If mipmaps were not in data, they are not generated automatically + + // Unbind current texture + glBindTexture(GL_TEXTURE_2D, 0); + + if (id > 0) TraceLog(INFO, "[TEX ID %i] Texture created successfully (%ix%i)", id, width, height); + else TraceLog(WARNING, "Texture could not be created"); + + return id; +} + +// Generate mipmap data for selected texture +void rlglGenerateMipmaps(unsigned int textureId) +{ + glBindTexture(GL_TEXTURE_2D, textureId); + + int width, height; + + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); + // Check if texture is power-of-two (POT) to enable mipmap generation bool texIsPOT = false; if (((width > 0) && ((width & (width - 1)) == 0)) && ((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true; - if (genMipmaps && !texIsPOT) + if (texIsPOT) { - TraceLog(WARNING, "[TEX ID %i] Texture is not power-of-two, mipmaps can not be generated", id); - genMipmaps = false; - } - - // Generate mipmaps if required - // TODO: Improve mipmaps support #if defined(GRAPHICS_API_OPENGL_11) - if (genMipmaps) - { // Compute required mipmaps + void *data = rlglReadTexturePixels(textureId, UNCOMPRESSED_R8G8B8A8); // TODO: Detect internal format + // NOTE: data size is reallocated to fit mipmaps data int mipmapCount = GenerateMipmaps(data, width, height); @@ -1794,48 +1840,21 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma mipHeight /= 2; } - TraceLog(WARNING, "[TEX ID %i] Mipmaps generated manually on CPU side", id); - } + TraceLog(WARNING, "[TEX ID %i] Mipmaps generated manually on CPU side", textureId); + #elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - if ((mipmapCount == 1) && (genMipmaps)) - { - glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically - TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically for new texture", id); - } + glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically + TraceLog(INFO, "[TEX ID %i] Mipmaps generated automatically", textureId); #endif - // Texture parameters configuration - // NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used -#if defined(GRAPHICS_API_OPENGL_ES2) - // NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // Set texture to clamp on x-axis - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Set texture to clamp on y-axis -#else - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis -#endif - - // Magnification and minification filters - 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 - #if defined(GRAPHICS_API_OPENGL_33) - if ((mipmapCount > 1) || (genMipmaps)) - { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate Trilinear filtering for mipmaps (must be available) - } #endif - - // At this point we have the texture loaded in GPU, with mipmaps generated (if desired) and texture parameters configured - - // Unbind current texture + } + else TraceLog(WARNING, "[TEX ID %i] Texture is not power-of-two, mipmaps can not be generated", textureId); + glBindTexture(GL_TEXTURE_2D, 0); - - if (id > 0) TraceLog(INFO, "[TEX ID %i] Texture created successfully (%ix%i)", id, width, height); - else TraceLog(WARNING, "Texture could not be created"); - - return id; } // Load vertex data into a VAO (if supported) and VBO @@ -2039,6 +2058,47 @@ unsigned char *rlglReadScreenPixels(int width, int height) return imgData; // NOTE: image data should be freed } +// Read texture pixel data +void *rlglReadTexturePixels(unsigned int textureId, unsigned int format) +{ + int width, height; + + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); + //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); + //GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE + + int glFormat, glType; + void *pixels = NULL; + unsigned int size = width*height; + + switch (format) + { + case UNCOMPRESSED_GRAYSCALE: pixels = (unsigned char *)malloc(size); glFormat = GL_LUMINANCE; glType = GL_UNSIGNED_BYTE; // 8 bit per pixel (no alpha) + case UNCOMPRESSED_GRAY_ALPHA: pixels = (unsigned char *)malloc(size*2); glFormat = GL_LUMINANCE_ALPHA; glType = GL_UNSIGNED_BYTE; // 16 bpp (2 channels) + case UNCOMPRESSED_R5G6B5: pixels = (unsigned short *)malloc(size); glFormat = GL_RGB; glType = GL_UNSIGNED_SHORT_5_6_5; // 16 bpp + case UNCOMPRESSED_R8G8B8: pixels = (unsigned char *)malloc(size*3); glFormat = GL_RGB; glType = GL_UNSIGNED_BYTE; // 24 bpp + case UNCOMPRESSED_R5G5B5A1: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_5_5_5_1; // 16 bpp (1 bit alpha) + case UNCOMPRESSED_R4G4B4A4: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_4_4_4_4; // 16 bpp (4 bit alpha) + case UNCOMPRESSED_R8G8B8A8: pixels = (unsigned char *)malloc(size*4); glFormat = GL_RGBA; glType = GL_UNSIGNED_BYTE; // 32 bpp + default: TraceLog(WARNING, "Texture format not suported"); break; + } + + glBindTexture(GL_TEXTURE_2D, textureId); + + // NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding. + // Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting. + // GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.) + // GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.) + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels); + + glBindTexture(GL_TEXTURE_2D, 0); + + return pixels; +} + // Load a shader (vertex shader + fragment shader) from files Shader rlglLoadShader(char *vsFileName, char *fsFileName) { @@ -2159,15 +2219,18 @@ void rlglSetDefaultShader(void) int GetShaderLocation(Shader shader, const char *uniformName) { - int location = glGetUniformLocation(shader.id, uniformName); + int location = -1; +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + location = glGetUniformLocation(shader.id, uniformName); if (location == -1) TraceLog(WARNING, "[SHDR ID %i] Shader location for %s could not be found", shader.id, uniformName); - +#endif return location; } void SetShaderValue(Shader shader, int uniformLoc, float *value, int size) { +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) glUseProgram(shader.id); if (size == 1) glUniform1fv(uniformLoc, 1, value); // Shader uniform type: float @@ -2177,10 +2240,12 @@ void SetShaderValue(Shader shader, int uniformLoc, float *value, int size) else TraceLog(WARNING, "Shader value float array size not recognized"); glUseProgram(0); +#endif } void SetShaderMapDiffuse(Shader *shader, Texture2D texture) { +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) shader->texDiffuseId = texture.id; glUseProgram(shader->id); @@ -2193,10 +2258,12 @@ void SetShaderMapDiffuse(Shader *shader, Texture2D texture) glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); glUseProgram(0); +#endif } void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture) { +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) shader->mapNormalLoc = glGetUniformLocation(shader->id, uniformName); if (shader->mapNormalLoc == -1) TraceLog(WARNING, "[SHDR ID %i] Shader location for %s could not be found", shader->id, uniformName); @@ -2215,10 +2282,12 @@ void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D textu glActiveTexture(GL_TEXTURE0); glUseProgram(0); } +#endif } void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture) { +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) shader->mapSpecularLoc = glGetUniformLocation(shader->id, uniformName); if (shader->mapSpecularLoc == -1) TraceLog(WARNING, "[SHDR ID %i] Shader location for %s could not be found", shader->id, uniformName); @@ -2237,6 +2306,7 @@ void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D tex glActiveTexture(GL_TEXTURE0); glUseProgram(0); } +#endif } #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) @@ -2865,6 +2935,7 @@ void TraceLog(int msgType, const char *text, ...) } #endif +#if defined(GRAPHICS_API_OPENGL_ES2) static char **StringSplit(char *baseString, const char delimiter, int *numExt) { char **result = 0; @@ -2913,4 +2984,5 @@ static char **StringSplit(char *baseString, const char delimiter, int *numExt) *numExt = (count - 1); return result; -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/rlgl.h b/src/rlgl.h index 41c13ef73..e241a9c14 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -209,7 +209,9 @@ void rlglClose(void); // De-init rlgl void rlglDraw(void); // Draw VAO/VBO void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff) -unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps); // Load in GPU OpenGL texture +unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load in GPU OpenGL texture +void rlglGenerateMipmaps(unsigned int textureId); // Generate mipmap data for selected texture + Shader rlglLoadShader(char *vsFileName, char *fsFileName); // Load a shader (vertex shader + fragment shader) from files unsigned int rlglLoadShaderFromText(char *vShaderStr, char *fShaderStr); // Load a shader from text data void rlglInitPostpro(void); // Initialize postprocessing system @@ -222,9 +224,10 @@ void rlglSetDefaultShader(void); // Set default shader to be used Model rlglLoadModel(VertexData mesh); // Upload vertex data into GPU and provided VAO/VBO ids void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires); -Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates +Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates -byte *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer) +unsigned char *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer) +void *rlglReadTexturePixels(unsigned int textureId, unsigned int format); // Read texture pixel data #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) void PrintProjectionMatrix(void); // DEBUG: Print projection matrix diff --git a/src/text.c b/src/text.c index 1647070c7..dbbb962f4 100644 --- a/src/text.c +++ b/src/text.c @@ -171,11 +171,12 @@ extern void LoadDefaultFont(void) //fwrite(image.pixels, 1, 128*128*4, myimage); //fclose(myimage); - Image image = LoadImageFromData(imagePixels, imWidth, imHeight, UNCOMPRESSED_GRAY_ALPHA); + Image image = LoadImageEx(imagePixels, imWidth, imHeight); + ImageConvertFormat(&image, UNCOMPRESSED_GRAY_ALPHA); free(imagePixels); - defaultFont.texture = LoadTextureFromImage(image, false); // Convert loaded image to OpenGL texture + defaultFont.texture = LoadTextureFromImage(image); UnloadImage(image); // Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars @@ -240,7 +241,7 @@ SpriteFont LoadSpriteFont(const char *fileName) Color *imagePixels = GetPixelData(image); #if defined(PLATFORM_RPI) || defined(PLATFORM_WEB) - ConvertToPOT(&image, MAGENTA); + ImageConvertToPOT(&image, MAGENTA); #endif // Process bitmap Font pixel data to get measures (Character array) // spriteFont.charSet data is filled inside the function and memory is allocated! @@ -251,7 +252,7 @@ SpriteFont LoadSpriteFont(const char *fileName) spriteFont.numChars = numChars; - spriteFont.texture = LoadTextureFromImage(image, false); // Convert loaded image to OpenGL texture + spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture free(imagePixels); UnloadImage(image); @@ -556,13 +557,14 @@ static SpriteFont LoadRBMF(const char *fileName) counter++; } - Image image = LoadImageFromData(imagePixels, rbmfHeader.imgWidth, rbmfHeader.imgHeight, UNCOMPRESSED_GRAY_ALPHA); + Image image = LoadImageEx(imagePixels, rbmfHeader.imgWidth, rbmfHeader.imgHeight); + ImageConvertFormat(&image, UNCOMPRESSED_GRAY_ALPHA); free(imagePixels); TraceLog(INFO, "[%s] Image reconstructed correctly, now converting it to texture", fileName); - spriteFont.texture = LoadTextureFromImage(image, false); + spriteFont.texture = LoadTextureFromImage(image); UnloadImage(image); // Unload image data //TraceLog(INFO, "[%s] Starting charSet reconstruction", fileName); @@ -689,7 +691,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize) */ font.numChars = 95; font.charSet = (Character *)malloc(font.numChars*sizeof(Character)); - font.texture = LoadTextureFromImage(image, false); + font.texture = LoadTextureFromImage(image); //stbtt_aligned_quad letter; //int x = 0, y = 0; diff --git a/src/textures.c b/src/textures.c index e6c6cccb5..42c7810b1 100644 --- a/src/textures.c +++ b/src/textures.c @@ -123,6 +123,32 @@ Image LoadImage(const char *fileName) return image; } +// Load image data from Color array data (RGBA - 32bit) +Image LoadImageEx(Color *pixels, int width, int height) +{ + Image image; + image.data = NULL; + image.width = width; + image.height = height; + image.mipmaps = 1; + image.format = UNCOMPRESSED_R8G8B8A8; + + int k = 0; + + image.data = (unsigned char *)malloc(image.width*image.height*4*sizeof(unsigned char)); + + for (int i = 0; i < image.width*image.height*4; i += 4) + { + ((unsigned char *)image.data)[i] = pixels[k].r; + ((unsigned char *)image.data)[i + 1] = pixels[k].g; + ((unsigned char *)image.data)[i + 2] = pixels[k].b; + ((unsigned char *)image.data)[i + 3] = pixels[k].a; + k++; + } + + return image; +} + // Load an image from rRES file (raylib Resource) // TODO: Review function to support multiple color modes Image LoadImageFromRES(const char *rresName, int resId) @@ -243,12 +269,12 @@ Texture2D LoadTexture(const char *fileName) Image image = LoadImage(fileName); #if defined(PLATFORM_RPI) || defined(PLATFORM_WEB) - ConvertToPOT(&image, BLANK); + ImageConvertToPOT(&image, BLANK); #endif if (image.data != NULL) { - texture = LoadTextureFromImage(image, false); + texture = LoadTextureFromImage(image); UnloadImage(image); } else @@ -261,7 +287,7 @@ Texture2D LoadTexture(const char *fileName) return texture; } -Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps) +Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount) { Texture2D texture; @@ -270,14 +296,14 @@ Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, in texture.mipmaps = mipmapCount; texture.format = textureFormat; - texture.id = rlglLoadTexture(data, width, height, textureFormat, mipmapCount, genMipmaps); + texture.id = rlglLoadTexture(data, width, height, textureFormat, mipmapCount); return texture; } // Load a texture from image data // NOTE: image is not unloaded, it must be done manually -Texture2D LoadTextureFromImage(Image image, bool genMipmaps) +Texture2D LoadTextureFromImage(Image image) { Texture2D texture; @@ -288,7 +314,7 @@ Texture2D LoadTextureFromImage(Image image, bool genMipmaps) texture.mipmaps = 0; texture.format = 0; - texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps, false); + texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps); texture.width = image.width; texture.height = image.height; @@ -304,7 +330,7 @@ Texture2D LoadTextureFromRES(const char *rresName, int resId) Texture2D texture; Image image = LoadImageFromRES(rresName, resId); - texture = LoadTextureFromImage(image, false); + texture = LoadTextureFromImage(image); UnloadImage(image); return texture; @@ -324,7 +350,7 @@ void UnloadTexture(Texture2D texture) // Convert image to POT (power-of-two) // NOTE: Requirement on OpenGL ES 2.0 (RPI, HTML5) -void ConvertToPOT(Image *image, Color fillColor) +void ImageConvertToPOT(Image *image, Color fillColor) { // TODO: Review for new image struct /* @@ -447,144 +473,174 @@ Color *GetPixelData(Image image) return pixels; } -// Fill image data with pixels Color data (RGBA - 32bit) -// NOTE: Data is transformed to desired format -Image LoadImageFromData(Color *pixels, int width, int height, int format) +// Get pixel data from GPU texture and return an Image +Image GetTextureData(Texture2D texture) { Image image; - image.data = NULL; - image.width = width; - image.height = height; - image.mipmaps = 1; - image.format = format; - - int k = 0; - switch (format) + image.data = rlglReadTexturePixels(texture.id, texture.format); + + if (image.data != NULL) { - case UNCOMPRESSED_GRAYSCALE: - { - image.data = (unsigned char *)malloc(image.width*image.height*sizeof(unsigned char)); - - for (int i = 0; i < image.width*image.height; i++) - { - ((unsigned char *)image.data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f); - k++; - } - - } break; - case UNCOMPRESSED_GRAY_ALPHA: - { - image.data = (unsigned char *)malloc(image.width*image.height*2*sizeof(unsigned char)); - - for (int i = 0; i < image.width*image.height*2; i += 2) - { - ((unsigned char *)image.data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f); - ((unsigned char *)image.data)[i + 1] = pixels[k].a; - k++; - } - - } break; - case UNCOMPRESSED_R5G6B5: - { - image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short)); - - unsigned char r; - unsigned char g; - unsigned char b; - - for (int i = 0; i < image.width*image.height; i++) - { - r = (unsigned char)(round((float)pixels[k].r*31/255)); - g = (unsigned char)(round((float)pixels[k].g*63/255)); - b = (unsigned char)(round((float)pixels[k].b*31/255)); - - ((unsigned short *)image.data)[i] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b; - - k++; - } - - } break; - case UNCOMPRESSED_R8G8B8: - { - image.data = (unsigned char *)malloc(image.width*image.height*3*sizeof(unsigned char)); - - for (int i = 0; i < image.width*image.height*3; i += 3) - { - ((unsigned char *)image.data)[i] = pixels[k].r; - ((unsigned char *)image.data)[i + 1] = pixels[k].g; - ((unsigned char *)image.data)[i + 2] = pixels[k].b; - k++; - } - } break; - case UNCOMPRESSED_R5G5B5A1: - { - image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short)); - - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a = 1; - - for (int i = 0; i < image.width*image.height; i++) - { - r = (unsigned char)(round((float)pixels[k].r*31/255)); - g = (unsigned char)(round((float)pixels[k].g*31/255)); - b = (unsigned char)(round((float)pixels[k].b*31/255)); - a = (pixels[k].a > 50) ? 1 : 0; - - ((unsigned short *)image.data)[i] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1| (unsigned short)a; - - k++; - } - - } break; - case UNCOMPRESSED_R4G4B4A4: - { - image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short)); - - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a; - - for (int i = 0; i < image.width*image.height; i++) - { - r = (unsigned char)(round((float)pixels[k].r*15/255)); - g = (unsigned char)(round((float)pixels[k].g*15/255)); - b = (unsigned char)(round((float)pixels[k].b*15/255)); - a = (unsigned char)(round((float)pixels[k].a*15/255)); - - ((unsigned short *)image.data)[i] = (unsigned short)r << 12 | (unsigned short)g << 8| (unsigned short)b << 4| (unsigned short)a; - - k++; - } - - } break; - case UNCOMPRESSED_R8G8B8A8: - { - image.data = (unsigned char *)malloc(image.width*image.height*4*sizeof(unsigned char)); - - for (int i = 0; i < image.width*image.height*4; i += 4) - { - ((unsigned char *)image.data)[i] = pixels[k].r; - ((unsigned char *)image.data)[i + 1] = pixels[k].g; - ((unsigned char *)image.data)[i + 2] = pixels[k].b; - ((unsigned char *)image.data)[i + 3] = pixels[k].a; - k++; - } - } break; - default: - { - TraceLog(WARNING, "Format not recognized, image could not be loaded"); - - return image; - } break; + image.width = texture.width; + image.height = texture.height; + image.format = texture.format; + image.mipmaps = 1; } - + else TraceLog(WARNING, "Texture pixel data could not be obtained"); + return image; } +// Convert image data to desired format +void ImageConvertFormat(Image *image, int newFormat) +{ + if ((image->format != newFormat) && (image->format < 8) && (newFormat < 8)) + { + Color *pixels = GetPixelData(*image); + + free(image->data); + + image->format = newFormat; + + int k = 0; + + switch (image->format) + { + case UNCOMPRESSED_GRAYSCALE: + { + image->data = (unsigned char *)malloc(image->width*image->height*sizeof(unsigned char)); + + for (int i = 0; i < image->width*image->height; i++) + { + ((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f); + k++; + } + + } break; + case UNCOMPRESSED_GRAY_ALPHA: + { + image->data = (unsigned char *)malloc(image->width*image->height*2*sizeof(unsigned char)); + + for (int i = 0; i < image->width*image->height*2; i += 2) + { + ((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f); + ((unsigned char *)image->data)[i + 1] = pixels[k].a; + k++; + } + + } break; + case UNCOMPRESSED_R5G6B5: + { + image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short)); + + unsigned char r; + unsigned char g; + unsigned char b; + + for (int i = 0; i < image->width*image->height; i++) + { + r = (unsigned char)(round((float)pixels[k].r*31/255)); + g = (unsigned char)(round((float)pixels[k].g*63/255)); + b = (unsigned char)(round((float)pixels[k].b*31/255)); + + ((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b; + + k++; + } + + } break; + case UNCOMPRESSED_R8G8B8: + { + image->data = (unsigned char *)malloc(image->width*image->height*3*sizeof(unsigned char)); + + for (int i = 0; i < image->width*image->height*3; i += 3) + { + ((unsigned char *)image->data)[i] = pixels[k].r; + ((unsigned char *)image->data)[i + 1] = pixels[k].g; + ((unsigned char *)image->data)[i + 2] = pixels[k].b; + k++; + } + } break; + case UNCOMPRESSED_R5G5B5A1: + { + image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short)); + + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a = 1; + + for (int i = 0; i < image->width*image->height; i++) + { + r = (unsigned char)(round((float)pixels[k].r*31/255)); + g = (unsigned char)(round((float)pixels[k].g*31/255)); + b = (unsigned char)(round((float)pixels[k].b*31/255)); + a = (pixels[k].a > 50) ? 1 : 0; + + ((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1| (unsigned short)a; + + k++; + } + + } break; + case UNCOMPRESSED_R4G4B4A4: + { + image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short)); + + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; + + for (int i = 0; i < image->width*image->height; i++) + { + r = (unsigned char)(round((float)pixels[k].r*15/255)); + g = (unsigned char)(round((float)pixels[k].g*15/255)); + b = (unsigned char)(round((float)pixels[k].b*15/255)); + a = (unsigned char)(round((float)pixels[k].a*15/255)); + + ((unsigned short *)image->data)[i] = (unsigned short)r << 12 | (unsigned short)g << 8| (unsigned short)b << 4| (unsigned short)a; + + k++; + } + + } break; + case UNCOMPRESSED_R8G8B8A8: + { + image->data = (unsigned char *)malloc(image->width*image->height*4*sizeof(unsigned char)); + + for (int i = 0; i < image->width*image->height*4; i += 4) + { + ((unsigned char *)image->data)[i] = pixels[k].r; + ((unsigned char *)image->data)[i + 1] = pixels[k].g; + ((unsigned char *)image->data)[i + 2] = pixels[k].b; + ((unsigned char *)image->data)[i + 3] = pixels[k].a; + k++; + } + } break; + default: break; + } + + free(pixels); + } + else TraceLog(WARNING, "Image data format is compressed, can not be converted"); +} + +/* +Image ImageCopy(Image image); +void ImageCrop(Image *image, Rectangle crop); +void ImageResize(Image *image, int newWidth, int newHeight); +void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); +void ImageDrawText(Image *dst, const char *text, Vector2 position, int size, Color color); +*/ + +// Generate GPU mipmaps for a texture +void GenTextureMipmaps(Texture2D texture) +{ + rlglGenerateMipmaps(texture.id); +} + // Draw a Texture2D void DrawTexture(Texture2D texture, int posX, int posY, Color tint) { @@ -1224,6 +1280,8 @@ static Image LoadASTC(const char *fileName) // NOTE: Assuming Little Endian (could it be wrong?) image.width = 0x00000000 | ((int)header.width[2] << 16) | ((int)header.width[1] << 8) | ((int)header.width[0]); image.height = 0x00000000 | ((int)header.height[2] << 16) | ((int)header.height[1] << 8) | ((int)header.height[0]); + + // NOTE: ASTC format only contains one mipmap level image.mipmaps = 1; TraceLog(DEBUG, "ASTC image width: %i", image.width); @@ -1250,5 +1308,49 @@ static Image LoadASTC(const char *fileName) fclose(astcFile); } + return image; +} + +// Load RAW image file +static Image LoadRAW(const char *fileName, int width, int height, int format, int headerSize) +{ + Image image; + + image.data = NULL; + image.width = 0; + image.height = 0; + image.mipmaps = 0; + image.format = 0; + + FILE *rawFile = fopen(fileName, "rb"); + + if (rawFile == NULL) + { + TraceLog(WARNING, "[%s] RAW image file could not be opened", fileName); + } + else + { + if (headerSize > 0) fseek(rawFile, headerSize, SEEK_SET); + + int dataSize = 0; + + // TODO: Calculate data size and allocate memory + switch (format) + { + + } + + fread(image.data, dataSize, 1, rawFile); + + // TODO: Check if data have been read + + image.width = width; + image.height = height; + image.mipmaps = 0; + image.format = format; + + fclose(rawFile); + } + return image; } \ No newline at end of file From e30421e84cf5a331df0249e000a31043b5f27bd8 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 13 Jul 2015 18:14:47 +0200 Subject: [PATCH 04/12] Updated to latest version 2.06 --- src/stb_image.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/stb_image.h b/src/stb_image.h index 1249c3039..81d1ecf63 100644 --- a/src/stb_image.h +++ b/src/stb_image.h @@ -1,4 +1,4 @@ -/* stb_image - v2.05 - public domain image loader - http://nothings.org/stb_image.h +/* stb_image - v2.06 - public domain image loader - http://nothings.org/stb_image.h no warranty implied; use at your own risk Do this: @@ -143,6 +143,7 @@ Latest revision history: + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit 2.03 (2015-04-12) additional corruption checking @@ -5147,7 +5148,8 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int p = out+channel; if (channel >= channelCount) { // Fill this channel with default data. - for (i = 0; i < pixelCount; i++) *p = (channel == 3 ? 255 : 0), p += 4; + for (i = 0; i < pixelCount; i++, p += 4) + *p = (channel == 3 ? 255 : 0); } else { // Read the RLE data. count = 0; @@ -5193,11 +5195,12 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int p = out + channel; if (channel > channelCount) { // Fill this channel with default data. - for (i = 0; i < pixelCount; i++) *p = channel == 3 ? 255 : 0, p += 4; + for (i = 0; i < pixelCount; i++, p += 4) + *p = channel == 3 ? 255 : 0; } else { // Read the data. - for (i = 0; i < pixelCount; i++) - *p = stbi__get8(s), p += 4; + for (i = 0; i < pixelCount; i++, p += 4) + *p = stbi__get8(s); } } } @@ -5207,7 +5210,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int if (out == NULL) return out; // stbi__convert_format frees input on failure } - if (comp) *comp = channelCount; + if (comp) *comp = 4; *y = h; *x = w; @@ -6300,6 +6303,7 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int /* revision history: + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit 2.03 (2015-04-12) extra corruption checking (mmozeiko) From d50194940da6e9d048fe82ab2fbdedf8a269f99f Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 13 Jul 2015 18:15:31 +0200 Subject: [PATCH 05/12] Updated to raylib v1.3 --- src/resources | Bin 107204 -> 107204 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/resources b/src/resources index 2038c07a3f61871b1a5c97b6afd0a7614a8dbd5c..b41637ff9b954988ee201b08d9170af717483771 100644 GIT binary patch delta 310 zcmX?dlaFfwqmFfjBmLU`!nb8v{S!6Ci}hxi#( z@p_VLtm>QBF>YVS$e1*r(RjMx ULdIN1)9LjK8GC^|-bIYt0T?JYg8%>k delta 310 zcmX?dlPIXJ}E;1J(~L;MV? zcs Date: Mon, 13 Jul 2015 18:16:24 +0200 Subject: [PATCH 06/12] Some small code tweaks --- src/gestures.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/gestures.c b/src/gestures.c index 5b62cbff8..ad8ac9f61 100644 --- a/src/gestures.c +++ b/src/gestures.c @@ -132,10 +132,10 @@ static Vector2 touchPosition; //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -extern void ProcessMotionEvent(GestureEvent event); extern void ResetGestures(void); extern Vector2 GetRawPosition(void); +static void ProcessMotionEvent(GestureEvent event); static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, float magnitude); static float OnPinch(); static void SetDualInput(GestureEvent event); @@ -265,7 +265,7 @@ extern void InitAndroidGestures(struct android_app *app) //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- -extern void ProcessMotionEvent(GestureEvent event) +static void ProcessMotionEvent(GestureEvent event) { // Resets dragVector = (Vector2){ 0, 0 }; @@ -359,7 +359,7 @@ extern void ProcessMotionEvent(GestureEvent event) { lastDragPosition = endDragPosition; - endDragPosition = GetRawPosition(); + endDragPosition = touchPosition; //endDragPosition.x = AMotionEvent_getX(event, 0); //endDragPosition.y = AMotionEvent_getY(event, 0); @@ -568,6 +568,18 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) { //int32_t key = AKeyEvent_getKeyCode(event); //int32_t AKeyEvent_getMetaState(event); + + int32_t code = AKeyEvent_getKeyCode((const AInputEvent *)event); + + // If we are in active mode, we eat the back button and move into pause mode. + // If we are already in pause mode, we allow the back button to be handled by the OS, which means we'll be shut down. + /* + if ((code == AKEYCODE_BACK) && mActiveMode) + { + setActiveMode(false); + return 1; + } + */ } int32_t action = AMotionEvent_getAction(event); @@ -589,7 +601,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) ProcessMotionEvent(gestureEvent); - return 0; + return 0; // return 1; } #endif From 3434255ce6ef1ca0df1dc5ffd4e875cb4697e8f8 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 13 Jul 2015 18:17:05 +0200 Subject: [PATCH 07/12] Decoupling camera system from raylib main library --- src/camera.c | 3 ++- src/camera.h | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/camera.h diff --git a/src/camera.c b/src/camera.c index 1aa39ca81..cde118c9d 100644 --- a/src/camera.c +++ b/src/camera.c @@ -23,7 +23,8 @@ * **********************************************************************************************/ -#include "raylib.h" +#include "camera.h" + #include //---------------------------------------------------------------------------------- diff --git a/src/camera.h b/src/camera.h new file mode 100644 index 000000000..cb5f2bdef --- /dev/null +++ b/src/camera.h @@ -0,0 +1,69 @@ +/******************************************************************************************* +* +* raylib Camera System - Camera Modes Setup and Control Functions +* +* Copyright (c) 2015 Marc Palau and Ramon Santamaria +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef CAMERA_H +#define CAMERA_H + +#include "raylib.h" + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// Camera modes +typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; + + +#ifdef __cplusplus +extern "C" { // Prevents name mangling of functions +#endif + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +//... + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- +void SetCameraMode(int mode); // Select camera mode (multiple camera modes available) +Camera UpdateCamera(Vector3 *position); // Update camera with position + +void SetCameraControls(int front, int left, int back, int right, int up, int down); +void SetCameraMouseSensitivity(float sensitivity); +void SetCameraResetPosition(Vector3 resetPosition); +void SetCameraResetControl(int resetKey); +void SetCameraPawnControl(int pawnControlKey); +void SetCameraFnControl(int fnControlKey); +void SetCameraSmoothZoomControl(int smoothZoomControlKey); +void SetCameraOrbitalTarget(Vector3 target); + +#ifdef __cplusplus +} +#endif + +#endif // CAMERA_H From 66556b8b479e998dc022fa9c884eb39fae1479f7 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 13 Jul 2015 18:19:29 +0200 Subject: [PATCH 08/12] Added some functions and renamed some others Added: - LoadImageRaw() - ImageCopy() Renamed: - GetPixelData() -> GetImageData() --- src/models.c | 76 ++++----------- src/text.c | 2 +- src/textures.c | 244 ++++++++++++++++++++++++++++--------------------- 3 files changed, 161 insertions(+), 161 deletions(-) diff --git a/src/models.c b/src/models.c index 8d772f023..c45e18c80 100644 --- a/src/models.c +++ b/src/models.c @@ -600,7 +600,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight) int mapX = heightmap.width; int mapZ = heightmap.height; - Color *heightmapPixels = GetPixelData(heightmap); + Color *heightmapPixels = GetImageData(heightmap); // NOTE: One vertex per pixel // TODO: Consider resolution when generating model data? @@ -721,7 +721,7 @@ Model LoadCubicmap(Image cubicmap) { VertexData vData; - Color *cubicmapPixels = GetPixelData(cubicmap); + Color *cubicmapPixels = GetImageData(cubicmap); // Map cube size will be 1.0 float mapCubeSide = 1.0f; @@ -1105,8 +1105,6 @@ void UnloadModel(Model model) rlDeleteBuffers(model.mesh.vboId[2]); rlDeleteVertexArrays(model.mesh.vaoId); - //rlDeleteTextures(model.texture.id); - //rlDeleteShader(model.shader.id); } // Link a texture to a model @@ -1114,8 +1112,9 @@ void SetModelTexture(Model *model, Texture2D texture) { if (texture.id <= 0) { - model->texture.id = whiteTexture; // Default white texture (use mesh color) - model->shader.texDiffuseId = whiteTexture; + // Use default white texture (use mesh color) + model->texture.id = whiteTexture; // OpenGL 1.1 + model->shader.texDiffuseId = whiteTexture; // OpenGL 3.3 / ES 2.0 } else { @@ -1124,26 +1123,6 @@ void SetModelTexture(Model *model, Texture2D texture) } } -// Load a custom shader (vertex shader + fragment shader) -Shader LoadShader(char *vsFileName, char *fsFileName) -{ - Shader shader = rlglLoadShader(vsFileName, fsFileName); - - return shader; -} - -// Unload a custom shader from memory -void UnloadShader(Shader shader) -{ - rlDeleteShader(shader.id); -} - -// Set shader for a model -void SetModelShader(Model *model, Shader shader) -{ - rlglSetModelShader(model, shader); -} - // Draw a model (with texture if set) void DrawModel(Model model, Vector3 position, float scale, Color tint) { @@ -1269,7 +1248,7 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec rlDisableTexture(); } - +// Detect collision between two spheres bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB) { bool collision = false; @@ -1285,22 +1264,10 @@ bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, floa return collision; } +// Detect collision between two boxes +// NOTE: Boxes are defined by two points minimum and maximum bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2) { - /* - // Get min and max vertex to construct bounds (AABB) - Vector3 minVertex = tempVertices[0]; - Vector3 maxVertex = tempVertices[0]; - - for (int i = 1; i < tempVertices.Count; i++) - { - minVertex = Vector3.Min(minVertex, tempVertices[i]); - maxVertex = Vector3.Max(maxVertex, tempVertices[i]); - } - - bounds = new BoundingBox(minVertex, maxVertex); - */ - bool collision = true; if ((maxBBox1.x >= minBBox2.x) && (minBBox1.x <= maxBBox2.x)) @@ -1313,6 +1280,7 @@ bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, V return collision; } +// Detect collision between box and sphere bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere) { bool collision = false; @@ -1326,35 +1294,29 @@ bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSph { float dmin = 0; - if (centerSphere.x - minBBox.x <= radiusSphere) - dmin += (centerSphere.x - minBBox.x) * (centerSphere.x - minBBox.x); - else if (maxBBox.x - centerSphere.x <= radiusSphere) - dmin += (centerSphere.x - maxBBox.x) * (centerSphere.x - maxBBox.x); + if (centerSphere.x - minBBox.x <= radiusSphere) dmin += (centerSphere.x - minBBox.x)*(centerSphere.x - minBBox.x); + else if (maxBBox.x - centerSphere.x <= radiusSphere) dmin += (centerSphere.x - maxBBox.x)*(centerSphere.x - maxBBox.x); - if (centerSphere.y - minBBox.y <= radiusSphere) - dmin += (centerSphere.y - minBBox.y) * (centerSphere.y - minBBox.y); - else if (maxBBox.y - centerSphere.y <= radiusSphere) - dmin += (centerSphere.y - maxBBox.y) * (centerSphere.y - maxBBox.y); + if (centerSphere.y - minBBox.y <= radiusSphere) dmin += (centerSphere.y - minBBox.y)*(centerSphere.y - minBBox.y); + else if (maxBBox.y - centerSphere.y <= radiusSphere) dmin += (centerSphere.y - maxBBox.y)*(centerSphere.y - maxBBox.y); - if (centerSphere.z - minBBox.z <= radiusSphere) - dmin += (centerSphere.z - minBBox.z) * (centerSphere.z - minBBox.z); - else if (maxBBox.z - centerSphere.z <= radiusSphere) - dmin += (centerSphere.z - maxBBox.z) * (centerSphere.z - maxBBox.z); + if (centerSphere.z - minBBox.z <= radiusSphere) dmin += (centerSphere.z - minBBox.z)*(centerSphere.z - minBBox.z); + else if (maxBBox.z - centerSphere.z <= radiusSphere) dmin += (centerSphere.z - maxBBox.z)*(centerSphere.z - maxBBox.z); - if (dmin <= radiusSphere * radiusSphere) collision = true; + if (dmin <= radiusSphere*radiusSphere) collision = true; } return collision; } -// TODO +// TODO: Useful function to check collision area? //BoundingBox GetCollisionArea(BoundingBox box1, BoundingBox box2) // Detect and resolve cubicmap collisions // NOTE: player position (or camera) is modified inside this function Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius) { - Color *cubicmapPixels = GetPixelData(cubicmap); + Color *cubicmapPixels = GetImageData(cubicmap); // Detect the cell where the player is located Vector3 impactDirection = { 0, 0, 0 }; @@ -1697,7 +1659,7 @@ static VertexData LoadOBJ(const char *fileName) // Second reading pass: Get vertex data to fill intermediate arrays // NOTE: This second pass is required in case of multiple meshes defined in same OBJ - // TODO: Consider that diferent meshes can have different vertex data available (position, texcoords, normals) + // TODO: Consider that different meshes can have different vertex data available (position, texcoords, normals) while(!feof(objFile)) { fscanf(objFile, "%c", &dataType); diff --git a/src/text.c b/src/text.c index dbbb962f4..feed211ee 100644 --- a/src/text.c +++ b/src/text.c @@ -238,7 +238,7 @@ SpriteFont LoadSpriteFont(const char *fileName) // At this point we have a data array... - Color *imagePixels = GetPixelData(image); + Color *imagePixels = GetImageData(image); #if defined(PLATFORM_RPI) || defined(PLATFORM_WEB) ImageConvertToPOT(&image, MAGENTA); diff --git a/src/textures.c b/src/textures.c index 42c7810b1..b7ab1f7e7 100644 --- a/src/textures.c +++ b/src/textures.c @@ -149,6 +149,56 @@ Image LoadImageEx(Color *pixels, int width, int height) return image; } +// Load an image from RAW file +Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize) +{ + Image image; + + image.data = NULL; + image.width = 0; + image.height = 0; + image.mipmaps = 0; + image.format = 0; + + FILE *rawFile = fopen(fileName, "rb"); + + if (rawFile == NULL) + { + TraceLog(WARNING, "[%s] RAW image file could not be opened", fileName); + } + else + { + if (headerSize > 0) fseek(rawFile, headerSize, SEEK_SET); + + unsigned int size = width*height; + + switch (format) + { + case UNCOMPRESSED_GRAYSCALE: image.data = (unsigned char *)malloc(size); break; // 8 bit per pixel (no alpha) + case UNCOMPRESSED_GRAY_ALPHA: image.data = (unsigned char *)malloc(size*2); size *= 2; break; // 16 bpp (2 channels) + case UNCOMPRESSED_R5G6B5: image.data = (unsigned short *)malloc(size); break; // 16 bpp + case UNCOMPRESSED_R8G8B8: image.data = (unsigned char *)malloc(size*3); size *= 3; break; // 24 bpp + case UNCOMPRESSED_R5G5B5A1: image.data = (unsigned short *)malloc(size); break; // 16 bpp (1 bit alpha) + case UNCOMPRESSED_R4G4B4A4: image.data = (unsigned short *)malloc(size); break; // 16 bpp (4 bit alpha) + case UNCOMPRESSED_R8G8B8A8: image.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp + default: TraceLog(WARNING, "Image format not suported"); break; + } + + fread(image.data, size, 1, rawFile); + + // TODO: Check if data have been read + + image.width = width; + image.height = height; + image.mipmaps = 0; + image.format = format; + + fclose(rawFile); + } + + return image; +} + // Load an image from rRES file (raylib Resource) // TODO: Review function to support multiple color modes Image LoadImageFromRES(const char *rresName, int resId) @@ -301,6 +351,18 @@ Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, in return texture; } +// Load an image as texture from rRES file (raylib Resource) +Texture2D LoadTextureFromRES(const char *rresName, int resId) +{ + Texture2D texture; + + Image image = LoadImageFromRES(rresName, resId); + texture = LoadTextureFromImage(image); + UnloadImage(image); + + return texture; +} + // Load a texture from image data // NOTE: image is not unloaded, it must be done manually Texture2D LoadTextureFromImage(Image image) @@ -324,18 +386,6 @@ Texture2D LoadTextureFromImage(Image image) return texture; } -// Load an image as texture from rRES file (raylib Resource) -Texture2D LoadTextureFromRES(const char *rresName, int resId) -{ - Texture2D texture; - - Image image = LoadImageFromRES(rresName, resId); - texture = LoadTextureFromImage(image); - UnloadImage(image); - - return texture; -} - // Unload image from CPU memory (RAM) void UnloadImage(Image image) { @@ -348,46 +398,8 @@ void UnloadTexture(Texture2D texture) rlDeleteTextures(texture.id); } -// Convert image to POT (power-of-two) -// NOTE: Requirement on OpenGL ES 2.0 (RPI, HTML5) -void ImageConvertToPOT(Image *image, Color fillColor) -{ - // TODO: Review for new image struct - /* - // Just add the required amount of pixels at the right and bottom sides of image... - int potWidth = GetNextPOT(image->width); - int potHeight = GetNextPOT(image->height); - - // Check if POT texture generation is required (if texture is not already POT) - if ((potWidth != image->width) || (potHeight != image->height)) - { - Color *imgDataPixelPOT = NULL; - - // Generate POT array from NPOT data - imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color)); - - for (int j = 0; j < potHeight; j++) - { - for (int i = 0; i < potWidth; i++) - { - if ((j < image->height) && (i < image->width)) imgDataPixelPOT[j*potWidth + i] = image->data[j*image->width + i]; - else imgDataPixelPOT[j*potWidth + i] = fillColor; - } - } - - TraceLog(WARNING, "Image converted to POT: (%ix%i) -> (%ix%i)", image->width, image->height, potWidth, potHeight); - - free(image->pixels); - - image->pixels = imgDataPixelPOT; - image->width = potWidth; - image->height = potHeight; - } - */ -} - // Get pixel data from image in the form of Color struct array -Color *GetPixelData(Image image) +Color *GetImageData(Image image) { Color *pixels = (Color *)malloc(image.width*image.height*sizeof(Color)); @@ -497,7 +509,7 @@ void ImageConvertFormat(Image *image, int newFormat) { if ((image->format != newFormat) && (image->format < 8) && (newFormat < 8)) { - Color *pixels = GetPixelData(*image); + Color *pixels = GetImageData(*image); free(image->data); @@ -627,13 +639,83 @@ void ImageConvertFormat(Image *image, int newFormat) else TraceLog(WARNING, "Image data format is compressed, can not be converted"); } -/* -Image ImageCopy(Image image); -void ImageCrop(Image *image, Rectangle crop); -void ImageResize(Image *image, int newWidth, int newHeight); -void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); -void ImageDrawText(Image *dst, const char *text, Vector2 position, int size, Color color); -*/ + +// Convert image to POT (power-of-two) +// NOTE: Requirement on OpenGL ES 2.0 (RPI, HTML5) +void ImageConvertToPOT(Image *image, Color fillColor) +{ + // TODO: Review for new image struct + /* + // Just add the required amount of pixels at the right and bottom sides of image... + int potWidth = GetNextPOT(image->width); + int potHeight = GetNextPOT(image->height); + + // Check if POT texture generation is required (if texture is not already POT) + if ((potWidth != image->width) || (potHeight != image->height)) + { + Color *imgDataPixelPOT = NULL; + + // Generate POT array from NPOT data + imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color)); + + for (int j = 0; j < potHeight; j++) + { + for (int i = 0; i < potWidth; i++) + { + if ((j < image->height) && (i < image->width)) imgDataPixelPOT[j*potWidth + i] = image->data[j*image->width + i]; + else imgDataPixelPOT[j*potWidth + i] = fillColor; + } + } + + TraceLog(WARNING, "Image converted to POT: (%ix%i) -> (%ix%i)", image->width, image->height, potWidth, potHeight); + + free(image->pixels); + + image->pixels = imgDataPixelPOT; + image->width = potWidth; + image->height = potHeight; + } + */ +} + +// Copy an image to a new image +Image ImageCopy(Image image) +{ + Image newImage; + + int size = image.width*image.height; + + switch (image.format) + { + case UNCOMPRESSED_GRAYSCALE: newImage.data = (unsigned char *)malloc(size); break; // 8 bit per pixel (no alpha) + case UNCOMPRESSED_GRAY_ALPHA: newImage.data = (unsigned char *)malloc(size*2); size *= 2; break; // 16 bpp (2 channels) + case UNCOMPRESSED_R5G6B5: newImage.data = (unsigned short *)malloc(size); size *= 2; break; // 16 bpp + case UNCOMPRESSED_R8G8B8: newImage.data = (unsigned char *)malloc(size*3); size *= 3; break; // 24 bpp + case UNCOMPRESSED_R5G5B5A1: newImage.data = (unsigned short *)malloc(size); size *= 2; break; // 16 bpp (1 bit alpha) + case UNCOMPRESSED_R4G4B4A4: newImage.data = (unsigned short *)malloc(size); size *= 2; break; // 16 bpp (4 bit alpha) + case UNCOMPRESSED_R8G8B8A8: newImage.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp + default: TraceLog(WARNING, "Image format not suported for copy"); break; + } + + if (newImage.data != NULL) + { + // NOTE: Size must be provided in bytes + memcpy(newImage.data, image.data, size); + + newImage.width = image.width; + newImage.height = image.height; + newImage.mipmaps = image.mipmaps; + newImage.format = image.format; + } + + return newImage; +} + +// TODO: Some useful functions to deal with images +//void ImageCrop(Image *image, Rectangle crop) {} +//void ImageResize(Image *image, int newWidth, int newHeight) {} +//void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec) {} +//void ImageDrawText(Image *dst, const char *text, Vector2 position, int size, Color color) {} // Generate GPU mipmaps for a texture void GenTextureMipmaps(Texture2D texture) @@ -1310,47 +1392,3 @@ static Image LoadASTC(const char *fileName) return image; } - -// Load RAW image file -static Image LoadRAW(const char *fileName, int width, int height, int format, int headerSize) -{ - Image image; - - image.data = NULL; - image.width = 0; - image.height = 0; - image.mipmaps = 0; - image.format = 0; - - FILE *rawFile = fopen(fileName, "rb"); - - if (rawFile == NULL) - { - TraceLog(WARNING, "[%s] RAW image file could not be opened", fileName); - } - else - { - if (headerSize > 0) fseek(rawFile, headerSize, SEEK_SET); - - int dataSize = 0; - - // TODO: Calculate data size and allocate memory - switch (format) - { - - } - - fread(image.data, dataSize, 1, rawFile); - - // TODO: Check if data have been read - - image.width = width; - image.height = height; - image.mipmaps = 0; - image.format = format; - - fclose(rawFile); - } - - return image; -} \ No newline at end of file From 552033da27ddeac2c8e9dd6b8ad33b7058963ef6 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 13 Jul 2015 18:20:16 +0200 Subject: [PATCH 09/12] Move shaders functions to module rlgl Shader functionality owns to rlgl, not core module --- src/core.c | 44 +---- src/raylib.h | 78 ++++----- src/rlgl.c | 457 +++++++++++++++++++++++++++++++-------------------- src/rlgl.h | 9 +- 4 files changed, 323 insertions(+), 265 deletions(-) diff --git a/src/core.c b/src/core.c index 301d9e6e0..1cdcd679c 100644 --- a/src/core.c +++ b/src/core.c @@ -192,9 +192,6 @@ static double targetTime = 0.0; // Desired time for one frame, if 0 static char configFlags = 0; static bool showLogo = false; -// Shaders variables -static bool enabledPostpro = false; - //---------------------------------------------------------------------------------- // Other Modules Functions Declaration (required by core) //---------------------------------------------------------------------------------- @@ -468,7 +465,7 @@ int GetScreenHeight(void) // Sets Background Color void ClearBackground(Color color) { - // TODO: Review "clearing area", full framebuffer vs render area + // Clear full framebuffer (not only render area) to color rlClearColor(color.r, color.g, color.b, color.a); } @@ -479,7 +476,7 @@ void BeginDrawing(void) updateTime = currentTime - previousTime; previousTime = currentTime; - if (enabledPostpro) rlEnableFBO(); + if (IsPosproShaderEnabled()) rlEnableFBO(); rlClearScreenBuffers(); @@ -496,7 +493,7 @@ void EndDrawing(void) { rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) - if (enabledPostpro) rlglDrawPostpro(); // Draw postprocessing effect (shader) + if (IsPosproShaderEnabled()) rlglDrawPostpro(); // Draw postprocessing effect (shader) SwapBuffers(); // Copy back buffer to front buffer @@ -970,39 +967,6 @@ Vector2 GetTouchPosition(void) } #endif -// Set postprocessing shader -void SetPostproShader(Shader shader) -{ - if (rlGetVersion() == OPENGL_11) TraceLog(WARNING, "Postprocessing shaders not supported on OpenGL 1.1"); - else - { - if (!enabledPostpro) - { - enabledPostpro = true; - rlglInitPostpro(); - rlglSetPostproShader(shader); - } - else - { - rlglSetPostproShader(shader); - } - } -} - -// Set custom shader to be used in batch draw -void SetCustomShader(Shader shader) -{ - rlglSetCustomShader(shader); -} - -// Set default shader to be used in batch draw -void SetDefaultShader(void) -{ - rlglSetDefaultShader(); - - enabledPostpro = false; -} - //---------------------------------------------------------------------------------- // Module specific Functions Definition //---------------------------------------------------------------------------------- @@ -1579,7 +1543,7 @@ static void PollInputEvents(void) // Poll Events (registered events) // TODO: Enable/disable activityMinimized to block activity if minimized //while ((ident = ALooper_pollAll(activityMinimized ? 0 : -1, NULL, &events,(void**)&source)) >= 0) - while ((ident = ALooper_pollAll(0, NULL, &events,(void**)&source)) >= 0) + while ((ident = ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0) { // Process this event if (source != NULL) source->process(app, source); diff --git a/src/raylib.h b/src/raylib.h index e03fc9b21..228d3e581 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -265,9 +265,6 @@ typedef struct Camera { Vector3 up; } Camera; -// Camera modes -typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; - // Vertex data definning a mesh // NOTE: If using OpenGL 1.1, data loaded in CPU; if OpenGL 3.3+ data loaded in GPU (vaoId) typedef struct VertexData { @@ -284,21 +281,21 @@ typedef struct VertexData { typedef struct Shader { unsigned int id; // Shader program id + // TODO: This should be Texture2D objects unsigned int texDiffuseId; // Diffuse texture id unsigned int texNormalId; // Normal texture id unsigned int texSpecularId; // Specular texture id // Variable attributes - int vertexLoc; // Vertex attribute location point (vertex shader) - int texcoordLoc; // Texcoord attribute location point (vertex shader) - int normalLoc; // Normal attribute location point (vertex shader) - int colorLoc; // Color attibute location point (vertex shader) + int vertexLoc; // Vertex attribute location point (vertex shader) + int texcoordLoc; // Texcoord attribute location point (vertex shader) + int normalLoc; // Normal attribute location point (vertex shader) + int colorLoc; // Color attibute location point (vertex shader) // Uniforms - int projectionLoc; // Projection matrix uniform location point (vertex shader) - int modelviewLoc; // ModeView matrix uniform location point (vertex shader) - - int tintColorLoc; // Color uniform location point (fragment shader) + int projectionLoc; // Projection matrix uniform location point (vertex shader) + int modelviewLoc; // ModeView matrix uniform location point (vertex shader) + int tintColorLoc; // Color uniform location point (fragment shader) int mapDiffuseLoc; // Diffuse map texture uniform location point (fragment shader) int mapNormalLoc; // Normal map texture uniform location point (fragment shader) @@ -421,32 +418,28 @@ Color Fade(Color color, float alpha); // Color fade-in or void SetConfigFlags(char flags); // Enable some window configurations void ShowLogo(void); // Activates raylib logo at startup (can be done with flags) -void SetPostproShader(Shader shader); // Set fullscreen postproduction shader -void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw -void SetDefaultShader(void); // Set default shader to be used in batch draw +Ray GetMouseRay(Vector2 mousePosition, Camera camera); // TODO: Gives the ray trace from mouse position -Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Gives the rayTrace from mouse position +//------------------------------------------------------------------------------------ +// Shaders System Functions (Module: rlgl) +// NOTE: This functions are useless when using OpenGL 1.1 +//------------------------------------------------------------------------------------ +Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations +unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr); // Load a custom shader and return program id +void UnloadShader(Shader shader); // Unload a custom shader from memory +void SetPostproShader(Shader shader); // Set fullscreen postproduction shader +void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw +void SetDefaultShader(void); // Set default shader to be used in batch draw +void SetModelShader(Model *model, Shader shader); // Link a shader to a model +bool IsPosproShaderEnabled(void); // Check if postprocessing shader is enabled -// Camera modes setup and control functions (module: camera) -void SetCameraMode(int mode); // Select camera mode (multiple camera modes available) -Camera UpdateCamera(Vector3 *position); // Update camera with position - -void SetCameraControls(int front, int left, int back, int right, int up, int down); -void SetCameraMouseSensitivity(float sensitivity); -void SetCameraResetPosition(Vector3 resetPosition); -void SetCameraResetControl(int resetKey); -void SetCameraPawnControl(int pawnControlKey); -void SetCameraFnControl(int fnControlKey); -void SetCameraSmoothZoomControl(int smoothZoomControlKey); -void SetCameraOrbitalTarget(Vector3 target); - -// Shaders control functions -int GetShaderLocation(Shader shader, const char *uniformName); -void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); - -void SetShaderMapDiffuse(Shader *shader, Texture2D texture); -void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture); -void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture); +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 //------------------------------------------------------------------------------------ // Input Handling Functions (Module: core) @@ -535,6 +528,7 @@ bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 //------------------------------------------------------------------------------------ Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit) +Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource) Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount); // Load a texture from raw data into GPU memory @@ -542,10 +536,10 @@ Texture2D LoadTextureFromRES(const char *rresName, int resId); Texture2D LoadTextureFromImage(Image image); // Load a texture from image data (and generate mipmaps) void UnloadImage(Image image); // Unload image from CPU memory (RAM) void UnloadTexture(Texture2D texture); // Unload texture from GPU memory +Color *GetImageData(Image image); // Get pixel data from image as a Color struct array +Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image void ImageConvertToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two) void ImageConvertFormat(Image *image, int newFormat); // Convert image data to desired format -Color *GetPixelData(Image image); // Get pixel data from image as a Color struct array -Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D @@ -600,7 +594,6 @@ Model LoadHeightmap(Image heightmap, float maxHeight); Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) void UnloadModel(Model model); // Unload 3d model from memory void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model -void SetModelShader(Model *model, Shader shader); // Link a shader to a model (not available on OpenGL 1.1) void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) void DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color tint); // Draw a model with extended parameters @@ -609,12 +602,9 @@ void DrawModelWires(Model model, Vector3 position, float scale, Color color); void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec -Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader (vertex shader + fragment shader) -void UnloadShader(Shader shader); // Unload a custom shader from memory - -bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); -bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2); -bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere); +bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres +bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2); // Detect collision between two boxes +bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Return the normal vector of the impacted surface //------------------------------------------------------------------------------------ diff --git a/src/rlgl.c b/src/rlgl.c index 4ff652b0a..b4bd71155 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -230,6 +230,9 @@ static bool texCompASTCSupported = false; // ASTC texture compression support // Framebuffer object and texture static GLuint fbo, fboColorTexture, fboDepthTexture; static Model postproQuad; + +// Shaders related variables +static bool enabledPostpro = false; #endif // Compressed textures support flags @@ -957,7 +960,7 @@ void rlglInit(void) // Init default Shader (GLSL 110) -> Common for GL 3.3+ and ES2 defaultShader = LoadDefaultShader(); simpleShader = LoadSimpleShader(); - //customShader = rlglLoadShader("custom.vs", "custom.fs"); // Works ok + //customShader = LoadShader("custom.vs", "custom.fs"); // Works ok currentShader = defaultShader; @@ -1054,25 +1057,6 @@ void rlglInitPostpro(void) #endif } -// Set postprocessing shader -void rlglSetPostproShader(Shader shader) -{ -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - rlglSetModelShader(&postproQuad, shader); - - Texture2D texture; - texture.id = fboColorTexture; - texture.width = GetScreenWidth(); - texture.height = GetScreenHeight(); - - SetShaderMapDiffuse(&postproQuad.shader, texture); - - //TraceLog(INFO, "Postproquad texture id: %i", postproQuad.texture.id); - //TraceLog(INFO, "Postproquad shader diffuse map id: %i", postproQuad.shader.texDiffuseId); - //TraceLog(INFO, "Shader diffuse map id: %i", shader.texDiffuseId); -#endif -} - // Vertex Buffer Object deinitialization (memory free) void rlglClose(void) { @@ -1377,7 +1361,18 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r // Set shader textures (diffuse, normal, specular) glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, model.shader.texDiffuseId); - //glUniform1i(model.shader.mapDiffuseLoc, 0); // Diffuse texture fits in texture unit 0 + + if (model.shader.texNormalId != 0) + { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, model.shader.texNormalId); + } + + if (model.shader.texSpecularId != 0) + { + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, model.shader.texSpecularId); + } if (vaoSupported) { @@ -1402,9 +1397,21 @@ void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 r // Draw call! glDrawArrays(GL_TRIANGLES, 0, model.mesh.vertexCount); + + if (model.shader.texNormalId != 0) + { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, 0); + } + + if (model.shader.texSpecularId != 0) + { + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, 0); + } - glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures glActiveTexture(GL_TEXTURE0); // Set shader active texture to default 0 + glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures if (vaoSupported) glBindVertexArray(0); // Unbind VAO else glBindBuffer(GL_ARRAY_BUFFER, 0); // Unbind VBOs @@ -1933,12 +1940,130 @@ Model rlglLoadModel(VertexData mesh) return model; } +// Read screen pixel data (color buffer) +unsigned char *rlglReadScreenPixels(int width, int height) +{ + unsigned char *screenData = (unsigned char *)malloc(width * height * sizeof(unsigned char) * 4); + + // NOTE: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData); + + // Flip image vertically! + unsigned char *imgData = (unsigned char *)malloc(width * height * sizeof(unsigned char) * 4); + + for (int y = height-1; y >= 0; y--) + { + for (int x = 0; x < (width*4); x++) + { + imgData[x + (height - y - 1)*width*4] = screenData[x + (y*width*4)]; + } + } + + free(screenData); + + return imgData; // NOTE: image data should be freed +} + +// Read texture pixel data +void *rlglReadTexturePixels(unsigned int textureId, unsigned int format) +{ + int width, height; + + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); + //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); + //GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE + + int glFormat = 0, glType = 0; + void *pixels = NULL; + unsigned int size = width*height; + + switch (format) + { + case UNCOMPRESSED_GRAYSCALE: pixels = (unsigned char *)malloc(size); glFormat = GL_LUMINANCE; glType = GL_UNSIGNED_BYTE; break; // 8 bit per pixel (no alpha) + case UNCOMPRESSED_GRAY_ALPHA: pixels = (unsigned char *)malloc(size*2); glFormat = GL_LUMINANCE_ALPHA; glType = GL_UNSIGNED_BYTE; break; // 16 bpp (2 channels) + case UNCOMPRESSED_R5G6B5: pixels = (unsigned short *)malloc(size); glFormat = GL_RGB; glType = GL_UNSIGNED_SHORT_5_6_5; break; // 16 bpp + case UNCOMPRESSED_R8G8B8: pixels = (unsigned char *)malloc(size*3); glFormat = GL_RGB; glType = GL_UNSIGNED_BYTE; break; // 24 bpp + case UNCOMPRESSED_R5G5B5A1: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_5_5_5_1; break; // 16 bpp (1 bit alpha) + case UNCOMPRESSED_R4G4B4A4: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_4_4_4_4; break; // 16 bpp (4 bit alpha) + case UNCOMPRESSED_R8G8B8A8: pixels = (unsigned char *)malloc(size*4); glFormat = GL_RGBA; glType = GL_UNSIGNED_BYTE; break; // 32 bpp + default: TraceLog(WARNING, "Texture format not suported"); break; + } + + glBindTexture(GL_TEXTURE_2D, textureId); + + // NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding. + // Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting. + // GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.) + // GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.) + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels); + + glBindTexture(GL_TEXTURE_2D, 0); + + return pixels; +} + + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Shaders Functions +// NOTE: Those functions are exposed directly to the user in raylib.h +//---------------------------------------------------------------------------------- + +// Load a custom shader and bind default locations +Shader LoadShader(char *vsFileName, char *fsFileName) +{ + Shader shader; #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) -// Load a shader (vertex shader + fragment shader) from text data -unsigned int rlglLoadShaderFromText(char *vShaderStr, char *fShaderStr) + // Shaders loading from external text file + char *vShaderStr = TextFileRead(vsFileName); + char *fShaderStr = TextFileRead(fsFileName); + + shader.id = LoadShaderProgram(vShaderStr, fShaderStr); + + if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Custom shader loaded successfully", shader.id); + else TraceLog(WARNING, "[SHDR ID %i] Custom shader could not be loaded", shader.id); + + // Shader strings must be freed + free(vShaderStr); + free(fShaderStr); + + // Set shader textures ids (all 0 by default) + shader.texDiffuseId = 0; + shader.texNormalId = 0; + shader.texSpecularId = 0; + + // Get handles to GLSL input attibute locations + //------------------------------------------------------------------- + shader.vertexLoc = glGetAttribLocation(shader.id, "vertexPosition"); + shader.texcoordLoc = glGetAttribLocation(shader.id, "vertexTexCoord"); + shader.normalLoc = glGetAttribLocation(shader.id, "vertexNormal"); + // NOTE: custom shader does not use colorLoc + shader.colorLoc = -1; + + // Get handles to GLSL uniform locations (vertex shader) + shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix"); + shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix"); + + // Get handles to GLSL uniform locations (fragment shader) + shader.tintColorLoc = glGetUniformLocation(shader.id, "tintColor"); + shader.mapDiffuseLoc = glGetUniformLocation(shader.id, "texture0"); + shader.mapNormalLoc = -1; // It can be set later + shader.mapSpecularLoc = -1; // It can be set later + //-------------------------------------------------------------------- +#endif + + return shader; +} + +// Load a custom shader and return program id +unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr) { - unsigned int program; + unsigned int program = 0; + +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) GLuint vertexShader; GLuint fragmentShader; @@ -2029,154 +2154,18 @@ unsigned int rlglLoadShaderFromText(char *vShaderStr, char *fShaderStr) glDeleteShader(vertexShader); glDeleteShader(fragmentShader); - +#endif return program; } -#endif -// Read screen pixel data (color buffer) -unsigned char *rlglReadScreenPixels(int width, int height) +// Unload a custom shader from memory +void UnloadShader(Shader shader) { - unsigned char *screenData = (unsigned char *)malloc(width * height * sizeof(unsigned char) * 4); - - // NOTE: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, screenData); - - // Flip image vertically! - unsigned char *imgData = (unsigned char *)malloc(width * height * sizeof(unsigned char) * 4); - - for (int y = height-1; y >= 0; y--) - { - for (int x = 0; x < (width*4); x++) - { - imgData[x + (height - y - 1)*width*4] = screenData[x + (y*width*4)]; - } - } - - free(screenData); - - return imgData; // NOTE: image data should be freed -} - -// Read texture pixel data -void *rlglReadTexturePixels(unsigned int textureId, unsigned int format) -{ - int width, height; - - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); - //glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); - //GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE - - int glFormat, glType; - void *pixels = NULL; - unsigned int size = width*height; - - switch (format) - { - case UNCOMPRESSED_GRAYSCALE: pixels = (unsigned char *)malloc(size); glFormat = GL_LUMINANCE; glType = GL_UNSIGNED_BYTE; // 8 bit per pixel (no alpha) - case UNCOMPRESSED_GRAY_ALPHA: pixels = (unsigned char *)malloc(size*2); glFormat = GL_LUMINANCE_ALPHA; glType = GL_UNSIGNED_BYTE; // 16 bpp (2 channels) - case UNCOMPRESSED_R5G6B5: pixels = (unsigned short *)malloc(size); glFormat = GL_RGB; glType = GL_UNSIGNED_SHORT_5_6_5; // 16 bpp - case UNCOMPRESSED_R8G8B8: pixels = (unsigned char *)malloc(size*3); glFormat = GL_RGB; glType = GL_UNSIGNED_BYTE; // 24 bpp - case UNCOMPRESSED_R5G5B5A1: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_5_5_5_1; // 16 bpp (1 bit alpha) - case UNCOMPRESSED_R4G4B4A4: pixels = (unsigned short *)malloc(size); glFormat = GL_RGBA; glType = GL_UNSIGNED_SHORT_4_4_4_4; // 16 bpp (4 bit alpha) - case UNCOMPRESSED_R8G8B8A8: pixels = (unsigned char *)malloc(size*4); glFormat = GL_RGBA; glType = GL_UNSIGNED_BYTE; // 32 bpp - default: TraceLog(WARNING, "Texture format not suported"); break; - } - - glBindTexture(GL_TEXTURE_2D, textureId); - - // NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding. - // Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting. - // GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.) - // GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.) - glPixelStorei(GL_PACK_ALIGNMENT, 1); - - glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels); - - glBindTexture(GL_TEXTURE_2D, 0); - - return pixels; -} - -// Load a shader (vertex shader + fragment shader) from files -Shader rlglLoadShader(char *vsFileName, char *fsFileName) -{ - Shader shader; - -#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); - - shader.id = rlglLoadShaderFromText(vShaderStr, fShaderStr); - - if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Custom shader loaded successfully", shader.id); - else TraceLog(WARNING, "[SHDR ID %i] Custom shader could not be loaded", shader.id); - - // Shader strings must be freed - free(vShaderStr); - free(fShaderStr); - - // Set shader textures ids (all 0 by default) - shader.texDiffuseId = 0; - shader.texNormalId = 0; - shader.texSpecularId = 0; - - // Get handles to GLSL input attibute locations - //------------------------------------------------------------------- - shader.vertexLoc = glGetAttribLocation(shader.id, "vertexPosition"); - shader.texcoordLoc = glGetAttribLocation(shader.id, "vertexTexCoord"); - shader.normalLoc = glGetAttribLocation(shader.id, "vertexNormal"); - // NOTE: custom shader does not use colorLoc - shader.colorLoc = -1; - - // Get handles to GLSL uniform locations (vertex shader) - shader.modelviewLoc = glGetUniformLocation(shader.id, "modelviewMatrix"); - shader.projectionLoc = glGetUniformLocation(shader.id, "projectionMatrix"); - - // Get handles to GLSL uniform locations (fragment shader) - shader.tintColorLoc = glGetUniformLocation(shader.id, "tintColor"); - shader.mapDiffuseLoc = glGetUniformLocation(shader.id, "texture0"); - shader.mapNormalLoc = -1; // It can be set later - shader.mapSpecularLoc = -1; // It can be set later - //-------------------------------------------------------------------- -#endif - - return shader; -} - -// Link shader to model -void rlglSetModelShader(Model *model, Shader shader) -{ -#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - model->shader = shader; - - if (vaoSupported) glBindVertexArray(model->mesh.vaoId); - - // Enable vertex attributes: position - glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[0]); - glEnableVertexAttribArray(shader.vertexLoc); - glVertexAttribPointer(shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); - - // Enable vertex attributes: texcoords - glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[1]); - glEnableVertexAttribArray(shader.texcoordLoc); - glVertexAttribPointer(shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); - - // Enable vertex attributes: normals - glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[2]); - glEnableVertexAttribArray(shader.normalLoc); - glVertexAttribPointer(shader.normalLoc, 3, GL_FLOAT, 0, 0, 0); - - if (vaoSupported) glBindVertexArray(0); // Unbind VAO - - //if (model->texture.id > 0) model->shader.texDiffuseId = model->texture.id; -#endif + rlDeleteShader(shader.id); } // Set custom shader to be used on batch draw -void rlglSetCustomShader(Shader shader) +void SetCustomShader(Shader shader) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) if (currentShader.id != shader.id) @@ -2208,15 +2197,84 @@ void rlglSetCustomShader(Shader shader) #endif } -// Set default shader to be used on batch draw -void rlglSetDefaultShader(void) +// Set postprocessing shader +void SetPostproShader(Shader shader) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - rlglSetCustomShader(defaultShader); - rlglSetPostproShader(defaultShader); + if (!enabledPostpro) + { + enabledPostpro = true; + rlglInitPostpro(); + } + + SetModelShader(&postproQuad, shader); + + Texture2D texture; + texture.id = fboColorTexture; + texture.width = GetScreenWidth(); + texture.height = GetScreenHeight(); + + SetShaderMapDiffuse(&postproQuad.shader, texture); + + //TraceLog(DEBUG, "Postproquad texture id: %i", postproQuad.texture.id); + //TraceLog(DEBUG, "Postproquad shader diffuse map id: %i", postproQuad.shader.texDiffuseId); + //TraceLog(DEBUG, "Shader diffuse map id: %i", shader.texDiffuseId); +#elif defined(GRAPHICS_API_OPENGL_11) + TraceLog(WARNING, "Postprocessing shaders not supported on OpenGL 1.1"); #endif } +// Set default shader to be used in batch draw +void SetDefaultShader(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + SetCustomShader(defaultShader); + SetPostproShader(defaultShader); + + enabledPostpro = false; +#endif +} + +// Link shader to model +void SetModelShader(Model *model, Shader shader) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + model->shader = shader; + + if (vaoSupported) glBindVertexArray(model->mesh.vaoId); + + // Enable vertex attributes: position + glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[0]); + glEnableVertexAttribArray(shader.vertexLoc); + glVertexAttribPointer(shader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); + + // Enable vertex attributes: texcoords + glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[1]); + glEnableVertexAttribArray(shader.texcoordLoc); + glVertexAttribPointer(shader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); + + // Enable vertex attributes: normals + glBindBuffer(GL_ARRAY_BUFFER, model->mesh.vboId[2]); + glEnableVertexAttribArray(shader.normalLoc); + glVertexAttribPointer(shader.normalLoc, 3, GL_FLOAT, 0, 0, 0); + + if (vaoSupported) glBindVertexArray(0); // Unbind VAO + + //if (model->texture.id > 0) model->shader.texDiffuseId = model->texture.id; +#endif +} + +// Check if postprocessing is enabled (used in module: core) +bool IsPosproShaderEnabled(void) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + return enabledPostpro; +#elif defined(GRAPHICS_API_OPENGL_11) + return false; +#endif +} + +// Get shader uniform location int GetShaderLocation(Shader shader, const char *uniformName) { int location = -1; @@ -2228,6 +2286,7 @@ int GetShaderLocation(Shader shader, const char *uniformName) return location; } +// Set shader uniform value (float) void SetShaderValue(Shader shader, int uniformLoc, float *value, int size) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) @@ -2237,12 +2296,29 @@ void SetShaderValue(Shader shader, int uniformLoc, float *value, int size) else if (size == 2) glUniform2fv(uniformLoc, 1, value); // Shader uniform type: vec2 else if (size == 3) glUniform3fv(uniformLoc, 1, value); // Shader uniform type: vec3 else if (size == 4) glUniform4fv(uniformLoc, 1, value); // Shader uniform type: vec4 - else TraceLog(WARNING, "Shader value float array size not recognized"); + else TraceLog(WARNING, "Shader value float array size not supported"); glUseProgram(0); #endif } +// Set shader uniform value (int) +void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size) +{ +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + glUseProgram(shader.id); + + if (size == 1) glUniform1iv(uniformLoc, 1, value); // Shader uniform type: int + else if (size == 2) glUniform2iv(uniformLoc, 1, value); // Shader uniform type: ivec2 + else if (size == 3) glUniform3iv(uniformLoc, 1, value); // Shader uniform type: ivec3 + else if (size == 4) glUniform4iv(uniformLoc, 1, value); // Shader uniform type: ivec4 + else TraceLog(WARNING, "Shader value int array size not supported"); + + glUseProgram(0); +#endif +} + +// Default diffuse shader map texture assignment void SetShaderMapDiffuse(Shader *shader, Texture2D texture) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) @@ -2261,6 +2337,7 @@ void SetShaderMapDiffuse(Shader *shader, Texture2D texture) #endif } +// Normal map texture shader assignment void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) @@ -2285,6 +2362,7 @@ void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D textu #endif } +// Specular map texture shader assignment void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) @@ -2300,7 +2378,7 @@ void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D tex glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, shader->texSpecularId); - glUniform1i(shader->mapSpecularLoc, 2); // Texture fits in active texture unit 0 + glUniform1i(shader->mapSpecularLoc, 2); // Texture fits in active texture unit 2 glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); @@ -2309,6 +2387,35 @@ void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D tex #endif } +// Generic shader maps assignment +// TODO: Trying to find a generic shader to allow any kind of map +// NOTE: mapLocation should be retrieved by user with GetShaderLocation() +// ISSUE: mapTextureId: Shader should contain a reference to map texture and corresponding textureUnit, +// so it can be automatically checked and used in rlglDrawModel() +void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textureUnit) +{ +/* +#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + if (mapLocation == -1) TraceLog(WARNING, "[SHDR ID %i] Map location could not be found", shader->id); + else + { + shader->mapTextureId = texture.id; + + glUseProgram(shader->id); + + glActiveTexture(GL_TEXTURE0 + textureUnit); + glBindTexture(GL_TEXTURE_2D, shader->mapTextureId); + + glUniform1i(mapLocation, textureUnit); // Texture fits in active textureUnit + + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE0); + glUseProgram(0); + } +#endif +*/ +} + #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) void PrintProjectionMatrix(void) { @@ -2415,7 +2522,7 @@ static Shader LoadDefaultShader(void) " gl_FragColor = texelColor*tintColor; \n" "} \n"; - shader.id = rlglLoadShaderFromText(vShaderStr, fShaderStr); + shader.id = LoadShaderProgram(vShaderStr, fShaderStr); if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Default shader loaded successfully", shader.id); else TraceLog(WARNING, "[SHDR ID %i] Default shader could not be loaded", shader.id); @@ -2491,7 +2598,7 @@ static Shader LoadSimpleShader(void) " gl_FragColor = texelColor*tintColor; \n" "} \n"; - shader.id = rlglLoadShaderFromText(vShaderStr, fShaderStr); + shader.id = LoadShaderProgram(vShaderStr, fShaderStr); if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Simple shader loaded successfully", shader.id); else TraceLog(WARNING, "[SHDR ID %i] Simple shader could not be loaded", shader.id); @@ -2710,7 +2817,7 @@ static void InitializeBuffersGPU(void) // Update 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 +// TODO: If no data changed on the CPU arrays --> No need to update GPU arrays (change flag required) static void UpdateBuffers(void) { if (lines.vCounter > 0) diff --git a/src/rlgl.h b/src/rlgl.h index e241a9c14..eabf07e40 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -212,14 +212,11 @@ void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Init unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load in GPU OpenGL texture void rlglGenerateMipmaps(unsigned int textureId); // Generate mipmap data for selected texture -Shader rlglLoadShader(char *vsFileName, char *fsFileName); // Load a shader (vertex shader + fragment shader) from files -unsigned int rlglLoadShaderFromText(char *vShaderStr, char *fShaderStr); // Load a shader from text data +// NOTE: There is a set of shader related functions that are available to end user, +// to avoid creating function wrappers through core module, they have been directly declared in raylib.h + void rlglInitPostpro(void); // Initialize postprocessing system void rlglDrawPostpro(void); // Draw with postprocessing shader -void rlglSetPostproShader(Shader shader); // Set postprocessing shader -void rlglSetModelShader(Model *model, Shader shader); // Set shader for a model -void rlglSetCustomShader(Shader shader); // Set custom shader to be used on batch draw -void rlglSetDefaultShader(void); // Set default shader to be used on batch draw Model rlglLoadModel(VertexData mesh); // Upload vertex data into GPU and provided VAO/VBO ids void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires); From 14d3b0a084808716b80eb93c91880f6b0c41133d Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 18 Jul 2015 19:25:15 +0200 Subject: [PATCH 10/12] Corrected issue on mipmaps generations --- src/rlgl.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/rlgl.c b/src/rlgl.c index b4bd71155..12a257366 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1809,17 +1809,21 @@ void rlglGenerateMipmaps(unsigned int textureId) { glBindTexture(GL_TEXTURE_2D, textureId); + // Check if texture is power-of-two (POT) + bool texIsPOT = false; + + // NOTE: In OpenGL ES 2.0 we have no way to retrieve texture size from id + +#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) int width, height; glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); - // Check if texture is power-of-two (POT) to enable mipmap generation - bool texIsPOT = false; - if (((width > 0) && ((width & (width - 1)) == 0)) && ((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true; +#endif - if (texIsPOT) + if ((texIsPOT) || (npotSupported)) { #if defined(GRAPHICS_API_OPENGL_11) // Compute required mipmaps @@ -1852,14 +1856,12 @@ void rlglGenerateMipmaps(unsigned int textureId) #elif 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", textureId); -#endif -#if defined(GRAPHICS_API_OPENGL_33) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Activate Trilinear filtering for mipmaps (must be available) #endif } - else TraceLog(WARNING, "[TEX ID %i] Texture is not power-of-two, mipmaps can not be generated", textureId); + else TraceLog(WARNING, "[TEX ID %i] Mipmaps can not be generated", textureId); glBindTexture(GL_TEXTURE_2D, 0); } @@ -1965,8 +1967,12 @@ unsigned char *rlglReadScreenPixels(int width, int height) } // Read texture pixel data +// NOTE: Retrieving pixel data from GPU not supported on OpenGL ES 2.0 void *rlglReadTexturePixels(unsigned int textureId, unsigned int format) { + void *pixels = NULL; + +#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) int width, height; glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); @@ -1975,7 +1981,7 @@ void *rlglReadTexturePixels(unsigned int textureId, unsigned int format) //GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE int glFormat = 0, glType = 0; - void *pixels = NULL; + unsigned int size = width*height; switch (format) @@ -2001,7 +2007,8 @@ void *rlglReadTexturePixels(unsigned int textureId, unsigned int format) glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels); glBindTexture(GL_TEXTURE_2D, 0); - +#endif + return pixels; } From a98578c91db7d51233ae56e599dd4a3b2244cd0c Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 18 Jul 2015 19:25:43 +0200 Subject: [PATCH 11/12] Updated minSdkVersion and added comments --- templates/android_project/AndroidManifest.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/templates/android_project/AndroidManifest.xml b/templates/android_project/AndroidManifest.xml index 7f542111f..8bb0534fb 100644 --- a/templates/android_project/AndroidManifest.xml +++ b/templates/android_project/AndroidManifest.xml @@ -13,18 +13,23 @@ android:versionCode="1" android:versionName="1.0" > - + + + + + + From 067b884f395b7b6d4c179cb3d58b0d17a02950ec Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 18 Jul 2015 19:26:13 +0200 Subject: [PATCH 12/12] Updated examples for next raylib version --- examples/models_cubicmap.c | 8 ++++---- examples/models_heightmap.c | 8 ++++---- examples/models_planes.c | 3 +-- examples/textures_compressed_dds.c | 4 ++-- examples/textures_image_loading.c | 6 +++--- examples/textures_mipmaps.c | 4 ++-- 6 files changed, 16 insertions(+), 17 deletions(-) diff --git a/examples/models_cubicmap.c b/examples/models_cubicmap.c index 60e93c6da..62f7b076e 100644 --- a/examples/models_cubicmap.c +++ b/examples/models_cubicmap.c @@ -23,13 +23,13 @@ int main() // Define the camera to look into our 3d world Camera camera = {{ 7.0, 7.0, 7.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; - Image img = LoadImage("resources/cubicmap.png"); // Load cubesmap image (RAM) - Texture2D texture = LoadTextureFromImage(img, false); // Convert image to texture (VRAM) - Model map = LoadCubicmap(img); // Load cubicmap model + Image image = LoadImage("resources/cubicmap.png"); // Load cubesmap image (RAM) + Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM) + Model map = LoadCubicmap(image); // Load cubicmap model (generate model from image) SetModelTexture(&map, texture); // Bind texture to model Vector3 mapPosition = { -1, 0.0, -1 }; // Set model position - UnloadImage(img); // Unload cubesmap image from RAM, already uploaded to VRAM + UnloadImage(image); // Unload cubesmap image from RAM, already uploaded to VRAM SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- diff --git a/examples/models_heightmap.c b/examples/models_heightmap.c index 7121c2615..a23656a56 100644 --- a/examples/models_heightmap.c +++ b/examples/models_heightmap.c @@ -23,13 +23,13 @@ int main() // Define the camera to look into our 3d world Camera camera = {{ 10.0, 12.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }}; - Image img = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM) - Texture2D texture = LoadTextureFromImage(img, false); // Convert image to texture (VRAM) - Model map = LoadHeightmap(img, 4); // Load heightmap model + Image image = LoadImage("resources/heightmap.png"); // Load heightmap image (RAM) + Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM) + Model map = LoadHeightmap(image, 4); // Load heightmap model SetModelTexture(&map, texture); // Bind texture to model Vector3 mapPosition = { -4, 0.0, -4 }; // Set model position - UnloadImage(img); // Unload heightmap image from RAM, already uploaded to VRAM + UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- diff --git a/examples/models_planes.c b/examples/models_planes.c index b0a6b8780..58b5137e4 100644 --- a/examples/models_planes.c +++ b/examples/models_planes.c @@ -42,8 +42,7 @@ int main() Begin3dMode(camera); - DrawPlane((Vector3){ 0, 0, 0 }, (Vector2){ 4, 4 }, (Vector3){ 0, 45, 0 }, RED); - //DrawPlaneEx((Vector3){ 0, 8, 0 }, (Vector2){ 2, 1 }, (Vector3){ 0, 0, 0 }, 4, 4, SKYBLUE); + DrawPlane((Vector3){ 0, 0, 0 }, (Vector2){ 4, 4 }, RED); // Draw a plane XZ DrawGrid(10.0, 1.0); diff --git a/examples/textures_compressed_dds.c b/examples/textures_compressed_dds.c index d2ba58c8d..1092d5caf 100644 --- a/examples/textures_compressed_dds.c +++ b/examples/textures_compressed_dds.c @@ -24,8 +24,8 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [textures] example - DDS texture loading and drawing"); // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - //Texture2D texture = LoadTexture("resources/raylib_logo.dds"); // Texture loading (compressed) - Texture2D texture = LoadTexture("resources/raylib_logo_uncompressed.dds"); // Texture loading (uncompressed) + + Texture2D texture = LoadTexture("resources/raylib_logo.dds"); // Texture loading (compressed) SetTargetFPS(60); // Set our game to run at 60 frames-per-second //--------------------------------------------------------------------------------------- diff --git a/examples/textures_image_loading.c b/examples/textures_image_loading.c index b7fc2cfca..7c6aae522 100644 --- a/examples/textures_image_loading.c +++ b/examples/textures_image_loading.c @@ -24,10 +24,10 @@ int main() // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required) - Image img = LoadImage("resources/raylib_logo.png"); // Loaded in CPU memory (RAM) - Texture2D texture = LoadTextureFromImage(img, false); // Image converted to texture, GPU memory (VRAM) + Image image = LoadImage("resources/raylib_logo.png"); // Loaded in CPU memory (RAM) + Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM) - UnloadImage(img); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM + UnloadImage(image); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM //--------------------------------------------------------------------------------------- // Main game loop diff --git a/examples/textures_mipmaps.c b/examples/textures_mipmaps.c index d3ba1708f..6b7a64f01 100644 --- a/examples/textures_mipmaps.c +++ b/examples/textures_mipmaps.c @@ -24,10 +24,10 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture mipmaps generation"); // NOTE: To generate mipmaps for an image, image must be loaded first and converted to texture - // with mipmaps option set to true on CreateTexture() Image image = LoadImage("resources/raylib_logo.png"); // Load image to CPU memory (RAM) - Texture2D texture = LoadTextureFromImage(image, true); // Create texture and generate mipmaps + Texture2D texture = LoadTextureFromImage(image); // Load texture into GPU memory (VRAM) + GenTextureMipmaps(texture); // Generate mipmaps for texture UnloadImage(image); // Once texture has been created, we can unload image data from RAM //--------------------------------------------------------------------------------------