Browse Source

Improved render to texture

Support render texture size different than screen size
raysan5 9 years ago
parent
commit
ea5b00528b
5 changed files with 51 additions and 9 deletions
  1. 2 0
      examples/shaders_custom_uniform.c
  2. 31 5
      src/core.c
  3. 14 0
      src/rlgl.c
  4. 1 0
      src/rlgl.h
  5. 3 4
      src/textures.c

+ 2 - 0
examples/shaders_custom_uniform.c

@@ -89,6 +89,8 @@ int main()
                     DrawGrid(10, 1.0f);     // Draw a grid
                     DrawGrid(10, 1.0f);     // Draw a grid
 
 
                 End3dMode();
                 End3dMode();
+                
+                DrawText("TEXT DRAWN IN RENDER TEXTURE", 200, 10, 30, RED);
             
             
             EndTextureMode();           // End drawing to texture (now we have a texture available for next passes)
             EndTextureMode();           // End drawing to texture (now we have a texture available for next passes)
             
             

+ 31 - 5
src/core.c

@@ -562,9 +562,8 @@ void Begin2dMode(Camera2D camera)
     Matrix matOrigin = MatrixTranslate(-camera.target.x, -camera.target.y, 0.0f);
     Matrix matOrigin = MatrixTranslate(-camera.target.x, -camera.target.y, 0.0f);
     Matrix matRotation = MatrixRotate((Vector3){ 0.0f, 0.0f, 1.0f }, camera.rotation*DEG2RAD);
     Matrix matRotation = MatrixRotate((Vector3){ 0.0f, 0.0f, 1.0f }, camera.rotation*DEG2RAD);
     Matrix matScale = MatrixScale(camera.zoom, camera.zoom, 1.0f);
     Matrix matScale = MatrixScale(camera.zoom, camera.zoom, 1.0f);
-    
     Matrix matTranslation = MatrixTranslate(camera.offset.x + camera.target.x, camera.offset.y + camera.target.y, 0.0f);
     Matrix matTranslation = MatrixTranslate(camera.offset.x + camera.target.x, camera.offset.y + camera.target.y, 0.0f);
-
+    
     Matrix matTransform = MatrixMultiply(MatrixMultiply(matOrigin, MatrixMultiply(matScale, matRotation)), matTranslation);
     Matrix matTransform = MatrixMultiply(MatrixMultiply(matOrigin, MatrixMultiply(matScale, matRotation)), matTranslation);
     
     
     rlMultMatrixf(MatrixToFloat(matTransform));
     rlMultMatrixf(MatrixToFloat(matTransform));
@@ -627,11 +626,24 @@ void BeginTextureMode(RenderTexture2D target)
 {
 {
     rlglDraw();                         // Draw Buffers (Only OpenGL 3+ and ES2)
     rlglDraw();                         // Draw Buffers (Only OpenGL 3+ and ES2)
 
 
-    rlEnableRenderTexture(target.id);
-    
+    rlEnableRenderTexture(target.id);   // Enable render target
+
     rlClearScreenBuffers();             // Clear render texture buffers
     rlClearScreenBuffers();             // Clear render texture buffers
+    
+    // Set viewport to framebuffer size
+    rlViewport(0, 0, target.texture.width, target.texture.height); 
+    
+    rlMatrixMode(RL_PROJECTION);        // Switch to PROJECTION matrix
+    rlLoadIdentity();                   // Reset current matrix (PROJECTION)
 
 
+    // Set orthographic projection to current framebuffer size
+    // NOTE: Configured top-left corner as (0, 0)
+    rlOrtho(0, target.texture.width, target.texture.height, 0, 0.0f, 1.0f);        
+
+    rlMatrixMode(RL_MODELVIEW);         // Switch back to MODELVIEW matrix
     rlLoadIdentity();                   // Reset current matrix (MODELVIEW)
     rlLoadIdentity();                   // Reset current matrix (MODELVIEW)
+
+    //rlScalef(0.0f, -1.0f, 0.0f);      // Flip Y-drawing (?)
 }
 }
 
 
 // Ends drawing to render texture
 // Ends drawing to render texture
@@ -639,7 +651,21 @@ void EndTextureMode(void)
 {
 {
     rlglDraw();                         // Draw Buffers (Only OpenGL 3+ and ES2)
     rlglDraw();                         // Draw Buffers (Only OpenGL 3+ and ES2)
 
 
-    rlDisableRenderTexture();
+    rlDisableRenderTexture();           // Disable render target
+
+    // Set viewport to default framebuffer size (screen size)
+    // TODO: consider possible viewport offsets
+    rlViewport(0, 0, GetScreenWidth(), GetScreenHeight());
+    
+    rlMatrixMode(RL_PROJECTION);        // Switch to PROJECTION matrix
+    rlLoadIdentity();                   // Reset current matrix (PROJECTION)
+    
+    // Set orthographic projection to current framebuffer size
+    // NOTE: Configured top-left corner as (0, 0)
+    rlOrtho(0, GetScreenWidth(), GetScreenHeight(), 0, 0.0f, 1.0f);
+
+    rlMatrixMode(RL_MODELVIEW);         // Switch back to MODELVIEW matrix
+    rlLoadIdentity();                   // Reset current matrix (MODELVIEW)
 }
 }
 
 
 // Set target FPS for the game
 // Set target FPS for the game

+ 14 - 0
src/rlgl.c

@@ -404,6 +404,12 @@ void rlOrtho(double left, double right, double bottom, double top, double near,
 
 
 #endif
 #endif
 
 
+// Set the viewport area (trasnformation from normalized device coordinates to window coordinates)
+void rlViewport(int x, int y, int width, int height)
+{
+    glViewport(x, y, width, height);
+}
+
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Module Functions Definition - Vertex level operations
 // Module Functions Definition - Vertex level operations
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
@@ -725,17 +731,25 @@ void rlDisableTexture(void)
 #endif
 #endif
 }
 }
 
 
+// Enable rendering to texture (fbo)
 void rlEnableRenderTexture(unsigned int id)
 void rlEnableRenderTexture(unsigned int id)
 {
 {
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
     glBindFramebuffer(GL_FRAMEBUFFER, id);
     glBindFramebuffer(GL_FRAMEBUFFER, id);
+
+    //glDisable(GL_CULL_FACE);    // Allow double side drawing for texture flipping
+    //glCullFace(GL_FRONT);
 #endif
 #endif
 }
 }
 
 
+// Disable rendering to texture
 void rlDisableRenderTexture(void)
 void rlDisableRenderTexture(void)
 {
 {
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+    //glEnable(GL_CULL_FACE);
+    //glCullFace(GL_BACK);
 #endif
 #endif
 }
 }
 
 

+ 1 - 0
src/rlgl.h

@@ -247,6 +247,7 @@ void rlScalef(float x, float y, float z);       // Multiply the current matrix b
 void rlMultMatrixf(float *mat);                 // Multiply the current matrix by another matrix
 void rlMultMatrixf(float *mat);                 // Multiply the current matrix by another matrix
 void rlFrustum(double left, double right, double bottom, double top, double near, double far);
 void rlFrustum(double left, double right, double bottom, double top, double near, double far);
 void rlOrtho(double left, double right, double bottom, double top, double near, double far);
 void rlOrtho(double left, double right, double bottom, double top, double near, double far);
+void rlViewport(int x, int y, int width, int height); // Set the viewport area
 
 
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 // Functions Declaration - Vertex level operations
 // Functions Declaration - Vertex level operations

+ 3 - 4
src/textures.c

@@ -1385,10 +1385,6 @@ void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float sc
 void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint)
 void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint)
 {
 {
     Rectangle destRec = { (int)position.x, (int)position.y, abs(sourceRec.width), abs(sourceRec.height) };
     Rectangle destRec = { (int)position.x, (int)position.y, abs(sourceRec.width), abs(sourceRec.height) };
-    
-    if (sourceRec.width < 0) sourceRec.x -= sourceRec.width;
-    if (sourceRec.height < 0) sourceRec.y -= sourceRec.height;
-    
     Vector2 origin = { 0, 0 };
     Vector2 origin = { 0, 0 };
 
 
     DrawTexturePro(texture, sourceRec, destRec, origin, 0.0f, tint);
     DrawTexturePro(texture, sourceRec, destRec, origin, 0.0f, tint);
@@ -1398,6 +1394,9 @@ void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Co
 // NOTE: origin is relative to destination rectangle size
 // NOTE: origin is relative to destination rectangle size
 void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint)
 void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint)
 {
 {
+    if (sourceRec.width < 0) sourceRec.x -= sourceRec.width;
+    if (sourceRec.height < 0) sourceRec.y -= sourceRec.height;
+    
     rlEnableTexture(texture.id);
     rlEnableTexture(texture.id);
 
 
     rlPushMatrix();
     rlPushMatrix();