# HG changeset patch # User koda # Date 1280488066 -7200 # Node ID 617d00c850b0cb115d108ad2dab4196ac4ae4e86 # Parent 5fdf49ace96c2225f6e96866d65d8a06bd02e23e creating a new branch for experimental 3d stereographic rendering currently it contains only an updated version of the anaglyph patch by Smaxx diff -r 5fdf49ace96c -r 617d00c850b0 .hgeol --- a/.hgeol Thu Jul 29 18:31:48 2010 -0400 +++ b/.hgeol Fri Jul 30 13:07:46 2010 +0200 @@ -1,6 +1,7 @@ [patterns] **.h = native **.c = native +**.m = native **.cpp = native **.lua = native **.txt = native diff -r 5fdf49ace96c -r 617d00c850b0 hedgewars/uMisc.pas --- a/hedgewars/uMisc.pas Thu Jul 29 18:31:48 2010 -0400 +++ b/hedgewars/uMisc.pas Fri Jul 30 13:07:46 2010 +0200 @@ -35,6 +35,8 @@ isSpeed : boolean; isFirstFrame : boolean; + isStereoEnabled : boolean = true; + fastUntilLag : boolean; GameState : TGameState; diff -r 5fdf49ace96c -r 617d00c850b0 hedgewars/uStore.pas --- a/hedgewars/uStore.pas Thu Jul 29 18:31:48 2010 -0400 +++ b/hedgewars/uStore.pas Fri Jul 30 13:07:46 2010 +0200 @@ -39,7 +39,9 @@ rotationQt: GLfloat; wScreen: LongInt; hScreen: LongInt; - + framel, framer, depthl, depthr: GLuint; + texl, texr: GLuint; + procedure initModule; procedure freeModule; @@ -801,6 +803,15 @@ SDL_FreeSurface(MissionIcons); FreeTexture(ropeIconTex); FreeTexture(HHTexture); + if isStereoEnabled then + begin + glDeleteTextures(1, @texl); + glDeleteRenderbuffersEXT(1, @depthl); + glDeleteFramebuffersEXT(1, @framel); + glDeleteTextures(1, @texr); + glDeleteRenderbuffersEXT(1, @depthr); + glDeleteFramebuffersEXT(1, @framer) + end end; @@ -1170,7 +1181,9 @@ {$ENDIF} end; -{$IFNDEF IPHONEOS} +{$IFDEF IPHONEOS} + cGPUVendor:= gvApple; +{$ELSE} if StrPos(Str2PChar(vendor), Str2PChar('nvidia')) <> nil then cGPUVendor:= gvNVIDIA else if StrPos(Str2PChar(vendor), Str2PChar('intel')) <> nil then @@ -1178,8 +1191,37 @@ else if StrPos(Str2PChar(vendor), Str2PChar('ati')) <> nil then cGPUVendor:= gvIntel; //SupportNPOTT:= glLoadExtension('GL_ARB_texture_non_power_of_two'); -{$ELSE} - cGPUVendor:= gvApple; + if isStereoEnabled then + begin + glLoadExtension('GL_EXT_framebuffer_object'); + glGenFramebuffersEXT(1, @framel); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framel); + glGenRenderbuffersEXT(1, @depthl); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthl); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, cScreenWidth, cScreenHeight); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthl); + glGenTextures(1, @texl); + glBindTexture(GL_TEXTURE_2D, texl); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, cScreenWidth, cScreenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nil); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texl, 0); + + glGenFramebuffersEXT(1, @framer); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framer); + glGenRenderbuffersEXT(1, @depthr); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthr); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, cScreenWidth, cScreenHeight); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthr); + glGenTextures(1, @texr); + glBindTexture(GL_TEXTURE_2D, texr); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, cScreenWidth, cScreenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nil); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texr, 0); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) + end; {$ENDIF} {$IFDEF DEBUGFILE} diff -r 5fdf49ace96c -r 617d00c850b0 hedgewars/uWorld.pas --- 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;