From 3f518d0f8cf5f083bc17732e7b8627cec3639940 Mon Sep 17 00:00:00 2001 From: Vadim Trochinsky Date: Sun, 16 May 2010 05:52:10 +0400 Subject: [PATCH] Initial stereo code. Anaglyph and horizontal interlacing are supported. No settings (change in Globals.cpp for now) --- Source/Game.h | 3 +- Source/GameDraw.cpp | 32 +++++++++++++++----- Source/GameTick.cpp | 37 ++++++++++++++++++++++++ Source/Globals.cpp | 4 +++ Source/OpenGL_Windows.cpp | 61 +++++++++++++++++++++++++++++++++++++-- Source/Stereo.h | 28 ++++++++++++++++++ 6 files changed, 154 insertions(+), 11 deletions(-) create mode 100644 Source/Stereo.h diff --git a/Source/Game.h b/Source/Game.h index bda4324..1297fbd 100644 --- a/Source/Game.h +++ b/Source/Game.h @@ -62,6 +62,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "binio.h" #include #include "gamegl.h" +#include "Stereo.h" extern GLuint rabbittexture; @@ -246,7 +247,7 @@ public: void LoadingScreen(); void FadeLoadingScreen(float howmuch); void Dispose(); - int DrawGLScene(void); + int DrawGLScene(StereoSide side); void Tick(); void TickOnce(); void TickOnceAfter(); diff --git a/Source/GameDraw.cpp b/Source/GameDraw.cpp index ea75d51..ba527aa 100644 --- a/Source/GameDraw.cpp +++ b/Source/GameDraw.cpp @@ -211,7 +211,7 @@ long long Game::MD5_string (char *string){ //return 1111111111111111; } -int Game::DrawGLScene(void) +int Game::DrawGLScene(StereoSide side) { static float texcoordwidth,texcoordheight; static float texviewwidth, texviewheight; @@ -230,8 +230,22 @@ int Game::DrawGLScene(void) 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; @@ -347,6 +361,9 @@ int Game::DrawGLScene(void) 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); @@ -3793,10 +3810,11 @@ int Game::DrawGLScene(void) //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); diff --git a/Source/GameTick.cpp b/Source/GameTick.cpp index 2e42476..4bcb66c 100644 --- a/Source/GameTick.cpp +++ b/Source/GameTick.cpp @@ -1683,6 +1683,43 @@ void Game::Tick() 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)){ diff --git a/Source/Globals.cpp b/Source/Globals.cpp index 2eae6fb..e0b189d 100644 --- a/Source/Globals.cpp +++ b/Source/Globals.cpp @@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "Person.h" #include "TGALoader.h" #include "openal_wrapper.h" +#include "Stereo.h" #include "Constants.h" @@ -267,3 +268,6 @@ bool gamestarted = 0; //TextureList textures; +StereoMode stereomode = stereoHorizontalInterlaced; +float stereoseparation = 0.05; +bool stereoreverse = false; \ No newline at end of file diff --git a/Source/OpenGL_Windows.cpp b/Source/OpenGL_Windows.cpp index da51185..b862fc2 100644 --- a/Source/OpenGL_Windows.cpp +++ b/Source/OpenGL_Windows.cpp @@ -321,7 +321,12 @@ void ShutdownDSp () void DrawGL (Game & game) { - game.DrawGLScene(); + if ( stereomode == stereoNone ) { + game.DrawGLScene(stereoCenter); + } else { + game.DrawGLScene(stereoLeft); + game.DrawGLScene(stereoRight); + } } @@ -924,7 +929,8 @@ Boolean SetUp (Game & game) 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()); @@ -973,7 +979,6 @@ Boolean SetUp (Game & game) 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); @@ -1015,6 +1020,56 @@ Boolean SetUp (Game & game) 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