hedgewars/uRender.pas
changeset 10302 ea0b0e2efd95
parent 10301 6a225b469eef
child 10304 7e40820b7ed6
equal deleted inserted replaced
10301:6a225b469eef 10302:ea0b0e2efd95
    21 
    21 
    22 unit uRender;
    22 unit uRender;
    23 
    23 
    24 interface
    24 interface
    25 
    25 
    26 uses SDLh, uTypes, GLunit, uConsts, uStore{$IFDEF GL2}, uMatrix{$ENDIF};
    26 uses SDLh, uTypes, GLunit, uConsts{$IFDEF GL2}, uMatrix{$ENDIF};
    27 
    27 
    28 procedure DrawSprite            (Sprite: TSprite; X, Y, Frame: LongInt);
    28 procedure DrawSprite            (Sprite: TSprite; X, Y, Frame: LongInt);
    29 procedure DrawSprite            (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
    29 procedure DrawSprite            (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
    30 procedure DrawSpriteFromRect    (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
    30 procedure DrawSpriteFromRect    (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
    31 procedure DrawSpriteClipped     (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
    31 procedure DrawSpriteClipped     (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
    62 
    62 
    63 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen
    63 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen
    64 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline;
    64 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline;
    65 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline;
    65 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline;
    66 
    66 
    67 
    67 procedure SetScale(f: GLfloat);
       
    68 procedure UpdateViewLimits();
       
    69 
       
    70 procedure EnableTexture(enable:Boolean);
       
    71 
       
    72 procedure SetTexCoordPointer(p: Pointer;n: Integer);
       
    73 procedure SetVertexPointer(p: Pointer;n: Integer);
       
    74 procedure SetColorPointer(p: Pointer;n: Integer);
       
    75 
       
    76 procedure UpdateModelviewProjection(); inline;
       
    77 
       
    78 procedure openglLoadIdentity    (); inline;
    68 procedure openglTranslProjMatrix(X, Y, Z: GLFloat); inline;
    79 procedure openglTranslProjMatrix(X, Y, Z: GLFloat); inline;
    69 procedure openglPushMatrix      (); inline;
    80 procedure openglPushMatrix      (); inline;
    70 procedure openglPopMatrix       (); inline;
    81 procedure openglPopMatrix       (); inline;
    71 procedure openglTranslatef      (X, Y, Z: GLfloat); inline;
    82 procedure openglTranslatef      (X, Y, Z: GLfloat); inline;
    72 procedure openglScalef          (ScaleX, ScaleY, ScaleZ: GLfloat); inline;
    83 procedure openglScalef          (ScaleX, ScaleY, ScaleZ: GLfloat); inline;
   100 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline;
   111 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline;
   101 begin
   112 begin
   102     if Y > ViewBottomY then exit(1);
   113     if Y > ViewBottomY then exit(1);
   103     if Y + Height < ViewTopY then exit(-1);
   114     if Y + Height < ViewTopY then exit(-1);
   104     isDyAreaOffscreen:= 0;
   115     isDyAreaOffscreen:= 0;
       
   116 end;
       
   117 
       
   118 procedure openglLoadIdentity(); inline;
       
   119 begin
       
   120 {$IFDEF GL2}
       
   121     hglLoadIdentity();
       
   122 {$ELSE}
       
   123     glLoadIdentity();
       
   124 {$ENDIF}
   105 end;
   125 end;
   106 
   126 
   107 procedure openglTranslProjMatrix(X, Y, Z: GLfloat); inline;
   127 procedure openglTranslProjMatrix(X, Y, Z: GLfloat); inline;
   108 begin
   128 begin
   109 {$IFDEF GL2}
   129 {$IFDEF GL2}
   182         {$ELSE}
   202         {$ELSE}
   183         glDisableClientState(GL_COLOR_ARRAY);
   203         glDisableClientState(GL_COLOR_ARRAY);
   184         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   204         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   185         {$ENDIF}
   205         {$ENDIF}
   186         end;
   206         end;
       
   207 end;
       
   208 
       
   209 procedure UpdateModelviewProjection(); inline;
       
   210 {$IFDEF GL2}
       
   211 var
       
   212     mvp: TMatrix4x4f;
       
   213 {$ENDIF}
       
   214 begin
       
   215 {$IFDEF GL2}
       
   216     //MatrixMultiply(mvp, mProjection, mModelview);
       
   217 {$HINTS OFF}
       
   218     hglMVP(mvp);
       
   219 {$HINTS ON}
       
   220     glUniformMatrix4fv(uCurrentMVPLocation, 1, GL_FALSE, @mvp[0, 0]);
       
   221 {$ENDIF}
       
   222 end;
       
   223 
       
   224 procedure SetTexCoordPointer(p: Pointer; n: Integer);
       
   225 begin
       
   226 {$IFDEF GL2}
       
   227     glBindBuffer(GL_ARRAY_BUFFER, tBuffer);
       
   228     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n * 2, p, GL_STATIC_DRAW);
       
   229     glEnableVertexAttribArray(aTexCoord);
       
   230     glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, pointer(0));
       
   231 {$ELSE}
       
   232     n:= n;
       
   233     glTexCoordPointer(2, GL_FLOAT, 0, p);
       
   234 {$ENDIF}
       
   235 end;
       
   236 
       
   237 procedure SetVertexPointer(p: Pointer; n: Integer);
       
   238 begin
       
   239 {$IFDEF GL2}
       
   240     glBindBuffer(GL_ARRAY_BUFFER, vBuffer);
       
   241     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n * 2, p, GL_STATIC_DRAW);
       
   242     glEnableVertexAttribArray(aVertex);
       
   243     glVertexAttribPointer(aVertex, 2, GL_FLOAT, GL_FALSE, 0, pointer(0));
       
   244 {$ELSE}
       
   245     n:= n;
       
   246     glVertexPointer(2, GL_FLOAT, 0, p);
       
   247 {$ENDIF}
       
   248 end;
       
   249 
       
   250 procedure SetColorPointer(p: Pointer; n: Integer);
       
   251 begin
       
   252 {$IFDEF GL2}
       
   253     glBindBuffer(GL_ARRAY_BUFFER, cBuffer);
       
   254     glBufferData(GL_ARRAY_BUFFER, n * 4, p, GL_STATIC_DRAW);
       
   255     glEnableVertexAttribArray(aColor);
       
   256     glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, pointer(0));
       
   257 {$ELSE}
       
   258     n:= n;
       
   259     glColorPointer(4, GL_UNSIGNED_BYTE, 0, p);
       
   260 {$ENDIF}
       
   261 end;
       
   262 
       
   263 procedure EnableTexture(enable:Boolean);
       
   264 begin
       
   265     {$IFDEF GL2}
       
   266     if enable then
       
   267         glUniform1i(glGetUniformLocation(shaderMain, pchar('enableTexture')), 1)
       
   268     else
       
   269         glUniform1i(glGetUniformLocation(shaderMain, pchar('enableTexture')), 0);
       
   270     {$ELSE}
       
   271     if enable then
       
   272         glEnable(GL_TEXTURE_2D)
       
   273     else
       
   274         glDisable(GL_TEXTURE_2D);
       
   275     {$ENDIF}
       
   276 end;
       
   277 
       
   278 procedure UpdateViewLimits();
       
   279 var tmp: real;
       
   280 begin
       
   281     // cScaleFactor is 2.0 on "no zoom"
       
   282     tmp:= cScreenWidth / cScaleFactor;
       
   283     ViewRightX:= round(tmp); // ceil could make more sense
       
   284     ViewLeftX:= round(-tmp); // floor could make more sense
       
   285     tmp:= cScreenHeight / cScaleFactor;
       
   286     ViewBottomY:= round(tmp) + cScreenHeight div 2; // ceil could make more sense
       
   287     ViewTopY:= round(-tmp) + cScreenHeight div 2; // floor could make more sense
       
   288 end;
       
   289 
       
   290 procedure SetScale(f: GLfloat);
       
   291 begin
       
   292 // leave immediately if scale factor did not change
       
   293     if f = cScaleFactor then
       
   294         exit;
       
   295 
       
   296     // for going back to default scaling just pop matrix
       
   297     if f = cDefaultZoomLevel then
       
   298         begin
       
   299         openglPopMatrix;
       
   300         end
       
   301     else
       
   302         begin
       
   303         openglPushMatrix; // save default scaling in matrix
       
   304         openglLoadIdentity();
       
   305         openglScalef(f / cScreenWidth, -f / cScreenHeight, 1.0);
       
   306         openglTranslatef(0, -cScreenHeight / 2, 0);
       
   307         end;
       
   308 
       
   309     cScaleFactor:= f;
       
   310     updateViewLimits();
       
   311 
       
   312     UpdateModelviewProjection;
   187 end;
   313 end;
   188 
   314 
   189 procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
   315 procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
   190 begin
   316 begin
   191 r.y:= r.y + Height * Position;
   317 r.y:= r.y + Height * Position;
   313 TextureBuffer[3].Y:= Texture^.tb[3].Y - Overlap;
   439 TextureBuffer[3].Y:= Texture^.tb[3].Y - Overlap;
   314 
   440 
   315 SetVertexPointer(@Texture^.vb, Length(Texture^.vb));
   441 SetVertexPointer(@Texture^.vb, Length(Texture^.vb));
   316 SetTexCoordPointer(@TextureBuffer, Length(Texture^.vb));
   442 SetTexCoordPointer(@TextureBuffer, Length(Texture^.vb));
   317 
   443 
   318 {$IFDEF GL2}
       
   319 UpdateModelviewProjection;
   444 UpdateModelviewProjection;
   320 {$ENDIF}
       
   321 
   445 
   322 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
   446 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
   323 openglPopMatrix;
   447 openglPopMatrix;
   324 end;
   448 end;
   325 
   449 
   393 TextureBuffer[3].Y:= fb;
   517 TextureBuffer[3].Y:= fb;
   394 
   518 
   395 SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
   519 SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
   396 SetTexCoordPointer(@TextureBuffer[0], Length(VertexBuffer));
   520 SetTexCoordPointer(@TextureBuffer[0], Length(VertexBuffer));
   397 
   521 
   398 {$IFDEF GL2}
       
   399 UpdateModelviewProjection;
   522 UpdateModelviewProjection;
   400 {$ENDIF}
       
   401 
   523 
   402 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   524 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   403 
   525 
   404 openglPopMatrix;
   526 openglPopMatrix;
   405 
   527 
   465 VertexBuffer[3].Y:= hh;
   587 VertexBuffer[3].Y:= hh;
   466 
   588 
   467 SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
   589 SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
   468 SetTexCoordPointer(@Texture^.tb, Length(VertexBuffer));
   590 SetTexCoordPointer(@Texture^.tb, Length(VertexBuffer));
   469 
   591 
   470 {$IFDEF GL2}
       
   471 UpdateModelviewProjection;
   592 UpdateModelviewProjection;
   472 {$ENDIF}
       
   473 
   593 
   474 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   594 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   475 
   595 
   476 openglPopMatrix;
   596 openglPopMatrix;
   477 
   597 
   549 
   669 
   550     openglPushMatrix;
   670     openglPushMatrix;
   551     openglTranslatef(WorldDx, WorldDy, 0);
   671     openglTranslatef(WorldDx, WorldDy, 0);
   552     glLineWidth(Width);
   672     glLineWidth(Width);
   553 
   673 
   554     {$IFDEF GL2}
       
   555     UpdateModelviewProjection;
   674     UpdateModelviewProjection;
   556     {$ENDIF}
       
   557 
   675 
   558     Tint(r, g, b, a);
   676     Tint(r, g, b, a);
   559     VertexBuffer[0].X:= X0;
   677     VertexBuffer[0].X:= X0;
   560     VertexBuffer[0].Y:= Y0;
   678     VertexBuffer[0].Y:= Y0;
   561     VertexBuffer[1].X:= X1;
   679     VertexBuffer[1].X:= X1;
   678     TextureBuffer[3].Y:= b;
   796     TextureBuffer[3].Y:= b;
   679 
   797 
   680     SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
   798     SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
   681     SetTexCoordPointer(@TextureBuffer[0], Length(VertexBuffer));
   799     SetTexCoordPointer(@TextureBuffer[0], Length(VertexBuffer));
   682 
   800 
   683 {$IFDEF GL2}
       
   684     UpdateModelviewProjection;
   801     UpdateModelviewProjection;
   685 {$ENDIF}
       
   686 
   802 
   687     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   803     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   688 
   804 
   689     openglPopMatrix;
   805     openglPopMatrix;
   690 end;
   806 end;
   762     openglUseColorOnly(false);
   878     openglUseColorOnly(false);
   763 end;
   879 end;
   764 
   880 
   765 procedure DrawWaterBody(pVertexBuffer: Pointer);
   881 procedure DrawWaterBody(pVertexBuffer: Pointer);
   766 begin
   882 begin
   767 {$IFDEF GL2}
       
   768         UpdateModelviewProjection;
   883         UpdateModelviewProjection;
   769 {$ENDIF}
       
   770 
   884 
   771         BeginWater;
   885         BeginWater;
       
   886 
   772         if SuddenDeathDmg then
   887         if SuddenDeathDmg then
   773             SetColorPointer(@SDWaterColorArray[0], 4)
   888             SetColorPointer(@SDWaterColorArray[0], 4)
   774         else
   889         else
   775             SetColorPointer(@WaterColorArray[0], 4);
   890             SetColorPointer(@WaterColorArray[0], 4);
   776 
   891