hedgewars/uRender.pas
changeset 10327 c3770d87311b
parent 10326 1748eed62a95
child 10328 1eaae604d7a4
equal deleted inserted replaced
10326:1748eed62a95 10327:c3770d87311b
    79 procedure CreateFramebuffer(var frame, depth, tex: GLuint);
    79 procedure CreateFramebuffer(var frame, depth, tex: GLuint);
    80 procedure DeleteFramebuffer(var frame, depth, tex: GLuint);
    80 procedure DeleteFramebuffer(var frame, depth, tex: GLuint);
    81 
    81 
    82 procedure EnableTexture(enable:Boolean);
    82 procedure EnableTexture(enable:Boolean);
    83 
    83 
    84 procedure SetTexCoordPointer(p: Pointer;n: Integer);
    84 procedure SetTexCoordPointer(p: Pointer;n: Integer); inline;
    85 procedure SetVertexPointer(p: Pointer;n: Integer);
    85 procedure SetVertexPointer(p: Pointer;n: Integer); inline;
    86 procedure SetColorPointer(p: Pointer;n: Integer);
    86 procedure SetColorPointer(p: Pointer;n: Integer); inline;
    87 
    87 
    88 procedure UpdateModelviewProjection(); inline;
    88 procedure UpdateModelviewProjection(); inline;
    89 
    89 
    90 procedure openglLoadIdentity    (); inline;
    90 procedure openglLoadIdentity    (); inline;
    91 procedure openglTranslProjMatrix(X, Y, Z: GLFloat); inline;
    91 procedure openglTranslProjMatrix(X, Y, Z: GLFloat); inline;
   112 var
   112 var
   113     shaderMain: GLuint;
   113     shaderMain: GLuint;
   114     shaderWater: GLuint;
   114     shaderWater: GLuint;
   115 {$ENDIF}
   115 {$ENDIF}
   116 
   116 
   117 var LastTint: LongWord = 0;
   117 var VertexBuffer : array [0 ..59] of TVertex2f;
       
   118     TextureBuffer: array [0 .. 7] of TVertex2f;
       
   119     LastTint: LongWord = 0;
   118     LastColorPointer , LastTexCoordPointer , LastVertexPointer : Pointer;
   120     LastColorPointer , LastTexCoordPointer , LastVertexPointer : Pointer;
   119 {$IFDEF GL2}
   121 {$IFDEF GL2}
   120     LastColorPointerN, LastTexCoordPointerN, LastVertexPointerN: Integer;
   122     LastColorPointerN, LastTexCoordPointerN, LastVertexPointerN: Integer;
   121 {$ENDIF}
   123 {$ENDIF}
   122 
   124 
   579 {$HINTS ON}
   581 {$HINTS ON}
   580     glUniformMatrix4fv(uCurrentMVPLocation, 1, GL_FALSE, @mvp[0, 0]);
   582     glUniformMatrix4fv(uCurrentMVPLocation, 1, GL_FALSE, @mvp[0, 0]);
   581 {$ENDIF}
   583 {$ENDIF}
   582 end;
   584 end;
   583 
   585 
   584 procedure SetTexCoordPointer(p: Pointer; n: Integer);
   586 procedure SetTexCoordPointer(p: Pointer; n: Integer); inline;
   585 begin
   587 begin
   586 {$IFDEF GL2}
   588 {$IFDEF GL2}
   587     if (p = LastTexCoordPointer) and (n = LastTexCoordPointerN) then
   589     if (p = LastTexCoordPointer) and (n = LastTexCoordPointerN) then
   588         exit;
   590         exit;
   589     glBindBuffer(GL_ARRAY_BUFFER, tBuffer);
   591     glBindBuffer(GL_ARRAY_BUFFER, tBuffer);
   590     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n * 2, p, GL_STATIC_DRAW);
   592     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n * 2, p, GL_STATIC_DRAW);
   591     glEnableVertexAttribArray(aTexCoord);
   593     glEnableVertexAttribArray(aTexCoord);
   592     glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, pointer(0));
   594     glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, pointer(0));
   593     LastTexCoordPointer:= n;
   595     LastTexCoordPointerN:= n;
   594 {$ELSE}
   596 {$ELSE}
   595     if p = LastTexCoordPointer then
   597     if p = LastTexCoordPointer then
   596         exit;
   598         exit;
   597     n:= n;
   599     n:= n;
   598     glTexCoordPointer(2, GL_FLOAT, 0, p);
   600     glTexCoordPointer(2, GL_FLOAT, 0, p);
   599 {$ENDIF}
   601 {$ENDIF}
   600     LastTexCoordPointer:= p;
   602     LastTexCoordPointer:= p;
   601 end;
   603 end;
   602 
   604 
   603 procedure SetVertexPointer(p: Pointer; n: Integer);
   605 procedure SetVertexPointer(p: Pointer; n: Integer); inline;
   604 begin
   606 begin
   605 {$IFDEF GL2}
   607 {$IFDEF GL2}
   606     if (p = LastVertexPointer) and (n = LastVertexPointerN) then
   608     if (p = LastVertexPointer) and (n = LastVertexPointerN) then
   607         exit;
   609         exit;
   608     glBindBuffer(GL_ARRAY_BUFFER, vBuffer);
   610     glBindBuffer(GL_ARRAY_BUFFER, vBuffer);
   609     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n * 2, p, GL_STATIC_DRAW);
   611     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n * 2, p, GL_STATIC_DRAW);
   610     glEnableVertexAttribArray(aVertex);
   612     glEnableVertexAttribArray(aVertex);
   611     glVertexAttribPointer(aVertex, 2, GL_FLOAT, GL_FALSE, 0, pointer(0));
   613     glVertexAttribPointer(aVertex, 2, GL_FLOAT, GL_FALSE, 0, pointer(0));
   612     LastVertexPointer:= n;
   614     LastVertexPointerN:= n;
   613 {$ELSE}
   615 {$ELSE}
   614     if p = LastVertexPointer then
   616     if p = LastVertexPointer then
   615         exit;
   617         exit;
   616     n:= n;
   618     n:= n;
   617     glVertexPointer(2, GL_FLOAT, 0, p);
   619     glVertexPointer(2, GL_FLOAT, 0, p);
   618 {$ENDIF}
   620 {$ENDIF}
   619     LastVertexPointer:= p;
   621     LastVertexPointer:= p;
   620 end;
   622 end;
   621 
   623 
   622 procedure SetColorPointer(p: Pointer; n: Integer);
   624 procedure SetColorPointer(p: Pointer; n: Integer); inline;
   623 begin
   625 begin
   624 {$IFDEF GL2}
   626 {$IFDEF GL2}
   625     if (p = LastColorPointer) and (n = LastColorPointerN) then
   627     if (p = LastColorPointer) and (n = LastColorPointerN) then
   626         exit;
   628         exit;
   627     glBindBuffer(GL_ARRAY_BUFFER, cBuffer);
   629     glBindBuffer(GL_ARRAY_BUFFER, cBuffer);
   628     glBufferData(GL_ARRAY_BUFFER, n * 4, p, GL_STATIC_DRAW);
   630     glBufferData(GL_ARRAY_BUFFER, n * 4, p, GL_STATIC_DRAW);
   629     glEnableVertexAttribArray(aColor);
   631     glEnableVertexAttribArray(aColor);
   630     glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, pointer(0));
   632     glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, pointer(0));
   631     LastColorPointer:= n;
   633     LastColorPointerN:= n;
   632 {$ELSE}
   634 {$ELSE}
   633     if p = LastColorPointer then
   635     if p = LastColorPointer then
   634         exit;
   636         exit;
   635     n:= n;
   637     n:= n;
   636     glColorPointer(4, GL_UNSIGNED_BYTE, 0, p);
   638     glColorPointer(4, GL_UNSIGNED_BYTE, 0, p);
   721 DrawTextureFromRectDir(X, Y, W, H, r, SourceTexture, 1)
   723 DrawTextureFromRectDir(X, Y, W, H, r, SourceTexture, 1)
   722 end;
   724 end;
   723 
   725 
   724 procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt);
   726 procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt);
   725 var _l, _r, _t, _b: real;
   727 var _l, _r, _t, _b: real;
   726     VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
       
   727     xw, yh: LongInt;
   728     xw, yh: LongInt;
   728 begin
   729 begin
   729 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then
   730 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then
   730     exit;
   731     exit;
   731 
   732 
   775 TextureBuffer[2].X:= _r;
   776 TextureBuffer[2].X:= _r;
   776 TextureBuffer[2].Y:= _b;
   777 TextureBuffer[2].Y:= _b;
   777 TextureBuffer[3].X:= _l;
   778 TextureBuffer[3].X:= _l;
   778 TextureBuffer[3].Y:= _b;
   779 TextureBuffer[3].Y:= _b;
   779 
   780 
   780 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
   781 SetVertexPointer(@VertexBuffer[0], 4);
   781 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
   782 SetTexCoordPointer(@TextureBuffer[0], 4);
   782 glDrawArrays(GL_TRIANGLE_FAN, 0, High(VertexBuffer) - Low(VertexBuffer) + 1);
   783 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
   783 end;
   784 end;
   784 
   785 
   785 procedure DrawTexture(X, Y: LongInt; Texture: PTexture); inline;
   786 procedure DrawTexture(X, Y: LongInt; Texture: PTexture); inline;
   786 begin
   787 begin
   787     DrawTexture(X, Y, Texture, 1.0);
   788     DrawTexture(X, Y, Texture, 1.0);
   826 TextureBuffer[2].X:= Texture^.tb[2].X - Overlap;
   827 TextureBuffer[2].X:= Texture^.tb[2].X - Overlap;
   827 TextureBuffer[2].Y:= Texture^.tb[2].Y - Overlap;
   828 TextureBuffer[2].Y:= Texture^.tb[2].Y - Overlap;
   828 TextureBuffer[3].X:= Texture^.tb[3].X + Overlap;
   829 TextureBuffer[3].X:= Texture^.tb[3].X + Overlap;
   829 TextureBuffer[3].Y:= Texture^.tb[3].Y - Overlap;
   830 TextureBuffer[3].Y:= Texture^.tb[3].Y - Overlap;
   830 
   831 
   831 SetVertexPointer(@Texture^.vb, Length(Texture^.vb));
   832 SetVertexPointer(@Texture^.vb, 4);
   832 SetTexCoordPointer(@TextureBuffer, Length(Texture^.vb));
   833 SetTexCoordPointer(@TextureBuffer, 4);
   833 
   834 
   834 UpdateModelviewProjection;
   835 UpdateModelviewProjection;
   835 
   836 
   836 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
   837 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
   837 openglPopMatrix;
   838 openglPopMatrix;
   838 end;
   839 end;
   839 
   840 
   840 procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt);
   841 procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt);
   841 begin
   842 begin
   913 TextureBuffer[2].X:= fr;
   914 TextureBuffer[2].X:= fr;
   914 TextureBuffer[2].Y:= fb;
   915 TextureBuffer[2].Y:= fb;
   915 TextureBuffer[3].X:= fl;
   916 TextureBuffer[3].X:= fl;
   916 TextureBuffer[3].Y:= fb;
   917 TextureBuffer[3].Y:= fb;
   917 
   918 
   918 SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
   919 SetVertexPointer(@VertexBuffer[0], 4);
   919 SetTexCoordPointer(@TextureBuffer[0], Length(VertexBuffer));
   920 SetTexCoordPointer(@TextureBuffer[0], 4);
   920 
   921 
   921 UpdateModelviewProjection;
   922 UpdateModelviewProjection;
   922 
   923 
   923 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   924 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
   924 
   925 
   925 openglPopMatrix;
   926 openglPopMatrix;
   926 
   927 
   927 end;
   928 end;
   928 
   929 
   971 openglPopMatrix;
   972 openglPopMatrix;
   972 
   973 
   973 end;
   974 end;
   974 
   975 
   975 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
   976 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
   976 var VertexBuffer: array [0..3] of TVertex2f;
       
   977 begin
   977 begin
   978 
   978 
   979 if isDxAreaOffscreen(X, 2 * hw) <> 0 then
   979 if isDxAreaOffscreen(X, 2 * hw) <> 0 then
   980     exit;
   980     exit;
   981 if isDyAreaOffscreen(Y, 2 * hh) <> 0 then
   981 if isDyAreaOffscreen(Y, 2 * hh) <> 0 then
  1007 VertexBuffer[2].X:= hw;
  1007 VertexBuffer[2].X:= hw;
  1008 VertexBuffer[2].Y:= hh;
  1008 VertexBuffer[2].Y:= hh;
  1009 VertexBuffer[3].X:= -hw;
  1009 VertexBuffer[3].X:= -hw;
  1010 VertexBuffer[3].Y:= hh;
  1010 VertexBuffer[3].Y:= hh;
  1011 
  1011 
  1012 SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
  1012 SetVertexPointer(@VertexBuffer[0], 4);
  1013 SetTexCoordPointer(@Texture^.tb, Length(VertexBuffer));
  1013 SetTexCoordPointer(@Texture^.tb, 4);
  1014 
  1014 
  1015 UpdateModelviewProjection;
  1015 UpdateModelviewProjection;
  1016 
  1016 
  1017 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
  1017 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
  1018 
  1018 
  1019 openglPopMatrix;
  1019 openglPopMatrix;
  1020 
  1020 
  1021 end;
  1021 end;
  1022 
  1022 
  1090 begin
  1090 begin
  1091 DrawLine(X0, Y0, X1, Y1, Width, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF)
  1091 DrawLine(X0, Y0, X1, Y1, Width, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF)
  1092 end;
  1092 end;
  1093 
  1093 
  1094 procedure DrawLine(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte);
  1094 procedure DrawLine(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte);
  1095 var VertexBuffer: array [0..1] of TVertex2f;
       
  1096 begin
  1095 begin
  1097     glEnable(GL_LINE_SMOOTH);
  1096     glEnable(GL_LINE_SMOOTH);
  1098 
  1097 
  1099     EnableTexture(False);
  1098     EnableTexture(False);
  1100 
  1099 
  1108     VertexBuffer[0].X:= X0;
  1107     VertexBuffer[0].X:= X0;
  1109     VertexBuffer[0].Y:= Y0;
  1108     VertexBuffer[0].Y:= Y0;
  1110     VertexBuffer[1].X:= X1;
  1109     VertexBuffer[1].X:= X1;
  1111     VertexBuffer[1].Y:= Y1;
  1110     VertexBuffer[1].Y:= Y1;
  1112 
  1111 
  1113     SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
  1112     SetVertexPointer(@VertexBuffer[0], 2);
  1114     glDrawArrays(GL_LINES, 0, Length(VertexBuffer));
  1113     glDrawArrays(GL_LINES, 0, 2);
  1115     untint;
  1114     untint;
  1116 
  1115 
  1117     openglPopMatrix;
  1116     openglPopMatrix;
  1118 
  1117 
  1119     EnableTexture(True);
  1118     EnableTexture(True);
  1120 
  1119 
  1121     glDisable(GL_LINE_SMOOTH);
  1120     glDisable(GL_LINE_SMOOTH);
  1122 end;
  1121 end;
  1123 
  1122 
  1124 procedure DrawRect(rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean);
  1123 procedure DrawRect(rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean);
  1125 var VertexBuffer: array [0..3] of TVertex2f;
       
  1126 begin
  1124 begin
  1127 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
  1125 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
  1128 if (abs(rect.x) > rect.w) and ((abs(rect.x + rect.w / 2) - rect.w / 2) * 2 > ViewWidth) then
  1126 if (abs(rect.x) > rect.w) and ((abs(rect.x + rect.w / 2) - rect.w / 2) * 2 > ViewWidth) then
  1129     exit;
  1127     exit;
  1130 if (abs(rect.y) > rect.h) and ((abs(rect.y + rect.h / 2 - (cScreenHeight / 2)) - rect.h / 2) * 2 > ViewHeight) then
  1128 if (abs(rect.y) > rect.h) and ((abs(rect.y + rect.h / 2 - (cScreenHeight / 2)) - rect.h / 2) * 2 > ViewHeight) then
  1144     VertexBuffer[2].Y:= y + h;
  1142     VertexBuffer[2].Y:= y + h;
  1145     VertexBuffer[3].X:= x;
  1143     VertexBuffer[3].X:= x;
  1146     VertexBuffer[3].Y:= y + h;
  1144     VertexBuffer[3].Y:= y + h;
  1147 end;
  1145 end;
  1148 
  1146 
  1149 SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
  1147 SetVertexPointer(@VertexBuffer[0], 4);
  1150 if Fill then
  1148 if Fill then
  1151     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer))
  1149     glDrawArrays(GL_TRIANGLE_FAN, 0, 4)
  1152 else
  1150 else
  1153     glDrawArrays(GL_LINE_LOOP, 0, Length(VertexBuffer));
  1151     glDrawArrays(GL_LINE_LOOP, 0, 4);
  1154 
  1152 
  1155 untint;
  1153 untint;
  1156 
  1154 
  1157 EnableTexture(True);
  1155 EnableTexture(True);
  1158 
  1156 
  1175         CircleVertex[i].Y := Y + Radius*sin(i*pi/30);
  1173         CircleVertex[i].Y := Y + Radius*sin(i*pi/30);
  1176     end;
  1174     end;
  1177 
  1175 
  1178     EnableTexture(False);
  1176     EnableTexture(False);
  1179     glEnable(GL_LINE_SMOOTH);
  1177     glEnable(GL_LINE_SMOOTH);
  1180     openglPushMatrix;
  1178     //openglPushMatrix;
  1181     glLineWidth(Width);
  1179     glLineWidth(Width);
  1182     SetVertexPointer(@CircleVertex[0], 60);
  1180     SetVertexPointer(@CircleVertex[0], 60);
  1183     glDrawArrays(GL_LINE_LOOP, 0, 60);
  1181     glDrawArrays(GL_LINE_LOOP, 0, 60);
  1184     openglPopMatrix;
  1182     //openglPopMatrix;
  1185     EnableTexture(True);
  1183     EnableTexture(True);
  1186     glDisable(GL_LINE_SMOOTH);
  1184     glDisable(GL_LINE_SMOOTH);
  1187 end;
  1185 end;
  1188 
  1186 
  1189 
  1187 
  1192         (X: -16; Y: -16),
  1190         (X: -16; Y: -16),
  1193         (X:  16; Y: -16),
  1191         (X:  16; Y: -16),
  1194         (X:  16; Y:  16),
  1192         (X:  16; Y:  16),
  1195         (X: -16; Y:  16));
  1193         (X: -16; Y:  16));
  1196 var l, r, t, b: real;
  1194 var l, r, t, b: real;
  1197     TextureBuffer: array [0..3] of TVertex2f;
       
  1198 begin
  1195 begin
  1199     // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
  1196     // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
  1200     if (abs(X) > 32) and ((abs(X) - 16) * 2 > ViewWidth) then
  1197     if (abs(X) > 32) and ((abs(X) - 16) * 2 > ViewWidth) then
  1201         exit;
  1198         exit;
  1202     if (abs(Y) > 32) and ((abs(Y - cScreenHeight / 2) - 16) * 2 > ViewHeight) then
  1199     if (abs(Y) > 32) and ((abs(Y - cScreenHeight / 2) - 16) * 2 > ViewHeight) then
  1229     TextureBuffer[2].X:= r;
  1226     TextureBuffer[2].X:= r;
  1230     TextureBuffer[2].Y:= b;
  1227     TextureBuffer[2].Y:= b;
  1231     TextureBuffer[3].X:= l;
  1228     TextureBuffer[3].X:= l;
  1232     TextureBuffer[3].Y:= b;
  1229     TextureBuffer[3].Y:= b;
  1233 
  1230 
  1234     SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
  1231     SetVertexPointer(@VertexBuffer[0], 4);
  1235     SetTexCoordPointer(@TextureBuffer[0], Length(VertexBuffer));
  1232     SetTexCoordPointer(@TextureBuffer[0], 4);
  1236 
  1233 
  1237     UpdateModelviewProjection;
  1234     UpdateModelviewProjection;
  1238 
  1235 
  1239     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
  1236     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
  1240 
  1237 
  1241     openglPopMatrix;
  1238     openglPopMatrix;
  1242 end;
  1239 end;
  1243 
  1240 
  1244 procedure DrawScreenWidget(widget: POnScreenWidget);
  1241 procedure DrawScreenWidget(widget: POnScreenWidget);
  1313 
  1310 
  1314     openglUseColorOnly(false);
  1311     openglUseColorOnly(false);
  1315 end;
  1312 end;
  1316 
  1313 
  1317 procedure DrawWater(Alpha: byte; OffsetY, OffsetX: LongInt);
  1314 procedure DrawWater(Alpha: byte; OffsetY, OffsetX: LongInt);
  1318 var VertexBuffer : array [0..7] of TVertex2f;
  1315 var watertop, lx, rx, firsti, afteri, n: LongInt;
  1319     watertop, lx, rx, firsti, afteri, n: LongInt;
       
  1320 begin
  1316 begin
  1321 
  1317 
  1322 // those
  1318 // those
  1323 firsti:= -1;
  1319 firsti:= -1;
  1324 afteri:=  0;
  1320 afteri:=  0;