|
From: Lasse Kärkkäi. <tr...@us...> - 2011-01-27 00:39:56
|
Module: performous
Branch: stereo3d
Commit: 29518a18b84b24de4d2d0606db42fa4f8e07f472
Author: Lasse Karkkainen <tro...@tr...>
Date: Thu Jan 27 01:39:42 2011 +0100
Added Window::view() for setting up different views (e.g. stereoscopic). Made stereo3d configurable and made it adapt to window size instead of hardcoded FullHD.
---
data/schema.xml | 21 ++++++++++++++++
game/screenmanager.cc | 21 +---------------
game/video_driver.cc | 62 ++++++++++++++++++++++++++++++++++++------------
game/video_driver.hh | 4 +++
4 files changed, 73 insertions(+), 35 deletions(-)
diff --git a/data/schema.xml b/data/schema.xml
index 3f05b12..ab20020 100644
--- a/data/schema.xml
+++ b/data/schema.xml
@@ -125,6 +125,27 @@ to save the current settings to XML.
<long>Enable fullscreen mode on startup.</long>
</locale>
</entry>
+ <entry name="graphic/stereo3d" type="bool" value="false">
+ <locale name="C">
+ <short>Stereoscopic 3D</short>
+ <long>Enable 3D rendering of Performous.</long>
+ </locale>
+ </entry>
+ <entry name="graphic/stereo3dtype" type="int" value="0">
+ <limits min="0" max="1" step="1" />
+ <locale name="C">
+ <short>Stereo3D type</short>
+ <long>Some modes may only be activated in FullHD mode. 0 = red/cyan, 1 = over/under.</long>
+ </locale>
+ </entry>
+ <entry name="graphic/stereo3dseparation" type="float" value="50">
+ <ui unit=" %" />
+ <limits min="0" max="100" step="1" />
+ <locale name="C">
+ <short>Stereo3D separation</short>
+ <long>The strenght of the effect. Experiment with different settings for best results.</long>
+ </locale>
+ </entry>
<entry name="graphic/video" type="bool" value="true">
<locale name="C">
<short>Video playback</short>
diff --git a/game/screenmanager.cc b/game/screenmanager.cc
index e28dc19..7b3e057 100644
--- a/game/screenmanager.cc
+++ b/game/screenmanager.cc
@@ -42,28 +42,11 @@ Screen* ScreenManager::getScreen(std::string const& name) {
}
void ScreenManager::drawScreen() {
- // FIXME: Rendering using FBO doesn't work
- {
- glViewport(0, 0, 1920, 540);
- glutil::PushMatrixMode pp(GL_PROJECTION);
- glTranslatef(0.02f, 0.0f, 0.0f);
- glutil::PushMatrixMode pmv(GL_MODELVIEW);
- glTranslatef(-0.02f, 0.0f, 0.0f);
- //UseFBO fbo(m_fbo);
+ // Draw current frame for all the views
+ for (unsigned i = 0; window().view(i); ++i) {
getCurrentScreen()->draw();
drawNotifications();
}
- {
- glViewport(0, 540, 1920, 540);
- glutil::PushMatrixMode pp(GL_PROJECTION);
- glTranslatef(-0.02f, 0.0f, 0.0f);
- glutil::PushMatrixMode pmv(GL_MODELVIEW);
- glTranslatef(0.02f, 0.0f, 0.0f);
- //UseFBO fbo(m_fbo);
- getCurrentScreen()->draw();
- drawNotifications();
- }
- //m_fbo.getTexture().draw(Dimensions().fixedWidth(1.0));
}
diff --git a/game/video_driver.cc b/game/video_driver.cc
index 54f677b..ecd05d4 100644
--- a/game/video_driver.cc
+++ b/game/video_driver.cc
@@ -75,6 +75,52 @@ void Window::blank() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
+bool Window::view(unsigned num) {
+ // Setup the projection matrix for 2D translates
+ using namespace glmath;
+ glMatrixMode(GL_PROJECTION);
+ float h = virtH();
+ // OpenGL normalized coordinates go from -1 to 1, change scale so that our 2D translates can use the Performous normalized coordinates instead
+ upload(scale(Vec3(2.0f, 2.0f / h, 1.0f)));
+ // Note: we do the frustum on MODELVIEW so that 2D positioning can be done via projection matrix.
+ // glTranslatef on that will move the image, not the camera (i.e. far-away and nearby objects move the same amount)
+ glMatrixMode(GL_MODELVIEW);
+ const float f = near_ / z0;
+ upload(
+ scale(Vec3(0.5, 0.5 * h, 1.0))
+ * frustum(-0.5f * f, 0.5f * f, 0.5f * h * f, -0.5f * h * f, near_, far_)
+ * translate(Vec3(0.0, 0.0, -z0))
+ );
+ // Setup views
+ bool stereo = config["graphic/stereo3d"].b();
+ int type = config["graphic/stereo3dtype"].i();
+ if (type == 1 && !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;
+ if (stereo) {
+ if (num > 1) return false;
+ double separation = 0.0004f * (num ? -1 : 1) * config["graphic/stereo3dseparation"].f();
+ glMatrixMode(GL_PROJECTION);
+ glTranslatef(separation, 0.0f, 0.0f);
+ glMatrixMode(GL_MODELVIEW);
+ glTranslatef(-separation, 0.0f, 0.0f);
+ if (type == 0) {
+ // TODO: implement color shaders for red/cyan
+ }
+ if (type == 1) {
+ double margin = screen->h - s_height;
+ vy = 0.25 * margin + (num ? 0.5 * screen->h : 0.0);
+ vh *= 0.5;
+ }
+ } else {
+ if (num != 0) return false;
+ }
+ glViewport(vx, vy, vw, vh);
+ return true;
+}
+
void Window::swap() {
SDL_GL_SwapBuffers();
}
@@ -133,7 +179,6 @@ void Window::resize() {
}
if (s_height < 0.56f * s_width) s_width = round(s_height / 0.56f);
if (s_height > 0.8f * s_width) s_height = round(0.8f * s_width);
- glViewport(0.5f * (screen->w - s_width), 0.5f * (screen->h - s_height), s_width, s_height);
// Set flags
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
glDisable(GL_DEPTH_TEST);
@@ -142,21 +187,6 @@ void Window::resize() {
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
- // Setup the projection matrix for 2D translates
- using namespace glmath;
- glMatrixMode(GL_PROJECTION);
- float h = virtH();
- // OpenGL normalized coordinates go from -1 to 1, change scale so that our 2D translates can use the Performous normalized coordinates instead
- upload(scale(Vec3(2.0f, 2.0f / h, 1.0f)));
- // Note: we do the frustum on MODELVIEW so that 2D positioning can be done via projection matrix.
- // glTranslatef on that will move the image, not the camera (i.e. far-away and nearby objects move the same amount)
- glMatrixMode(GL_MODELVIEW);
- const float f = near_ / z0;
- upload(
- scale(Vec3(0.5, 0.5 * h, 1.0))
- * frustum(-0.5f * f, 0.5f * f, 0.5f * h * f, -0.5f * h * f, near_, far_)
- * translate(Vec3(0.0, 0.0, -z0))
- );
// Check for OpenGL errors
glutil::GLErrorChecker glerror("Window::resize");
}
diff --git a/game/video_driver.hh b/game/video_driver.hh
index 131c3ef..37f9f38 100644
--- a/game/video_driver.hh
+++ b/game/video_driver.hh
@@ -25,6 +25,10 @@ public:
Window(unsigned int windowW, unsigned int windowH, bool fullscreen);
/// destructor
~Window();
+ /// Setup everything for drawing a view.
+ /// @param num should be 0 the first time each frame then incremented for each additional view
+ /// @returns true if the view should be rendered, false if no more views are available
+ bool view(unsigned num);
/// clears window
void blank();
/// swaps buffers
|