--- a/hedgewars/uRender.pas Mon Mar 23 02:03:45 2015 +0100
+++ b/hedgewars/uRender.pas Tue Mar 24 12:48:55 2015 +0100
@@ -59,12 +59,16 @@
procedure DrawWaves (Dir, dX, dY, oX: LongInt; tnt: Byte);
procedure RenderClear ();
-procedure RenderSetClearColor (r, g, b, a: real);
+procedure RenderClear (mode: TRenderMode);
+procedure RenderSetClearColor (r, g, b, a: real);
procedure Tint (r, g, b, a: Byte); inline;
procedure Tint (c: Longword); inline;
procedure untint(); inline;
procedure setTintAdd (f: boolean); inline;
+// call this to finish the rendering of current frame
+procedure FinishRender();
+
function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline;
// 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen
@@ -74,7 +78,8 @@
procedure SetScale(f: GLfloat);
procedure UpdateViewLimits();
-procedure RenderSetup();
+procedure RendererSetup();
+procedure RendererCleanup();
// TODO everything below this should not need a public interface
@@ -124,6 +129,11 @@
LastColorPointerN, LastTexCoordPointerN, LastVertexPointerN: Integer;
{$ENDIF}
+{$IFDEF USE_S3D_RENDERING}
+ // texture/vertex buffers for left/right/default eye modes
+ texLRDtb, texLvb, texRvb: array [0..3] of TVertex2f;
+{$ENDIF}
+
function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline;
begin
isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0);
@@ -148,11 +158,92 @@
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
end;
+{$IFDEF USE_S3D_RENDERING}
+procedure RenderClear(mode: TRenderMode);
+var frame: GLuint;
+begin
+ if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
+ begin
+ case mode of
+ rmLeftEye: frame:= frameL;
+ rmRightEye: frame:= frameR;
+ else
+ frame:= defaultFrame;
+ end;
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame);
+
+ RenderClear();
+ end
+ else
+ begin
+ // draw left eye in red channel only
+ if mode = rmLeftEye then
+ begin
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ RenderClear();
+ if cStereoMode = smGreenRed then
+ glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE)
+ else if cStereoMode = smBlueRed then
+ glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE)
+ else if cStereoMode = smCyanRed then
+ glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE)
+ else
+ glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
+ end
+ else
+ begin
+ // draw right eye in selected channel(s) only
+ if cStereoMode = smRedGreen then
+ glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE)
+ else if cStereoMode = smRedBlue then
+ glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE)
+ else if cStereoMode = smRedCyan then
+ glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE)
+ else
+ glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
+ end;
+ end;
+end;
+{$ENDIF}
+
procedure RenderSetClearColor(r, g, b, a: real);
begin
glClearColor(r, g, b, a);
end;
+procedure FinishRender();
+begin
+
+{$IFDEF USE_S3D_RENDERING}
+if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
+ begin
+ RenderClear(rmDefault);
+
+ SetScale(cDefaultZoomLevel);
+
+
+ // same for all
+ SetTexCoordPointer(@texLRDtb, Length(texLRDtb));
+
+
+ // draw left frame
+ glBindTexture(GL_TEXTURE_2D, texl);
+ SetVertexPointer(@texLvb, Length(texLvb));
+ //UpdateModelviewProjection;
+ glDrawArrays(GL_TRIANGLE_FAN, 0, Length(texLvb));
+
+ // draw right frame
+ glBindTexture(GL_TEXTURE_2D, texl);
+ SetVertexPointer(@texRvb, Length(texRvb));
+ //UpdateModelviewProjection;
+ glDrawArrays(GL_TRIANGLE_FAN, 0, Length(texRvb));
+
+ SetScale(zoom);
+ end;
+{$ENDIF}
+end;
+
{$IFDEF GL2}
function CompileShader(shaderFile: string; shaderType: GLenum): GLuint;
var
@@ -303,14 +394,42 @@
glDeleteRenderbuffersEXT(1, @depth);
glDeleteFramebuffersEXT(1, @frame);
end;
+{$ENDIF}
+procedure RendererCleanup();
+begin
+{$IFNDEF PAS2C}
+{$IFDEF USE_VIDEO_RECORDING}
+ if defaultFrame <> 0 then
+ DeleteFramebuffer(defaultFrame, depthv, texv);
{$ENDIF}
-procedure RenderSetup();
+{$IFDEF USE_S3D_RENDERING}
+ if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
+ begin
+ DeleteFramebuffer(framel, depthl, texl);
+ DeleteFramebuffer(framer, depthr, texr);
+ end
+{$ENDIF}
+{$ENDIF}
+end;
+
+procedure RendererSetup();
var AuxBufNum: LongInt = 0;
tmpstr: ansistring;
tmpint: LongInt;
tmpn: LongInt;
begin
+{$IFDEF MOBILE}
+ // TODO: this function creates an opengles1.1 context
+ // un-comment below and add proper logic to support opengles2.0
+ //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
+ //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
+ if SDLGLcontext = nil then
+ SDLGLcontext:= SDL_GL_CreateContext(SDLwindow);
+ SDLTry(SDLGLcontext <> nil, true);
+ SDL_GL_SetSwapInterval(1);
+{$ENDIF}
+
// suppress hint/warning
AuxBufNum:= AuxBufNum;
@@ -427,12 +546,66 @@
CreateFramebuffer(framel, depthl, texl);
CreateFramebuffer(framer, depthr, texr);
+
+
+
// reset
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame)
end
else
cStereoMode:= smNone;
end;
+
+ // set up vertex/texture buffers for frame textures
+ texLRDtb[0].X:= 0.0;
+ texLRDtb[0].Y:= 0.0;
+ texLRDtb[1].X:= 1.0;
+ texLRDtb[1].Y:= 0.0;
+ texLRDtb[2].X:= 1.0;
+ texLRDtb[2].Y:= 1.0;
+ texLRDtb[3].X:= 0.0;
+ texLRDtb[3].Y:= 1.0;
+
+ if cStereoMode = smHorizontal then
+ begin
+ texLvb[0].X:= cScreenWidth / -2;
+ texLvb[0].Y:= cScreenHeight;
+ texLvb[1].X:= 0;
+ texLvb[1].Y:= cScreenHeight;
+ texLvb[2].X:= 0;
+ texLvb[2].Y:= 0;
+ texLvb[3].X:= cScreenWidth / -2;
+ texLvb[3].Y:= 0;
+
+ texRvb[0].X:= 0;
+ texRvb[0].Y:= cScreenHeight;
+ texRvb[1].X:= cScreenWidth / 2;
+ texRvb[1].Y:= cScreenHeight;
+ texRvb[2].X:= cScreenWidth / 2;
+ texRvb[2].Y:= 0;
+ texRvb[3].X:= 0;
+ texRvb[3].Y:= 0;
+ end
+ else
+ begin
+ texLvb[0].X:= cScreenWidth / -2;
+ texLvb[0].Y:= cScreenHeight / 2;
+ texLvb[1].X:= cScreenWidth / 2;
+ texLvb[1].Y:= cScreenHeight / 2;
+ texLvb[2].X:= cScreenWidth / 2;
+ texLvb[2].Y:= 0;
+ texLvb[3].X:= cScreenWidth / -2;
+ texLvb[3].Y:= 0;
+
+ texRvb[0].X:= cScreenWidth / -2;
+ texRvb[0].Y:= cScreenHeight;
+ texRvb[1].X:= cScreenWidth / 2;
+ texRvb[1].Y:= cScreenHeight;
+ texRvb[2].X:= cScreenWidth / 2;
+ texRvb[2].Y:= cScreenHeight / 2;
+ texRvb[3].X:= cScreenWidth / -2;
+ texRvb[3].Y:= cScreenHeight / 2;
+ end;
{$ENDIF}
// set view port to whole window