|
From: Lasse Kärkkäi. <tr...@us...> - 2011-02-06 20:14:12
|
Module: performous
Branch: opengl2
Commit: 8186733b5fdd1f1c925634cb338ec66a6ba16c17
Author: Lasse Karkkainen <tro...@tr...>
Date: Sun Feb 6 21:12:35 2011 +0100
3D composition optimization and fixes
* Viewports now properly positioned in cropped (overwide/overtall) modes too
* FBOs rendered in final resolution (1:1 pixel mapping)
* FBOs have depth buffers
---
game/fbo.hh | 14 ++++++++++----
game/video_driver.cc | 38 ++++++++++++++++++++++++++------------
2 files changed, 36 insertions(+), 16 deletions(-)
diff --git a/game/fbo.hh b/game/fbo.hh
index f511a99..f980faa 100644
--- a/game/fbo.hh
+++ b/game/fbo.hh
@@ -5,19 +5,24 @@
#include "video_driver.hh"
/// Frame Buffer Object class
-class FBO: public boost::noncopyable {
+class FBO: boost::noncopyable {
public:
/// Generate the FBO and attach a fresh texture to it
- FBO(): m_texture() {
+ FBO(unsigned w, unsigned h) {
{
UseTexture tex(m_texture);
- glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, screenW(), screenH(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ }
+ {
+ UseTexture tex(m_depth);
+ glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_DEPTH_COMPONENT24, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
}
// Create FBO
glGenFramebuffersEXT(1, &m_fbo);
// Bind texture as COLOR_ATTACHMENT0
bind();
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE, m_texture.id(), 0);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, m_texture.id(), 0);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_RECTANGLE, m_depth.id(), 0);
unbind();
}
/// Handle clean-up
@@ -40,6 +45,7 @@ class FBO: public boost::noncopyable {
private:
GLuint m_fbo;
OpenGLTexture<GL_TEXTURE_RECTANGLE> m_texture;
+ OpenGLTexture<GL_TEXTURE_RECTANGLE> m_depth;
};
/// RAII FBO binder
diff --git a/game/video_driver.cc b/game/video_driver.cc
index 5585ccc..a766a49 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -92,28 +92,42 @@ void Window::blank() {
}
void Window::render(boost::function<void (void)> drawFunc) {
+ if (s_width < screen->w || s_height < screen->h) glClear(GL_COLOR_BUFFER_BIT); // Black bars
bool stereo = config["graphic/stereo3d"].b();
int type = config["graphic/stereo3dtype"].i();
if (type == 2 && !m_fullscreen) stereo = false; // Over/under only in full screen mode
- // Viewport parameters (defaults)
- double vx = 0.5f * (screen->w - s_width);
- double vy = 0.5f * (screen->h - s_height);
- double vw = s_width, vh = s_height;
- glViewport(vx, vy, vw, vh);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (!stereo) {
+ double vx = 0.5f * (screen->w - s_width);
+ double vy = 0.5f * (screen->h - s_height);
+ double vw = s_width, vh = s_height;
+ glViewport(vx, vy, vw, vh); // Drawable area of the window (excluding black bars)
view(0);
drawFunc();
return;
}
// Render each eye to FBO
- FBO fbo[2];
+ unsigned w = s_width;
+ unsigned h = s_height;
+ if (type == 2) h /= 2; // Half-height mode
+ FBO fboleft(w, h), fboright(w, h);
+ FBO* fbo[] = { &fboleft, &fboright };
for (unsigned i = 0; i < 2; ++i) {
- UseFBO user(fbo[i]);
+ UseFBO user(*fbo[i]);
+ glViewport(0, 0, w, h); // Full FBO
view(i);
drawFunc();
}
// Render to actual framebuffer from FBOs
+ glViewport(0, 0, screen->w, screen->h); // Entire window
+ {
+ // Use normalized eye coordinates for composition
+ using namespace glmath;
+ glMatrixMode(GL_PROJECTION);
+ upload(Matrix());
+ glMatrixMode(GL_MODELVIEW);
+ upload(Matrix());
+ }
glDisable(GL_BLEND);
Shader& sh = shader("surface");
glmath::Matrix colorMatrix;
@@ -142,14 +156,14 @@ void Window::render(boost::function<void (void)> drawFunc) {
glBlendFunc(GL_ONE, GL_ONE);
}
sh.bind();
- } else if (type == 2) { // Over/under
- double margin = screen->h - s_height;
- glViewport(vx, 0.25 * margin + (num ? 0.0 : 0.5 * screen->h), vw, 0.5 * vh);
}
{
- UseTexture use(fbo[num].getTexture());
+ // Render FBO with 1:1 pixels, properly filtered/positioned for 3d
+ UseTexture use(fbo[num]->getTexture());
sh.setUniformMatrix("colorMatrix", colorMatrix);
- fbo[num].getTexture().draw(Dimensions().stretch(1.0, virtH()), TexCoords(0.0, screenH(), screenW(), 0.0));
+ Dimensions dim = Dimensions().stretch(2.0 * w / screen->w, 2.0 * h / screen->h);
+ if (type == 2) dim.center(num == 0 ? 0.5 : -0.5);
+ fbo[num]->getTexture().draw(dim, TexCoords(0.0, 0.0, w, h));
sh.setUniformMatrix("colorMatrix", glmath::Matrix());
}
}
|