|
From: Lasse Kärkkäi. <tr...@us...> - 2011-02-08 09:22:21
|
Module: performous
Branch: opengl2
Commit: 44e634659198a7dd8834eaac9881c01554d9de01
Author: Lasse Karkkainen <tro...@tr...>
Date: Tue Feb 8 10:22:09 2011 +0100
Geometry shader stereo rendering, still has issues.
---
game/glmath.hh | 5 ++++
game/video_driver.cc | 43 ++++++++++++++++++++++++---------
game/video_driver.hh | 2 +
themes/default/shaders/core.frag | 13 ++++++----
themes/default/shaders/stereo3d.geom | 37 +++++++++++++++++++++++++++++
5 files changed, 83 insertions(+), 17 deletions(-)
diff --git a/game/glmath.hh b/game/glmath.hh
index 675a3cf..9177f01 100644
--- a/game/glmath.hh
+++ b/game/glmath.hh
@@ -32,6 +32,11 @@ namespace glmath {
static inline Vec3 normalize(Vec3 const& v) { return (1 / len(v)) * v; }
struct Matrix {
+ static Matrix zero() {
+ Matrix ret;
+ ret(0,0) = ret(1,1) = ret(2,2) = ret(3,3) = 0.0;
+ return ret;
+ }
Vec4 cols[4];
/// Identity matrix
Matrix() { for (unsigned k = 0; k < 4; ++k) cols[k][k] = 1.0; }
diff --git a/game/video_driver.cc b/game/video_driver.cc
index e7e0a71..5598ee5 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -73,25 +73,28 @@ Window::Window(unsigned int width, unsigned int height, bool fs): m_windowW(widt
input::SDL::init(); // Joysticks etc.
shader("surface")
.compileFile(getThemePath("shaders/core.vert"))
+ .compileFile(getThemePath("shaders/stereo3d.geom"))
.compileFile(getThemePath("shaders/core.frag"), "#define SURFACE\n")
.link()
.bind()
.setUniformMatrix("colorMatrix", glmath::Matrix());
shader("texture")
.compileFile(getThemePath("shaders/core.vert"))
+ .compileFile(getThemePath("shaders/stereo3d.geom"))
.compileFile(getThemePath("shaders/core.frag"), "#define TEXTURE\n")
.link()
.bind()
.setUniformMatrix("colorMatrix", glmath::Matrix());
shader("3dobject")
.compileFile(getThemePath("shaders/3dobject.vert"))
+ .compileFile(getThemePath("shaders/stereo3d.geom"))
.compileFile(getThemePath("shaders/3dobject.frag"))
.link();
shader("dancenote")
.compileFile(getThemePath("shaders/dancenote.vert"))
+ .compileFile(getThemePath("shaders/stereo3d.geom"))
.compileFile(getThemePath("shaders/dancenote.frag"))
.link();
-
double vx = 0.5f * (screen->w - s_width);
double vy = 0.5f * (screen->h - s_height);
double vw = s_width, vh = s_height;
@@ -105,6 +108,15 @@ void Window::blank() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
+void Window::updateStereo(glmath::Matrix const& left, glmath::Matrix const& right) {
+ for (ShaderMap::iterator it = m_shaders.begin(); it != m_shaders.end(); ++it) {
+ Shader& sh = *it->second;
+ sh.bind();
+ sh.setUniformMatrix("leftTransform", left);
+ sh.setUniformMatrix("rightTransform", right);
+ }
+}
+
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();
@@ -116,21 +128,28 @@ void Window::render(boost::function<void (void)> drawFunc) {
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)
+ updateStereo();
view(0);
drawFunc();
return;
}
- // Render each eye to FBO
+ // Render both eyes to FBO
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]);
- glViewport(0, 0, w, h); // Full FBO
- view(i + 1);
+ if (type < 2) h *= 2; // Full resolution stereo
+ FBO fbo(w, h);
+ {
+ UseFBO user(fbo);
+ glViewportIndexedf(0, 0, 0, w, h / 2);
+ glViewportIndexedf(1, 0, h / 2, w, h / 2);
+ double separation = getSeparation();
+ glmath::Matrix l, r;
+ l(0,3) = -separation; l(0,2) = 0.5 * separation;
+ r(0,3) = separation; r(0,2) = -0.5 * separation;
+ updateStereo(l, r);
+ view(0);
drawFunc();
+ updateStereo();
}
// Render to actual framebuffer from FBOs
glViewport(0, 0, screen->w, screen->h); // Entire window
@@ -173,11 +192,11 @@ void Window::render(boost::function<void (void)> drawFunc) {
}
{
// Render FBO with 1:1 pixels, properly filtered/positioned for 3d
- UseTexture use(fbo[num]->getTexture());
+ UseTexture use(fbo.getTexture());
sh.setUniformMatrix("colorMatrix", colorMatrix);
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));
+ if (type != 2) dim.center((num == 0 ? -0.25 : 0.25) * dim.h());
+ fbo.getTexture().draw(dim, TexCoords(0.0, 0.0, w, h));
sh.setUniformMatrix("colorMatrix", glmath::Matrix());
}
}
diff --git a/game/video_driver.hh b/game/video_driver.hh
index 3546219..0c5040d 100644
--- a/game/video_driver.hh
+++ b/game/video_driver.hh
@@ -1,5 +1,6 @@
#pragma once
+#include "glmath.hh"
#include "glshader.hh"
#include "glutil.hh"
#include <boost/function.hpp>
@@ -56,6 +57,7 @@ private:
/// Setup everything for drawing a view.
/// @param num 0 = no stereo, 1 = left eye, 2 = right eye
void view(unsigned num);
+ void updateStereo(glmath::Matrix const& left = glmath::Matrix(), glmath::Matrix const& right = glmath::Matrix::zero());
SDL_Surface* screen;
unsigned int m_windowW, m_windowH;
unsigned int m_fsW, m_fsH;
diff --git a/themes/default/shaders/core.frag b/themes/default/shaders/core.frag
index 872ac36..8b61013 100644
--- a/themes/default/shaders/core.frag
+++ b/themes/default/shaders/core.frag
@@ -1,10 +1,8 @@
-#version 120
+#version 330
#extension GL_ARB_texture_rectangle : require
//DEFINES
-uniform mat4 colorMatrix;
-
#ifdef SURFACE
uniform sampler2DRect tex;
#define TFUNC texture2DRect
@@ -15,10 +13,15 @@ uniform sampler2D tex;
#define TFUNC texture2D
#endif
+uniform mat4 colorMatrix;
+
+in vec4 color;
+in vec2 texcoord;
+
void main() {
- gl_FragColor = colorMatrix * (gl_Color
+ gl_FragColor = colorMatrix * (color
#ifdef TFUNC
- * TFUNC(tex, gl_TexCoord[0].st).rgba
+ * TFUNC(tex, texcoord).rgba
#endif
);
}
diff --git a/themes/default/shaders/stereo3d.geom b/themes/default/shaders/stereo3d.geom
new file mode 100644
index 0000000..a17d8a4
--- /dev/null
+++ b/themes/default/shaders/stereo3d.geom
@@ -0,0 +1,37 @@
+#version 330 compatibility
+#extension GL_ARB_viewport_array : require
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 6) out;
+
+uniform mat4 leftTransform;
+uniform mat4 rightTransform;
+
+out vec4 color;
+out vec2 texcoord;
+
+void main() {
+ // Fix Nvidia compile warnings ("may be used uninitialized")
+ color = vec4(0);
+ texcoord = vec2(0);
+ gl_Position = vec4(0);
+ // Render the left eye
+ gl_ViewportIndex = 0;
+ for(int i=0; i < gl_in.length(); ++i) {
+ color = gl_in[i].gl_FrontColor;
+ texcoord = gl_in[i].gl_TexCoord[0].st;
+ gl_Position = leftTransform * gl_in[i].gl_Position;
+ EmitVertex();
+ }
+ EndPrimitive();
+ // Render the right eye
+ gl_ViewportIndex = 1;
+ for(int i=0; i < gl_in.length(); ++i) {
+ color = gl_in[i].gl_FrontColor;
+ texcoord = gl_in[i].gl_TexCoord[0].st;
+ gl_Position = rightTransform * gl_in[i].gl_Position;
+ EmitVertex();
+ }
+ EndPrimitive();
+}
+
|