]> git.jsancho.org Git - lugaru.git/commitdiff
Initial stereo code.
authorVadim Trochinsky <vadim.trochinsky@gmail.com>
Sun, 16 May 2010 01:52:10 +0000 (05:52 +0400)
committerVadim Trochinsky <vadim.trochinsky@gmail.com>
Sun, 16 May 2010 01:52:10 +0000 (05:52 +0400)
Anaglyph and horizontal interlacing are supported.

No settings (change in Globals.cpp for now)

Source/Game.h
Source/GameDraw.cpp
Source/GameTick.cpp
Source/Globals.cpp
Source/OpenGL_Windows.cpp
Source/Stereo.h [new file with mode: 0644]

index bda4324218e65af58dd42ad4b6109e2e8f3ad6cb..1297fbdc4f6c016076c7bdbe308e563b2a53b5d7 100644 (file)
@@ -62,6 +62,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "binio.h"
 #include <fstream>
 #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();
index ea75d51b0eed5a8e5d972dd6fbe3a01ff4dcae03..ba527aaa8098bf72bceb93b5158197d909375a4a 100644 (file)
@@ -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);
index 2e424760f6f8ac8c9797aff2883ecf25924de61e..4bcb66c07ae657b55880ff5c8a41cea3d1648df1 100644 (file)
@@ -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)){
index 2eae6fbc7979c31da454398c1257935c144ce1c7..e0b189d811cf209b2da7594927f1eaef20d0920d 100644 (file)
@@ -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
index da5118519eb0526874f7878c36d76767a69cedf1..b862fc2997af3cc7de4a58cea7cc668318a76ae8 100644 (file)
@@ -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<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;
diff --git a/Source/Stereo.h b/Source/Stereo.h
new file mode 100644 (file)
index 0000000..084a9f4
--- /dev/null
@@ -0,0 +1,28 @@
+
+#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