FBO working as expected, render background on menu state
This commit is contained in:
parent
4b2886ebec
commit
4102ae093c
|
@ -68,6 +68,8 @@ void Engine::init()
|
|||
|
||||
void Engine::terminate()
|
||||
{
|
||||
changeState(NULL);
|
||||
|
||||
// save configs
|
||||
g_config.setValue("width", Platform::getWindowWidth());
|
||||
g_config.setValue("height", Platform::getWindowHeight());
|
||||
|
|
|
@ -24,25 +24,31 @@
|
|||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include "framebuffer.h"
|
||||
#include "platform.h"
|
||||
#include "graphics.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glu.h>
|
||||
#include "platform.h"
|
||||
#include "graphics.h"
|
||||
|
||||
FrameBuffer::FrameBuffer(int width, int height) :
|
||||
m_fbo(0)
|
||||
FrameBuffer::FrameBuffer(int width, int height)
|
||||
{
|
||||
m_fbo = 0;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
|
||||
// texture where the framebuffer will be store
|
||||
m_frameTexture = TexturePtr(new Texture(width, height, 4));
|
||||
// create FBO texture
|
||||
glGenTextures(1, &m_fboTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// we want a smooth framebuffer
|
||||
m_frameTexture->enableBilinearFilter();
|
||||
// we want bilinear filtering (for a smooth framebuffer)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
// use FBO only if supported
|
||||
// use FBO ext only if supported
|
||||
if(Platform::isExtensionSupported("EXT_framebuffer_object")) {
|
||||
m_fallbackOldImp = false;
|
||||
|
||||
|
@ -51,18 +57,14 @@ FrameBuffer::FrameBuffer(int width, int height) :
|
|||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||
|
||||
// attach 2D texture to this FBO
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_frameTexture->getTextureId(), 0);
|
||||
|
||||
// must be called before checking
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_fboTexture, 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
switch(status) {
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
//ok
|
||||
break;
|
||||
default:
|
||||
default: // fallback to old implementation
|
||||
m_fallbackOldImp = true;
|
||||
break;
|
||||
}
|
||||
|
@ -74,6 +76,7 @@ FrameBuffer::FrameBuffer(int width, int height) :
|
|||
|
||||
FrameBuffer::~FrameBuffer()
|
||||
{
|
||||
glDeleteTextures(1, &m_fboTexture);
|
||||
if(m_fbo)
|
||||
glDeleteFramebuffersEXT(1, &m_fbo);
|
||||
}
|
||||
|
@ -83,18 +86,21 @@ void FrameBuffer::bind()
|
|||
if(!m_fallbackOldImp) {
|
||||
// bind framebuffer
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||
|
||||
// must be called before rendering to framebuffer
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
}
|
||||
|
||||
// setup framebuffer viewport
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0.0f, m_width, 0, m_height);
|
||||
|
||||
// back to model view
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
// clear framebuffer
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// setup framebuffer viewport
|
||||
g_graphics.setViewport(m_width, m_height);
|
||||
}
|
||||
|
||||
void FrameBuffer::unbind()
|
||||
|
@ -102,19 +108,32 @@ void FrameBuffer::unbind()
|
|||
if(!m_fallbackOldImp) {
|
||||
// bind back buffer again
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
// must be called to render to back buffer again
|
||||
glDrawBuffer(GL_BACK);
|
||||
glReadBuffer(GL_BACK);
|
||||
} else {
|
||||
// copy screen to texture
|
||||
m_frameTexture->copyFromScreen(0, 0, 0, 0, m_width, m_height);
|
||||
|
||||
// clear screen
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
// restore graphics viewport
|
||||
g_graphics.restoreViewport();
|
||||
} else {
|
||||
// copy screen to texture
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboTexture);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
||||
|
||||
// restore graphics viewport
|
||||
g_graphics.restoreViewport();
|
||||
|
||||
// clear screen
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBuffer::draw(int x, int y, int width, int height)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, m_fboTexture);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2i(0, 0); glVertex2i(x, y);
|
||||
glTexCoord2i(0, 1); glVertex2i(x, y+height);
|
||||
glTexCoord2i(1, 1); glVertex2i(x+width, y+height);
|
||||
glTexCoord2i(1, 0); glVertex2i(x+width, y);
|
||||
glEnd();
|
||||
}
|
||||
|
|
|
@ -25,24 +25,25 @@
|
|||
#ifndef FRAMEBUFFER_H
|
||||
#define FRAMEBUFFER_H
|
||||
|
||||
#include "texture.h"
|
||||
#include <GL/gl.h>
|
||||
|
||||
class FrameBuffer
|
||||
{
|
||||
public:
|
||||
FrameBuffer(int width, int height);
|
||||
virtual ~FrameBuffer();
|
||||
|
||||
/// Return the texture where everything was drawn
|
||||
TexturePtr getFramebufferTexture();
|
||||
|
||||
/// Bind the framebuffer, everything rendered will be draw on it
|
||||
void bind();
|
||||
|
||||
/// Unbind the framebuffer, render on back buffer again
|
||||
void unbind();
|
||||
|
||||
/// Draw framebuffer
|
||||
void draw(int x, int y, int width, int height);
|
||||
|
||||
private:
|
||||
TexturePtr m_frameTexture;
|
||||
GLuint m_fboTexture;
|
||||
GLuint m_fbo;
|
||||
bool m_fallbackOldImp;
|
||||
int m_width;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "texture.h"
|
||||
|
||||
Graphics g_graphics;
|
||||
|
||||
|
@ -43,10 +44,10 @@ Graphics::~Graphics()
|
|||
void Graphics::init()
|
||||
{
|
||||
// setup opengl
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // black background
|
||||
glEnable(GL_ALPHA_TEST); // enable alpha
|
||||
glEnable(GL_ALPHA_TEST); // enable alpha by default
|
||||
glAlphaFunc(GL_GREATER, 0.0f); // default alpha mode
|
||||
glDisable(GL_DEPTH_TEST); // we are rendering 2D only, we don't need it
|
||||
glEnable(GL_TEXTURE_2D); // enable textures by default
|
||||
|
||||
notice("GPU %s", (const char*)glGetString(GL_RENDERER));
|
||||
notice("OpenGL %s", (const char*)glGetString(GL_VERSION));
|
||||
|
@ -64,13 +65,13 @@ void Graphics::resize(int width, int height)
|
|||
restoreViewport();
|
||||
}
|
||||
|
||||
void Graphics::setViewport(int width, int height)
|
||||
void Graphics::restoreViewport()
|
||||
{
|
||||
// resize gl viewport
|
||||
glViewport(0, 0, width, height);
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
|
||||
/*
|
||||
0 ,0---------0,w**
|
||||
0,0---------0,w
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
|
@ -79,7 +80,7 @@ void Graphics::setViewport(int width, int height)
|
|||
// setup view region like above
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0.0f, width, height, 0.0f);
|
||||
gluOrtho2D(0.0f, m_width, m_height, 0.0f);
|
||||
|
||||
// back to model view
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
@ -88,6 +89,7 @@ void Graphics::setViewport(int width, int height)
|
|||
|
||||
void Graphics::beginRender()
|
||||
{
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#ifndef GRAPHICS_H
|
||||
#define GRAPHICS_H
|
||||
|
||||
class Texture;
|
||||
|
||||
class Graphics
|
||||
{
|
||||
public:
|
||||
|
@ -37,18 +39,15 @@ public:
|
|||
/// Called after every window resize
|
||||
void resize(int width, int height);
|
||||
|
||||
/// Restore original viewport
|
||||
void restoreViewport();
|
||||
|
||||
/// Called before every render
|
||||
void beginRender();
|
||||
|
||||
/// Called after every render
|
||||
void endRender();
|
||||
|
||||
/// Restore original viewport
|
||||
void restoreViewport() { setViewport(m_width, m_height); }
|
||||
|
||||
/// Set viewport, used by FrameBuffer
|
||||
void setViewport(int width, int height);
|
||||
|
||||
int getWidth() { return m_width; }
|
||||
int getHeight() { return m_height; }
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ int main(int argc, const char *argv[])
|
|||
g_resources.init(argv[0]);
|
||||
if(g_resources.setWriteDir(Platform::getAppUserDir()))
|
||||
g_resources.addToSearchPath(Platform::getAppUserDir());
|
||||
g_resources.addToSearchPath("data");
|
||||
|
||||
// before loading configurations set the default ones
|
||||
setDefaultConfigs();
|
||||
|
|
|
@ -26,9 +26,15 @@
|
|||
#include "framebuffer.h"
|
||||
#include "graphics.h"
|
||||
#include "texturemanager.h"
|
||||
#include "logger.h"
|
||||
#include "engine.h"
|
||||
|
||||
FrameBuffer *fbo;
|
||||
TexturePtr background;
|
||||
|
||||
MenuState::MenuState()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MenuState::~MenuState()
|
||||
|
@ -38,7 +44,8 @@ MenuState::~MenuState()
|
|||
|
||||
void MenuState::onEnter()
|
||||
{
|
||||
|
||||
background = g_textures.get("background.png");
|
||||
background->enableBilinearFilter();
|
||||
}
|
||||
|
||||
void MenuState::onLeave()
|
||||
|
@ -48,17 +55,52 @@ void MenuState::onLeave()
|
|||
|
||||
void MenuState::onClose()
|
||||
{
|
||||
|
||||
g_engine.stop();
|
||||
}
|
||||
|
||||
void MenuState::onInputEvent(InputEvent* event)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MenuState::render()
|
||||
{
|
||||
// draw background
|
||||
background->bind();
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int screenWidth = g_graphics.getWidth();
|
||||
int screenHeight = g_graphics.getHeight();
|
||||
int textureWidth = background->getWidth();
|
||||
int textureHeight = background->getHeight();
|
||||
|
||||
int texCoordX;
|
||||
int texCoordY;
|
||||
int texCoordWidth;
|
||||
int texCoordHeight;
|
||||
|
||||
int wantedWidth = 1240;
|
||||
int wantedHeight = 880;
|
||||
|
||||
float originalRatio = (float)wantedWidth/wantedHeight;
|
||||
float screenRatio = (float)screenWidth/screenHeight;
|
||||
if(screenRatio >= originalRatio) {
|
||||
texCoordHeight = wantedHeight;
|
||||
texCoordWidth = std::min((int)(wantedHeight*screenRatio), textureWidth);
|
||||
} else {
|
||||
texCoordWidth = wantedWidth;
|
||||
texCoordHeight = std::min((int)(wantedWidth/screenRatio), textureHeight);
|
||||
}
|
||||
texCoordX = textureWidth - texCoordWidth;
|
||||
texCoordY = textureHeight - texCoordHeight;
|
||||
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f((float)texCoordX/textureWidth, (float)texCoordY/textureHeight); glVertex2i(x, y);
|
||||
glTexCoord2f((float)texCoordX/textureWidth, (float)(texCoordY+texCoordHeight)/textureHeight); glVertex2i(x, y+screenHeight);
|
||||
glTexCoord2f((float)(texCoordX+texCoordWidth)/textureWidth, (float)(texCoordY+texCoordHeight)/textureHeight); glVertex2i(x+screenWidth, y+screenHeight);
|
||||
glTexCoord2f((float)(texCoordX+texCoordWidth)/textureWidth, (float)texCoordY/textureHeight); glVertex2i(x+screenWidth, y);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void MenuState::update(int elapsedTicks)
|
||||
|
|
|
@ -62,7 +62,7 @@ Texture::Texture(int width, int height, int components, unsigned char *pixels)
|
|||
|
||||
Texture::~Texture()
|
||||
{
|
||||
if(m_textureId > 0)
|
||||
if(m_textureId)
|
||||
glDeleteTextures(1, &m_textureId);
|
||||
}
|
||||
|
||||
|
@ -73,14 +73,23 @@ void Texture::bind()
|
|||
|
||||
void Texture::enableBilinearFilter()
|
||||
{
|
||||
bind();
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureId);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
void Texture::copyFromScreen(int xoffset, int yoffset, int x, int y, int width, int height)
|
||||
void Texture::draw(int x, int y)
|
||||
{
|
||||
bind();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
|
||||
draw(x, y, m_width, m_height);
|
||||
}
|
||||
|
||||
void Texture::draw(int x, int y, int width, int height)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureId);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2i(0, 0); glVertex2i(x, y);
|
||||
glTexCoord2i(0, 1); glVertex2i(x, y+height);
|
||||
glTexCoord2i(1, 1); glVertex2i(x+width, y+height);
|
||||
glTexCoord2i(1, 0); glVertex2i(x+width, y);
|
||||
glEnd();
|
||||
}
|
||||
|
|
|
@ -43,12 +43,11 @@ public:
|
|||
/// Enable texture bilinear filter (smooth scaled textures)
|
||||
void enableBilinearFilter();
|
||||
|
||||
/// Copy screen pixels to texture
|
||||
void copyFromScreen(int xoffset, int yoffset, int x, int y, int width, int height);
|
||||
void draw(int x, int y);
|
||||
void draw(int x, int y, int width, int height);
|
||||
|
||||
int getWidth() const { return m_width; }
|
||||
int getHeight() const { return m_height; }
|
||||
GLuint getTextureId() const { return m_textureId; }
|
||||
|
||||
private:
|
||||
GLuint m_textureId;
|
||||
|
|
Loading…
Reference in New Issue