hedgewars/uWorld.pas
branchexperimental3D
changeset 3686 617d00c850b0
parent 3663 8c28abf427f5
child 3688 fd8c22a358de
--- a/hedgewars/uWorld.pas	Thu Jul 29 18:31:48 2010 -0400
+++ b/hedgewars/uWorld.pas	Fri Jul 30 13:07:46 2010 +0200
@@ -22,6 +22,7 @@
 interface
 uses SDLh, uGears, uConsts, uFloat, uRandom;
 
+type TRenderMode = (rmDefault, rmLeftEye, rmRightEye);
 
 var FollowGear: PGear;
     WindBarWidth: LongInt;
@@ -44,6 +45,7 @@
 
 procedure InitWorld;
 procedure DrawWorld(Lag: LongInt);
+procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode);
 procedure AddCaption(s: shortstring; Color: Longword; Group: TCapGroup);
 procedure ShowMission(caption, subcaption, text: ansistring; icon, time : LongInt);
 procedure HideMission;
@@ -528,14 +530,7 @@
 
 
 procedure DrawWorld(Lag: LongInt);
-var i, t: LongInt;
-    r: TSDL_Rect;
-    tdx, tdy: Double;
-    grp: TCapGroup;
-    s: string[15];
-    highlight: Boolean;
-    offset, offsetX, offsetY, ScreenBottom: LongInt;
-    VertexBuffer: array [0..3] of TVertex2f;
+var cc: array[0..3] of GLfloat;
 begin
     if not isPaused then
     begin
@@ -564,6 +559,93 @@
     if not isPaused then
         MoveCamera;
 
+    if not isStereoEnabled then
+    begin
+        glClear(GL_COLOR_BUFFER_BIT);
+        DrawWorldStereo(Lag, rmDefault)
+    end
+    else
+    begin
+        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framel);
+        glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+        DrawWorldStereo(Lag, rmLeftEye);
+        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framer);
+        glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+        DrawWorldStereo(0, rmRightEye);
+        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+        glGetFloatv(GL_COLOR_CLEAR_VALUE, @cc);
+        glClearColor(0, 0, 0, 0);
+        glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+        glClearColor(cc[0], cc[1], cc[2], cc[3]);
+        SetScale(2.0);
+        glEnable(GL_TEXTURE_2D);
+        glEnable(GL_BLEND);
+        glBlendFunc(GL_ONE, GL_ONE);
+        glBindTexture(GL_TEXTURE_2D, texl);
+        glColor3f(0.0, 1.0, 1.0);
+        glBegin(GL_QUADS);
+            glTexCoord2f(0.0, 0.0);
+            glVertex2d(cScreenWidth / -2, cScreenHeight);
+            glTexCoord2f(1.0, 0.0);
+            glVertex2d(cScreenWidth / 2, cScreenHeight);
+            glTexCoord2f(1.0, 1.0);
+            glVertex2d(cScreenWidth / 2, 0);
+            glTexCoord2f(0.0, 1.0);
+            glVertex2d(cScreenWidth / -2, 0);
+        glEnd();
+        glBindTexture(GL_TEXTURE_2D, texr);
+        glColor3f(1.0, 0.0, 0.0);
+        glBegin(GL_QUADS);
+            glTexCoord2f(0.0, 0.0);
+            glVertex2d(cScreenWidth / -2, cScreenHeight);
+            glTexCoord2f(1.0, 0.0);
+            glVertex2d(cScreenWidth / 2, cScreenHeight);
+            glTexCoord2f(1.0, 1.0);
+            glVertex2d(cScreenWidth / 2, 0);
+            glTexCoord2f(0.0, 1.0);
+            glVertex2d(cScreenWidth / -2, 0);
+        glEnd();
+        glColor3f(1.0, 1.0, 1.0);
+        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+        SetScale(zoom);
+    end
+end;
+
+ const cStereo_Sky     = 0.0750;
+       cStereo_Horizon = 0.0250;
+       cStereo_Water   = 0.0125;
+ var   stereoDepth: GLfloat = 0;
+ 
+ procedure ChangeDepth(rm: TRenderMode; d: GLfloat);
+ begin
+     if rm = rmDefault then exit
+     else if rm = rmRightEye then d:= -d;
+     stereoDepth:= stereoDepth + d;
+     glMatrixMode(GL_PROJECTION);
+     glTranslatef(d, 0, 0);
+     glMatrixMode(GL_MODELVIEW)
+ end;
+ 
+ procedure ResetDepth(rm: TRenderMode);
+ begin
+     if rm = rmDefault then exit;
+     glMatrixMode(GL_PROJECTION);
+     glTranslatef(-stereoDepth, 0, 0);
+     glMatrixMode(GL_MODELVIEW);
+     stereoDepth:= 0;
+ end;
+ 
+ procedure DrawWorldStereo(Lag: LongInt; RM: TRenderMode);
+ var i, t: LongInt;
+     r: TSDL_Rect;
+     tdx, tdy: Double;
+     grp: TCapGroup;
+     s: string[15];
+     highlight: Boolean;
+     offset, offsetX, offsetY, screenBottom: LongInt;
+     scale: GLfloat;
+     VertexBuffer: array [0..3] of TVertex2f;
+ begin
     if (cReducedQuality and rqNoBackground) = 0 then
     begin
         // Offsets relative to camera - spare them to wimpier cpus, no bg or flakes for them anyway
@@ -575,7 +657,9 @@
             HorizontOffset:= HorizontOffset + ((ScreenBottom-SkyOffset) div 20);
 
         // background
+ChangeDepth(RM, cStereo_Sky);
         DrawRepeated(sprSky, sprSkyL, sprSkyR, (WorldDx + LAND_WIDTH div 2) * 3 div 8, SkyOffset);
+ChangeDepth(RM, -cStereo_Horizon);
         DrawRepeated(sprHorizont, sprHorizontL, sprHorizontR, (WorldDx + LAND_WIDTH div 2) * 3 div 5, HorizontOffset);
     end;
 
@@ -585,10 +669,15 @@
     begin
         // Waves
         DrawWater(255, SkyOffset); 
+ChangeDepth(RM, -cStereo_Water);
         DrawWaves( 1,  0 - WorldDx div 32, - cWaveHeight + offsetY div 35, 64);
+ChangeDepth(RM, -cStereo_Water);
         DrawWaves( -1,  25 + WorldDx div 25, - cWaveHeight + offsetY div 38, 48);
+ChangeDepth(RM, -cStereo_Water);
         DrawWaves( 1,  75 - WorldDx div 19, - cWaveHeight + offsetY div 45, 32);
+ChangeDepth(RM, -cStereo_Water);
         DrawWaves(-1, 100 + WorldDx div 14, - cWaveHeight + offsetY div 70, 24);
+ResetDepth(RM);
     end
     else
         DrawWaves(-1, 100, - (cWaveHeight + (cWaveHeight shr 1)), 0);
@@ -628,16 +717,21 @@
     DrawWater(cWaterOpacity, 0);
 
     // Waves
+ChangeDepth(RM, cStereo_Water);
     DrawWaves( 1, 25 - WorldDx div 9, - cWaveHeight, 12);
 
     if (cReducedQuality and rq2DWater) = 0 then
     begin
         //DrawWater(cWaterOpacity, - offsetY div 40);
+ChangeDepth(RM, cStereo_Water);
         DrawWaves(-1, 50 + WorldDx div 6, - cWaveHeight - offsetY div 40, 8);
         DrawWater(cWaterOpacity, - offsetY div 20);
+ChangeDepth(RM, cStereo_Water);
         DrawWaves( 1, 75 - WorldDx div 4, - cWaveHeight - offsetY div 20, 2);
         DrawWater(cWaterOpacity, - offsetY div 10);
+ChangeDepth(RM, cStereo_Water);
         DrawWaves( -1, 25 + WorldDx div 3, - cWaveHeight - offsetY div 10, 0);
+ResetDepth(RM);
     end
     else
         DrawWaves(-1, 50, - (cWaveHeight shr 1), 0);
@@ -862,6 +956,8 @@
 offsetX:= 10;
 {$ENDIF}
 offsetY:= cOffsetY;
+if (RM = rmDefault) or (RM = rmLeftEye) then
+begin
 inc(Frames);
 
 if cShowFPS or (GameType = gmtDemo) then inc(CountTicks, Lag);
@@ -914,6 +1010,8 @@
 
 // lag warning (?)
 inc(SoundTimerTicks, Lag);
+end;
+
 if SoundTimerTicks >= 50 then
    begin
    SoundTimerTicks:= 0;