Browse Source

FBO working as expected, render background on menu state

Eduardo Bart 10 years ago
parent
commit
4102ae093c
9 changed files with 131 additions and 57 deletions
  1. 2
    0
      src/engine.cpp
  2. 47
    28
      src/framebuffer.cpp
  3. 6
    5
      src/framebuffer.h
  4. 8
    6
      src/graphics.cpp
  5. 5
    6
      src/graphics.h
  6. 1
    0
      src/main.cpp
  7. 46
    4
      src/menustate.cpp
  8. 14
    5
      src/texture.cpp
  9. 2
    3
      src/texture.h

+ 2
- 0
src/engine.cpp View File

@@ -68,6 +68,8 @@ void Engine::init()
68 68
 
69 69
 void Engine::terminate()
70 70
 {
71
+    changeState(NULL);
72
+
71 73
     // save configs
72 74
     g_config.setValue("width", Platform::getWindowWidth());
73 75
     g_config.setValue("height", Platform::getWindowHeight());

+ 47
- 28
src/framebuffer.cpp View File

@@ -24,25 +24,31 @@
24 24
 #define GL_GLEXT_PROTOTYPES
25 25
 
26 26
 #include "framebuffer.h"
27
+#include "platform.h"
28
+#include "graphics.h"
29
+#include "logger.h"
27 30
 
28 31
 #include <GL/glext.h>
29 32
 #include <GL/glu.h>
30
-#include "platform.h"
31
-#include "graphics.h"
32 33
 
33
-FrameBuffer::FrameBuffer(int width, int height) :
34
-    m_fbo(0)
34
+FrameBuffer::FrameBuffer(int width, int height)
35 35
 {
36
+    m_fbo = 0;
36 37
     m_width = width;
37 38
     m_height = height;
38 39
 
39
-    // texture where the framebuffer will be store
40
-    m_frameTexture = TexturePtr(new Texture(width, height, 4));
40
+    // create FBO texture
41
+    glGenTextures(1, &m_fboTexture);
42
+    glBindTexture(GL_TEXTURE_2D, m_fboTexture);
43
+    glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
44
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
45
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
41 46
 
42
-    // we want a smooth framebuffer
43
-    m_frameTexture->enableBilinearFilter();
47
+    // we want bilinear filtering (for a smooth framebuffer)
48
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
49
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
44 50
 
45
-    // use FBO only if supported
51
+    // use FBO ext only if supported
46 52
     if(Platform::isExtensionSupported("EXT_framebuffer_object")) {
47 53
         m_fallbackOldImp = false;
48 54
 
@@ -51,18 +57,14 @@ FrameBuffer::FrameBuffer(int width, int height) :
51 57
         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
52 58
 
53 59
         // attach 2D texture to this FBO
54
-        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_frameTexture->getTextureId(), 0);
55
-
56
-        // must be called before checking
57
-        glDrawBuffer(GL_NONE);
58
-        glReadBuffer(GL_NONE);
60
+        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_fboTexture, 0);
59 61
 
60 62
         GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
61 63
         switch(status) {
62 64
             case GL_FRAMEBUFFER_COMPLETE_EXT:
63 65
                 //ok
64 66
                 break;
65
-            default:
67
+            default: // fallback to old implementation
66 68
                 m_fallbackOldImp = true;
67 69
                 break;
68 70
         }
@@ -74,6 +76,7 @@ FrameBuffer::FrameBuffer(int width, int height) :
74 76
 
75 77
 FrameBuffer::~FrameBuffer()
76 78
 {
79
+    glDeleteTextures(1, &m_fboTexture);
77 80
     if(m_fbo)
78 81
         glDeleteFramebuffersEXT(1, &m_fbo);
79 82
 }
@@ -83,18 +86,21 @@ void FrameBuffer::bind()
83 86
     if(!m_fallbackOldImp) {
84 87
         // bind framebuffer
85 88
         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
86
-
87
-        // must be called before rendering to framebuffer
88
-        glDrawBuffer(GL_NONE);
89
-        glReadBuffer(GL_NONE);
90 89
     }
91 90
 
91
+    // setup framebuffer viewport
92
+    glViewport(0, 0, m_width, m_height);
93
+    glMatrixMode(GL_PROJECTION);
94
+    glLoadIdentity();
95
+    gluOrtho2D(0.0f, m_width, 0, m_height);
96
+
97
+    // back to model view
98
+    glMatrixMode(GL_MODELVIEW);
99
+    glLoadIdentity();
100
+
92 101
     // clear framebuffer
93 102
     glClearColor(0.0, 0.0, 0.0, 0.0);
94 103
     glClear(GL_COLOR_BUFFER_BIT);
95
-
96
-    // setup framebuffer viewport
97
-    g_graphics.setViewport(m_width, m_height);
98 104
 }
99 105
 
100 106
 void FrameBuffer::unbind()
@@ -102,19 +108,32 @@ void FrameBuffer::unbind()
102 108
     if(!m_fallbackOldImp) {
103 109
         // bind back buffer again
104 110
         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
105
-
106
-        // must be called to render to back buffer again
107 111
         glDrawBuffer(GL_BACK);
108 112
         glReadBuffer(GL_BACK);
113
+
114
+        // restore graphics viewport
115
+        g_graphics.restoreViewport();
109 116
     } else {
110 117
         // copy screen to texture
111
-        m_frameTexture->copyFromScreen(0, 0, 0, 0, m_width, m_height);
118
+        glBindTexture(GL_TEXTURE_2D, m_fboTexture);
119
+        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
120
+
121
+        // restore graphics viewport
122
+        g_graphics.restoreViewport();
112 123
 
113 124
         // clear screen
114
-        glClearColor(0.0, 0.0, 0.0, 0.0);
125
+        glClearColor(0.0, 0.0, 0.0, 1.0);
115 126
         glClear(GL_COLOR_BUFFER_BIT);
116 127
     }
128
+}
117 129
 
118
-    // restore graphics viewport
119
-    g_graphics.restoreViewport();
130
+void FrameBuffer::draw(int x, int y, int width, int height)
131
+{
132
+    glBindTexture(GL_TEXTURE_2D, m_fboTexture);
133
+    glBegin(GL_QUADS);
134
+    glTexCoord2i(0, 0); glVertex2i(x,       y);
135
+    glTexCoord2i(0, 1); glVertex2i(x,       y+height);
136
+    glTexCoord2i(1, 1); glVertex2i(x+width, y+height);
137
+    glTexCoord2i(1, 0); glVertex2i(x+width, y);
138
+    glEnd();
120 139
 }

+ 6
- 5
src/framebuffer.h View File

@@ -25,24 +25,25 @@
25 25
 #ifndef FRAMEBUFFER_H
26 26
 #define FRAMEBUFFER_H
27 27
 
28
-#include "texture.h"
28
+#include <GL/gl.h>
29 29
 
30 30
 class FrameBuffer
31 31
 {
32
+public:
32 33
     FrameBuffer(int width, int height);
33 34
     virtual ~FrameBuffer();
34 35
 
35
-    /// Return the texture where everything was drawn
36
-    TexturePtr getFramebufferTexture();
37
-
38 36
     /// Bind the framebuffer, everything rendered will be draw on it
39 37
     void bind();
40 38
 
41 39
     /// Unbind the framebuffer, render on back buffer again
42 40
     void unbind();
43 41
 
42
+    /// Draw framebuffer
43
+    void draw(int x, int y, int width, int height);
44
+
44 45
 private:
45
-    TexturePtr m_frameTexture;
46
+    GLuint m_fboTexture;
46 47
     GLuint m_fbo;
47 48
     bool m_fallbackOldImp;
48 49
     int m_width;

+ 8
- 6
src/graphics.cpp View File

@@ -27,6 +27,7 @@
27 27
 
28 28
 #include <GL/gl.h>
29 29
 #include <GL/glu.h>
30
+#include "texture.h"
30 31
 
31 32
 Graphics g_graphics;
32 33
 
@@ -43,10 +44,10 @@ Graphics::~Graphics()
43 44
 void Graphics::init()
44 45
 {
45 46
     // setup opengl
46
-    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // black background
47
-    glEnable(GL_ALPHA_TEST); // enable alpha
47
+    glEnable(GL_ALPHA_TEST); // enable alpha by default
48 48
     glAlphaFunc(GL_GREATER, 0.0f); // default alpha mode
49 49
     glDisable(GL_DEPTH_TEST); // we are rendering 2D only, we don't need it
50
+    glEnable(GL_TEXTURE_2D); // enable textures by default
50 51
 
51 52
     notice("GPU %s", (const char*)glGetString(GL_RENDERER));
52 53
     notice("OpenGL %s", (const char*)glGetString(GL_VERSION));
@@ -64,13 +65,13 @@ void Graphics::resize(int width, int height)
64 65
     restoreViewport();
65 66
 }
66 67
 
67
-void Graphics::setViewport(int width, int height)
68
+void Graphics::restoreViewport()
68 69
 {
69 70
     // resize gl viewport
70
-    glViewport(0, 0, width, height);
71
+    glViewport(0, 0, m_width, m_height);
71 72
 
72 73
     /*
73
-     0 ,0---------0,w**
74
+     0,0---------0,w
74 75
      |           |
75 76
      |           |
76 77
      |           |
@@ -79,7 +80,7 @@ void Graphics::setViewport(int width, int height)
79 80
     // setup view region like above
80 81
     glMatrixMode(GL_PROJECTION);
81 82
     glLoadIdentity();
82
-    gluOrtho2D(0.0f, width, height, 0.0f);
83
+    gluOrtho2D(0.0f, m_width, m_height, 0.0f);
83 84
 
84 85
     // back to model view
85 86
     glMatrixMode(GL_MODELVIEW);
@@ -88,6 +89,7 @@ void Graphics::setViewport(int width, int height)
88 89
 
89 90
 void Graphics::beginRender()
90 91
 {
92
+    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
91 93
     glClear(GL_COLOR_BUFFER_BIT);
92 94
     glLoadIdentity();
93 95
 }

+ 5
- 6
src/graphics.h View File

@@ -25,6 +25,8 @@
25 25
 #ifndef GRAPHICS_H
26 26
 #define GRAPHICS_H
27 27
 
28
+class Texture;
29
+
28 30
 class Graphics
29 31
 {
30 32
 public:
@@ -37,18 +39,15 @@ public:
37 39
     /// Called after every window resize
38 40
     void resize(int width, int height);
39 41
 
42
+    /// Restore original viewport
43
+    void restoreViewport();
44
+
40 45
     /// Called before every render
41 46
     void beginRender();
42 47
 
43 48
     /// Called after every render
44 49
     void endRender();
45 50
 
46
-    /// Restore original viewport
47
-    void restoreViewport() { setViewport(m_width, m_height); }
48
-
49
-    /// Set viewport, used by FrameBuffer
50
-    void setViewport(int width, int height);
51
-
52 51
     int getWidth() { return m_width; }
53 52
     int getHeight() { return m_height; }
54 53
 

+ 1
- 0
src/main.cpp View File

@@ -70,6 +70,7 @@ int main(int argc, const char *argv[])
70 70
     g_resources.init(argv[0]);
71 71
     if(g_resources.setWriteDir(Platform::getAppUserDir()))
72 72
         g_resources.addToSearchPath(Platform::getAppUserDir());
73
+    g_resources.addToSearchPath("data");
73 74
 
74 75
     // before loading configurations set the default ones
75 76
     setDefaultConfigs();

+ 46
- 4
src/menustate.cpp View File

@@ -26,9 +26,15 @@
26 26
 #include "framebuffer.h"
27 27
 #include "graphics.h"
28 28
 #include "texturemanager.h"
29
+#include "logger.h"
30
+#include "engine.h"
31
+
32
+FrameBuffer *fbo;
33
+TexturePtr background;
29 34
 
30 35
 MenuState::MenuState()
31 36
 {
37
+
32 38
 }
33 39
 
34 40
 MenuState::~MenuState()
@@ -38,7 +44,8 @@ MenuState::~MenuState()
38 44
 
39 45
 void MenuState::onEnter()
40 46
 {
41
-
47
+    background = g_textures.get("background.png");
48
+    background->enableBilinearFilter();
42 49
 }
43 50
 
44 51
 void MenuState::onLeave()
@@ -48,17 +55,52 @@ void MenuState::onLeave()
48 55
 
49 56
 void MenuState::onClose()
50 57
 {
51
-
58
+    g_engine.stop();
52 59
 }
53 60
 
54 61
 void MenuState::onInputEvent(InputEvent* event)
55 62
 {
56
-
57 63
 }
58 64
 
59 65
 void MenuState::render()
60 66
 {
61
-
67
+    // draw background
68
+    background->bind();
69
+
70
+    int x = 0;
71
+    int y = 0;
72
+    int screenWidth = g_graphics.getWidth();
73
+    int screenHeight = g_graphics.getHeight();
74
+    int textureWidth = background->getWidth();
75
+    int textureHeight = background->getHeight();
76
+
77
+    int texCoordX;
78
+    int texCoordY;
79
+    int texCoordWidth;
80
+    int texCoordHeight;
81
+
82
+    int wantedWidth = 1240;
83
+    int wantedHeight = 880;
84
+
85
+    float originalRatio = (float)wantedWidth/wantedHeight;
86
+    float screenRatio = (float)screenWidth/screenHeight;
87
+    if(screenRatio >= originalRatio) {
88
+        texCoordHeight = wantedHeight;
89
+        texCoordWidth = std::min((int)(wantedHeight*screenRatio), textureWidth);
90
+    } else {
91
+        texCoordWidth = wantedWidth;
92
+        texCoordHeight = std::min((int)(wantedWidth/screenRatio), textureHeight);
93
+    }
94
+    texCoordX = textureWidth - texCoordWidth;
95
+    texCoordY = textureHeight - texCoordHeight;
96
+
97
+
98
+    glBegin(GL_QUADS);
99
+    glTexCoord2f((float)texCoordX/textureWidth,                 (float)texCoordY/textureHeight); glVertex2i(x,       y);
100
+    glTexCoord2f((float)texCoordX/textureWidth,                 (float)(texCoordY+texCoordHeight)/textureHeight); glVertex2i(x,       y+screenHeight);
101
+    glTexCoord2f((float)(texCoordX+texCoordWidth)/textureWidth, (float)(texCoordY+texCoordHeight)/textureHeight); glVertex2i(x+screenWidth, y+screenHeight);
102
+    glTexCoord2f((float)(texCoordX+texCoordWidth)/textureWidth, (float)texCoordY/textureHeight); glVertex2i(x+screenWidth, y);
103
+    glEnd();
62 104
 }
63 105
 
64 106
 void MenuState::update(int elapsedTicks)

+ 14
- 5
src/texture.cpp View File

@@ -62,7 +62,7 @@ Texture::Texture(int width, int height, int components, unsigned char *pixels)
62 62
 
63 63
 Texture::~Texture()
64 64
 {
65
-    if(m_textureId > 0)
65
+    if(m_textureId)
66 66
         glDeleteTextures(1, &m_textureId);
67 67
 }
68 68
 
@@ -73,14 +73,23 @@ void Texture::bind()
73 73
 
74 74
 void Texture::enableBilinearFilter()
75 75
 {
76
-    bind();
76
+    glBindTexture(GL_TEXTURE_2D, m_textureId);
77 77
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
78 78
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
79 79
 }
80 80
 
81
-void Texture::copyFromScreen(int xoffset, int yoffset, int x, int y, int width, int height)
81
+void Texture::draw(int x, int y)
82 82
 {
83
-    bind();
84
-    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
83
+    draw(x, y, m_width, m_height);
85 84
 }
86 85
 
86
+void Texture::draw(int x, int y, int width, int height)
87
+{
88
+    glBindTexture(GL_TEXTURE_2D, m_textureId);
89
+    glBegin(GL_QUADS);
90
+    glTexCoord2i(0, 0); glVertex2i(x,       y);
91
+    glTexCoord2i(0, 1); glVertex2i(x,       y+height);
92
+    glTexCoord2i(1, 1); glVertex2i(x+width, y+height);
93
+    glTexCoord2i(1, 0); glVertex2i(x+width, y);
94
+    glEnd();
95
+}

+ 2
- 3
src/texture.h View File

@@ -43,12 +43,11 @@ public:
43 43
     /// Enable texture bilinear filter (smooth scaled textures)
44 44
     void enableBilinearFilter();
45 45
 
46
-    /// Copy screen pixels to texture
47
-    void copyFromScreen(int xoffset, int yoffset, int x, int y, int width, int height);
46
+    void draw(int x, int y);
47
+    void draw(int x, int y, int width, int height);
48 48
 
49 49
     int getWidth() const { return m_width; }
50 50
     int getHeight() const { return m_height; }
51
-    GLuint getTextureId() const { return m_textureId; }
52 51
 
53 52
 private:
54 53
     GLuint m_textureId;

Loading…
Cancel
Save