Anaglyph and horizontal interlacing are supported.
No settings (change in Globals.cpp for now)
#include "binio.h"
#include <fstream>
#include "gamegl.h"
+#include "Stereo.h"
extern GLuint rabbittexture;
void LoadingScreen();
void FadeLoadingScreen(float howmuch);
void Dispose();
- int DrawGLScene(void);
+ int DrawGLScene(StereoSide side);
void Tick();
void TickOnce();
void TickOnceAfter();
//return 1111111111111111;
}
-int Game::DrawGLScene(void)
+int Game::DrawGLScene(StereoSide side)
{
static float texcoordwidth,texcoordheight;
static float texviewwidth, texviewheight;
lastcheck+=multiplier;
- glColorMask( 1.0, 1.0, 1.0, 1.0 );
-
+ if ( stereomode == stereoAnaglyph ) {
+ switch(side) {
+ case stereoLeft: glColorMask( 1.0, 0.0, 0.0, 1.0 ); break;
+ case stereoRight: glColorMask( 0.0, 1.0, 1.0, 1.0 ); break;
+ }
+ } else {
+ glColorMask( 1.0, 1.0, 1.0, 1.0 );
+
+ if ( stereomode == stereoHorizontalInterlaced || stereomode == stereoVerticalInterlaced ) {
+ if (!stereoreverse) {
+ glStencilFunc(side == stereoLeft ? GL_NOTEQUAL : GL_EQUAL, 0x01, 0x01);
+ } else {
+ glStencilFunc(side == stereoLeft ? GL_EQUAL : GL_NOTEQUAL, 0x01, 0x01);
+ }
+ }
+ }
if(freeze||winfreeze||(mainmenu&&gameon)||(!gameon&&gamestarted)){
tempmult=multiplier;
glMatrixMode (GL_MODELVIEW);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glLoadIdentity ();
+
+ glTranslatef((stereoseparation/2) * side, 0, 0);
+
if(!cameramode&&!freeze&&!winfreeze){
glRotatef(float(Random()%100)/10*camerashake/*+(woozy*woozy)/10*/,0,0,1);
glRotatef(rotation2+sin(woozy/2)*(player[0].damage/player[0].damagetolerance)*5,1,0,0);
//glFlush();
- if(drawmode!=motionblurmode||mainmenu){
-
- swap_gl_buffers();
- }
+ if ( side == stereoRight || side == stereoCenter ) {
+ if(drawmode!=motionblurmode||mainmenu){
+ swap_gl_buffers();
+ }
+ }
//myassert(glGetError() == GL_NO_ERROR);
glDrawBuffer(GL_BACK);
static bool mainmenutogglekeydown;
+
+ if (IsKeyDown(theKeyMap, MAC_F6_KEY) && !freezetogglekeydown) {
+ if (IsKeyDown(theKeyMap, MAC_SHIFT_KEY)) {
+ stereoreverse=true;
+ } else {
+ stereoreverse=false;
+ }
+
+ if (stereoreverse) {
+ printf("Stereo reversed\n");
+ } else {
+ printf("Stereo unreversed\n");
+ }
+ freezetogglekeydown=1;
+ }
+
+ if (IsKeyDown(theKeyMap, MAC_F7_KEY)) {
+ if (IsKeyDown(theKeyMap, MAC_SHIFT_KEY)) {
+ stereoseparation -= 0.001;
+ } else {
+ stereoseparation -= 0.010;
+ }
+
+ printf("Stereo decreased increased to %f\n", stereoseparation);
+ }
+
+ if (IsKeyDown(theKeyMap, MAC_F8_KEY)) {
+ if (IsKeyDown(theKeyMap, MAC_SHIFT_KEY)) {
+ stereoseparation += 0.001;
+ } else {
+ stereoseparation += 0.010;
+ }
+
+ printf("Stereo separation increased to %f\n", stereoseparation);
+ }
+
+
if(!console){
if(mainmenu&&endgame==1)mainmenu=10;
if(IsKeyDown(theKeyMap, MAC_ESCAPE_KEY)&&!mainmenutogglekeydown&&(mainmenu==7&&entername)){
#include "Person.h"
#include "TGALoader.h"
#include "openal_wrapper.h"
+#include "Stereo.h"
#include "Constants.h"
//TextureList textures;
+StereoMode stereomode = stereoHorizontalInterlaced;
+float stereoseparation = 0.05;
+bool stereoreverse = false;
\ No newline at end of file
void DrawGL (Game & game)
{
- game.DrawGLScene();
+ if ( stereomode == stereoNone ) {
+ game.DrawGLScene(stereoCenter);
+ } else {
+ game.DrawGLScene(stereoLeft);
+ game.DrawGLScene(stereoRight);
+ }
}
SDL_ShowCursor(0);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
+
if (SDL_SetVideoMode(kContextWidth, kContextHeight, 0, sdlflags) == NULL)
{
fprintf(stderr, "SDL_SetVideoMode() failed: %s\n", SDL_GetError());
glDisable( GL_FOG);
glDisable( GL_LIGHTING);
glDisable( GL_LOGIC_OP);
- glDisable( GL_STENCIL_TEST);
glDisable( GL_TEXTURE_1D);
glDisable( GL_TEXTURE_2D);
glPixelTransferi( GL_MAP_COLOR, GL_FALSE);
game.newscreenwidth=screenwidth;
game.newscreenheight=screenheight;
+ GLint stencilbits = 0;
+ glGetIntegerv(GL_STENCIL_BITS, &stencilbits);
+ if ( stencilbits < 1 ) {
+ fprintf(stderr, "Failed to get a stencil buffer!\n");
+ SDL_Quit();
+ return false;
+ }
+
+ fprintf(stderr, "Stencil buffer has %i bits, good.\n", stencilbits);
+ fprintf(stderr, "Screen width is %i, height is %i\n", kContextWidth, kContextHeight);
+
+ glEnable( GL_STENCIL_TEST);
+ glClearStencil(0);
+ glClear( GL_STENCIL_BUFFER_BIT );
+ glStencilFunc(GL_ALWAYS, 0x1, 0x1);
+ glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 3);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glColorMask( 1.0, 1.0, 1.0, 1.0 );
+ char stencil[] = {64,127,255};
+
+ glViewport(0,0, kContextWidth, kContextHeight);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho((GLdouble)0, (GLdouble)kContextWidth, (GLdouble)kContextHeight, 0, -1, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ for(int y=0;y<kContextHeight;y+=2) {
+
+ for(int x=0;x<kContextWidth;x++) {
+ glRasterPos2i(x, y);
+ glDrawPixels(1, 1, GL_RGB, GL_UNSIGNED_BYTE, &stencil);
+ }
+ }
+
+ glStencilFunc(GL_NOTEQUAL, 0x01, 0x01);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+ // Something gets screwed up due to the changes above
+ // revert to default.
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+
game.InitGame();
return true;
--- /dev/null
+
+#ifndef STEREO_H_
+#define STEREO_H_
+
+enum StereoMode {
+ stereoNone,
+ stereoAnaglyph, /* red/cyan */
+ stereoHorizontalInterlaced, /* some 3D monitors */
+ stereoVerticalInterlaced,
+ stereoHorizontalSplit, /* cross-eyed view */
+ stereoVerticalSplit,
+ stereoOpenGL, /* Whatever OpenGL does, if supported */
+ stereoCount /* must be last element */
+};
+
+
+enum StereoSide {
+ // Code multiplies by StereoSide to calculate camera offsets
+ stereoLeft = -1,
+ stereoCenter = 0,
+ stereoRight = 1
+};
+
+extern StereoMode stereomode;
+extern float stereoseparation;
+extern bool stereoreverse;
+
+#endif
\ No newline at end of file