hedgewars/uRender.pas
changeset 10869 f23763bbac1b
parent 10724 eedd0697d55c
child 10870 5efea5942475
equal deleted inserted replaced
10868:acb03a9712c3 10869:f23763bbac1b
    57 procedure DrawScreenWidget      (widget: POnScreenWidget);
    57 procedure DrawScreenWidget      (widget: POnScreenWidget);
    58 procedure DrawWater             (Alpha: byte; OffsetY, OffsetX: LongInt);
    58 procedure DrawWater             (Alpha: byte; OffsetY, OffsetX: LongInt);
    59 procedure DrawWaves             (Dir, dX, dY, oX: LongInt; tnt: Byte);
    59 procedure DrawWaves             (Dir, dX, dY, oX: LongInt; tnt: Byte);
    60 
    60 
    61 procedure RenderClear           ();
    61 procedure RenderClear           ();
    62 procedure RenderSetClearColor      (r, g, b, a: real);
    62 procedure RenderClear           (mode: TRenderMode);
       
    63 procedure RenderSetClearColor   (r, g, b, a: real);
    63 procedure Tint                  (r, g, b, a: Byte); inline;
    64 procedure Tint                  (r, g, b, a: Byte); inline;
    64 procedure Tint                  (c: Longword); inline;
    65 procedure Tint                  (c: Longword); inline;
    65 procedure untint(); inline;
    66 procedure untint(); inline;
    66 procedure setTintAdd            (f: boolean); inline;
    67 procedure setTintAdd            (f: boolean); inline;
    67 
    68 
       
    69 // call this to finish the rendering of current frame
       
    70 procedure FinishRender();
       
    71 
    68 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline;
    72 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline;
    69 
    73 
    70 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen
    74 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen
    71 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline;
    75 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline;
    72 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline;
    76 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline;
    73 
    77 
    74 procedure SetScale(f: GLfloat);
    78 procedure SetScale(f: GLfloat);
    75 procedure UpdateViewLimits();
    79 procedure UpdateViewLimits();
    76 
    80 
    77 procedure RenderSetup();
    81 procedure RendererSetup();
       
    82 procedure RendererCleanup();
    78 
    83 
    79 // TODO everything below this should not need a public interface
    84 // TODO everything below this should not need a public interface
    80 
    85 
    81 procedure CreateFramebuffer(var frame, depth, tex: GLuint);
    86 procedure CreateFramebuffer(var frame, depth, tex: GLuint);
    82 procedure DeleteFramebuffer(var frame, depth, tex: GLuint);
    87 procedure DeleteFramebuffer(var frame, depth, tex: GLuint);
   122     LastColorPointer , LastTexCoordPointer , LastVertexPointer : Pointer;
   127     LastColorPointer , LastTexCoordPointer , LastVertexPointer : Pointer;
   123 {$IFDEF GL2}
   128 {$IFDEF GL2}
   124     LastColorPointerN, LastTexCoordPointerN, LastVertexPointerN: Integer;
   129     LastColorPointerN, LastTexCoordPointerN, LastVertexPointerN: Integer;
   125 {$ENDIF}
   130 {$ENDIF}
   126 
   131 
       
   132 {$IFDEF USE_S3D_RENDERING}
       
   133     // texture/vertex buffers for left/right/default eye modes
       
   134     texLRDtb, texLvb, texRvb: array [0..3] of TVertex2f;
       
   135 {$ENDIF}
       
   136 
   127 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline;
   137 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline;
   128 begin
   138 begin
   129     isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0);
   139     isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0);
   130 end;
   140 end;
   131 
   141 
   146 procedure RenderClear();
   156 procedure RenderClear();
   147 begin
   157 begin
   148     glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
   158     glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
   149 end;
   159 end;
   150 
   160 
       
   161 {$IFDEF USE_S3D_RENDERING}
       
   162 procedure RenderClear(mode: TRenderMode);
       
   163 var frame: GLuint;
       
   164 begin
       
   165     if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
       
   166         begin
       
   167         case mode of
       
   168             rmLeftEye:  frame:= frameL;
       
   169             rmRightEye: frame:= frameR;
       
   170             else
       
   171                 frame:= defaultFrame;
       
   172         end;
       
   173 
       
   174         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame);
       
   175 
       
   176         RenderClear();
       
   177         end
       
   178     else
       
   179         begin
       
   180         // draw left eye in red channel only
       
   181         if mode = rmLeftEye then
       
   182             begin
       
   183             glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
       
   184             RenderClear();
       
   185             if cStereoMode = smGreenRed then
       
   186                 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE)
       
   187             else if cStereoMode = smBlueRed then
       
   188                 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE)
       
   189             else if cStereoMode = smCyanRed then
       
   190                 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE)
       
   191             else
       
   192                 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
       
   193             end
       
   194         else
       
   195             begin
       
   196             // draw right eye in selected channel(s) only
       
   197             if cStereoMode = smRedGreen then
       
   198                 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE)
       
   199             else if cStereoMode = smRedBlue then
       
   200                 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE)
       
   201             else if cStereoMode = smRedCyan then
       
   202                 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE)
       
   203             else
       
   204                 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
       
   205             end;
       
   206         end;
       
   207 end;
       
   208 {$ENDIF}
       
   209 
   151 procedure RenderSetClearColor(r, g, b, a: real);
   210 procedure RenderSetClearColor(r, g, b, a: real);
   152 begin
   211 begin
   153     glClearColor(r, g, b, a);
   212     glClearColor(r, g, b, a);
       
   213 end;
       
   214 
       
   215 procedure FinishRender();
       
   216 begin
       
   217 
       
   218 {$IFDEF USE_S3D_RENDERING}
       
   219 if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
       
   220     begin
       
   221     RenderClear(rmDefault);
       
   222 
       
   223     SetScale(cDefaultZoomLevel);
       
   224 
       
   225 
       
   226     // same for all
       
   227     SetTexCoordPointer(@texLRDtb, Length(texLRDtb));
       
   228 
       
   229 
       
   230     // draw left frame
       
   231     glBindTexture(GL_TEXTURE_2D, texl);
       
   232     SetVertexPointer(@texLvb, Length(texLvb));
       
   233     //UpdateModelviewProjection;
       
   234     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(texLvb));
       
   235 
       
   236     // draw right frame
       
   237     glBindTexture(GL_TEXTURE_2D, texl);
       
   238     SetVertexPointer(@texRvb, Length(texRvb));
       
   239     //UpdateModelviewProjection;
       
   240     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(texRvb));
       
   241 
       
   242     SetScale(zoom);
       
   243     end;
       
   244 {$ENDIF}
   154 end;
   245 end;
   155 
   246 
   156 {$IFDEF GL2}
   247 {$IFDEF GL2}
   157 function CompileShader(shaderFile: string; shaderType: GLenum): GLuint;
   248 function CompileShader(shaderFile: string; shaderType: GLenum): GLuint;
   158 var
   249 var
   301 begin
   392 begin
   302     glDeleteTextures(1, @tex);
   393     glDeleteTextures(1, @tex);
   303     glDeleteRenderbuffersEXT(1, @depth);
   394     glDeleteRenderbuffersEXT(1, @depth);
   304     glDeleteFramebuffersEXT(1, @frame);
   395     glDeleteFramebuffersEXT(1, @frame);
   305 end;
   396 end;
   306 
   397 {$ENDIF}
   307 {$ENDIF}
   398 
   308 procedure RenderSetup();
   399 procedure RendererCleanup();
       
   400 begin
       
   401 {$IFNDEF PAS2C}
       
   402 {$IFDEF USE_VIDEO_RECORDING}
       
   403     if defaultFrame <> 0 then
       
   404         DeleteFramebuffer(defaultFrame, depthv, texv);
       
   405 {$ENDIF}
       
   406 {$IFDEF USE_S3D_RENDERING}
       
   407     if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then
       
   408         begin
       
   409         DeleteFramebuffer(framel, depthl, texl);
       
   410         DeleteFramebuffer(framer, depthr, texr);
       
   411         end
       
   412 {$ENDIF}
       
   413 {$ENDIF}
       
   414 end;
       
   415 
       
   416 procedure RendererSetup();
   309 var AuxBufNum: LongInt = 0;
   417 var AuxBufNum: LongInt = 0;
   310     tmpstr: ansistring;
   418     tmpstr: ansistring;
   311     tmpint: LongInt;
   419     tmpint: LongInt;
   312     tmpn: LongInt;
   420     tmpn: LongInt;
   313 begin
   421 begin
       
   422 {$IFDEF MOBILE}
       
   423     // TODO: this function creates an opengles1.1 context
       
   424     // un-comment below and add proper logic to support opengles2.0
       
   425     //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
       
   426     //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
       
   427     if SDLGLcontext = nil then
       
   428         SDLGLcontext:= SDL_GL_CreateContext(SDLwindow);
       
   429     SDLTry(SDLGLcontext <> nil, true);
       
   430     SDL_GL_SetSwapInterval(1);
       
   431 {$ENDIF}
       
   432 
   314     // suppress hint/warning
   433     // suppress hint/warning
   315     AuxBufNum:= AuxBufNum;
   434     AuxBufNum:= AuxBufNum;
   316 
   435 
   317     // get the max (h and v) size for textures that the gpu can support
   436     // get the max (h and v) size for textures that the gpu can support
   318     glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize);
   437     glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize);
   425         if glLoadExtension('GL_EXT_framebuffer_object') then
   544         if glLoadExtension('GL_EXT_framebuffer_object') then
   426             begin
   545             begin
   427             CreateFramebuffer(framel, depthl, texl);
   546             CreateFramebuffer(framel, depthl, texl);
   428             CreateFramebuffer(framer, depthr, texr);
   547             CreateFramebuffer(framer, depthr, texr);
   429 
   548 
       
   549 
       
   550 
       
   551 
   430             // reset
   552             // reset
   431             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame)
   553             glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame)
   432             end
   554             end
   433         else
   555         else
   434             cStereoMode:= smNone;
   556             cStereoMode:= smNone;
   435     end;
   557     end;
       
   558 
       
   559     // set up vertex/texture buffers for frame textures
       
   560     texLRDtb[0].X:= 0.0;
       
   561     texLRDtb[0].Y:= 0.0;
       
   562     texLRDtb[1].X:= 1.0;
       
   563     texLRDtb[1].Y:= 0.0;
       
   564     texLRDtb[2].X:= 1.0;
       
   565     texLRDtb[2].Y:= 1.0;
       
   566     texLRDtb[3].X:= 0.0;
       
   567     texLRDtb[3].Y:= 1.0;
       
   568 
       
   569     if cStereoMode = smHorizontal then
       
   570         begin
       
   571         texLvb[0].X:= cScreenWidth / -2;
       
   572         texLvb[0].Y:= cScreenHeight;
       
   573         texLvb[1].X:= 0;
       
   574         texLvb[1].Y:= cScreenHeight;
       
   575         texLvb[2].X:= 0;
       
   576         texLvb[2].Y:= 0;
       
   577         texLvb[3].X:= cScreenWidth / -2;
       
   578         texLvb[3].Y:= 0;
       
   579 
       
   580         texRvb[0].X:= 0;
       
   581         texRvb[0].Y:= cScreenHeight;
       
   582         texRvb[1].X:= cScreenWidth / 2;
       
   583         texRvb[1].Y:= cScreenHeight;
       
   584         texRvb[2].X:= cScreenWidth / 2;
       
   585         texRvb[2].Y:= 0;
       
   586         texRvb[3].X:= 0;
       
   587         texRvb[3].Y:= 0;
       
   588         end
       
   589     else
       
   590         begin
       
   591         texLvb[0].X:= cScreenWidth / -2;
       
   592         texLvb[0].Y:= cScreenHeight / 2;
       
   593         texLvb[1].X:= cScreenWidth / 2;
       
   594         texLvb[1].Y:= cScreenHeight / 2;
       
   595         texLvb[2].X:= cScreenWidth / 2;
       
   596         texLvb[2].Y:= 0;
       
   597         texLvb[3].X:= cScreenWidth / -2;
       
   598         texLvb[3].Y:= 0;
       
   599 
       
   600         texRvb[0].X:= cScreenWidth / -2;
       
   601         texRvb[0].Y:= cScreenHeight;
       
   602         texRvb[1].X:= cScreenWidth / 2;
       
   603         texRvb[1].Y:= cScreenHeight;
       
   604         texRvb[2].X:= cScreenWidth / 2;
       
   605         texRvb[2].Y:= cScreenHeight / 2;
       
   606         texRvb[3].X:= cScreenWidth / -2;
       
   607         texRvb[3].Y:= cScreenHeight / 2;
       
   608         end;
   436 {$ENDIF}
   609 {$ENDIF}
   437 
   610 
   438 // set view port to whole window
   611 // set view port to whole window
   439 glViewport(0, 0, cScreenWidth, cScreenHeight);
   612 glViewport(0, 0, cScreenWidth, cScreenHeight);
   440 
   613