hedgewars/uRender.pas
changeset 7304 8b3575750cd2
parent 7188 580cd247511e
child 7377 1aceade403ba
equal deleted inserted replaced
7301:bea42438a2ec 7304:8b3575750cd2
    23 interface
    23 interface
    24 
    24 
    25 uses SDLh, uTypes, GLunit, uConsts, uTextures, math;
    25 uses SDLh, uTypes, GLunit, uConsts, uTextures, math;
    26 
    26 
    27 procedure DrawSprite            (Sprite: TSprite; X, Y, Frame: LongInt);
    27 procedure DrawSprite            (Sprite: TSprite; X, Y, Frame: LongInt);
    28 procedure DrawSprite            (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
       
    29 procedure DrawSpriteFromRect    (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
    28 procedure DrawSpriteFromRect    (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
    30 procedure DrawSpriteClipped     (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
    29 procedure DrawSpriteClipped     (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
    31 procedure DrawSpriteRotated     (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
    30 procedure DrawSpriteRotated     (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
    32 procedure DrawSpriteRotatedF    (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
    31 procedure DrawSpriteRotatedF    (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
    33 
    32 
   132 begin
   131 begin
   133 DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture)
   132 DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture)
   134 end;
   133 end;
   135 
   134 
   136 procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
   135 procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
   137 var rr: TSDL_Rect;
   136 var 
       
   137     rr: TSDL_Rect;
   138     VertexBuffer, TextureBuffer: TVertexRect;
   138     VertexBuffer, TextureBuffer: TVertexRect;
   139 begin
   139     _l, _r, _t, _b: GLfloat;
   140 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then
   140 begin
   141     exit;
   141     if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then
   142 
   142         exit;
   143 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
   143 
   144 if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then
   144     // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
   145     exit;
   145     if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then
   146 if (abs(Y) > H) and ((abs(Y + H / 2 - (0.5 * cScreenHeight)) - H / 2) > cScreenHeight / cScaleFactor) then
   146         exit;
   147     exit;
   147     if (abs(Y) > H) and ((abs(Y + H / 2 - (0.5 * cScreenHeight)) - H / 2) > cScreenHeight / cScaleFactor) then
   148 
   148         exit;
   149 rr.x:= X;
   149 
   150 rr.y:= Y;
   150     rr.x:= X;
   151 rr.w:= W;
   151     rr.y:= Y;
   152 rr.h:= H;
   152     rr.w:= W;
   153 
   153     rr.h:= H;
   154 glBindTexture(GL_TEXTURE_2D, SourceTexture^.atlas^.id);
   154 
   155 
   155     glBindTexture(GL_TEXTURE_2D, SourceTexture^.atlas^.id);
   156 ComputeTexcoords(SourceTexture, r, @TextureBuffer);
   156 
   157 
   157     ComputeTexcoords(SourceTexture, r, @TextureBuffer);
   158 VertexBuffer[0].X:= X;
   158 
   159 VertexBuffer[0].Y:= Y;
   159     _l:= X + SourceTexture^.cropInfo.l;
   160 VertexBuffer[1].X:= rr.w + X;
   160     _r:= X + rr.w - SourceTexture^.cropInfo.l - SourceTexture^.cropInfo.r;
   161 VertexBuffer[1].Y:= Y;
   161     _t:= Y + SourceTexture^.cropInfo.t;
   162 VertexBuffer[2].X:= rr.w + X;
   162     _b:= Y + rr.h - SourceTexture^.cropInfo.t - SourceTexture^.cropInfo.b;
   163 VertexBuffer[2].Y:= rr.h + Y;
   163 
   164 VertexBuffer[3].X:= X;
   164 
   165 VertexBuffer[3].Y:= rr.h + Y;
   165     VertexBuffer[0].X:= _l;
   166 
   166     VertexBuffer[0].Y:= _t;
   167 SetVertexPointer(@VertexBuffer[0]);
   167     VertexBuffer[1].X:= _r;
   168 SetTexCoordPointer(@TextureBuffer[0]);
   168     VertexBuffer[1].Y:= _t;
   169 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   169     VertexBuffer[2].X:= _r;
       
   170     VertexBuffer[2].Y:= _b;
       
   171     VertexBuffer[3].X:= _l;
       
   172     VertexBuffer[3].Y:= _b;
       
   173 
       
   174     SetVertexPointer(@VertexBuffer[0]);
       
   175     //SetTexCoordPointer(@TextureBuffer[0]);
       
   176     SetTexCoordPointer(@SourceTexture^.tb[0]);
       
   177     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   170 end;
   178 end;
   171 
   179 
   172 procedure DrawTexture(X, Y: LongInt; Texture: PTexture); inline;
   180 procedure DrawTexture(X, Y: LongInt; Texture: PTexture); inline;
   173 begin
   181 begin
   174     DrawTexture(X, Y, Texture, 1.0);
   182     DrawTexture(X, Y, Texture, 1.0);
   196 
   204 
   197 procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real);
   205 procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real);
   198 var hw, nx, ny: LongInt;
   206 var hw, nx, ny: LongInt;
   199     r: TSDL_Rect;
   207     r: TSDL_Rect;
   200     VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
   208     VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
   201 begin
   209     _l, _r, _t, _b: GLfloat;
       
   210 begin
       
   211 
       
   212     while (Frame > 0) and (Texture <> nil) do
       
   213     begin
       
   214         Texture:= Texture^.nextFrame;
       
   215         dec(Frame);
       
   216     end;
       
   217 
       
   218     if Texture = nil then
       
   219         exit;
       
   220 
   202 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
   221 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
   203 if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then
   222 if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then
   204     exit;
   223     exit;
   205 if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then
   224 if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then
   206     exit;
   225     exit;
   216 // Any reason for this call? And why only in t direction, not s?
   235 // Any reason for this call? And why only in t direction, not s?
   217 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   236 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   218 
   237 
   219 hw:= w div (2 div Dir);
   238 hw:= w div (2 div Dir);
   220 
   239 
   221 nx:= round(Texture^.w / w); // number of horizontal frames
   240 r.y:=0;
   222 ny:= round(Texture^.h / h); // number of vertical frames
   241 r.x:=0;
   223 
       
   224 r.y:=(Frame mod ny) * h;
       
   225 r.x:=(Frame div ny) * w;
       
   226 r.w:=w;
   242 r.w:=w;
   227 r.h:=h;
   243 r.h:=h;
   228 ComputeTexcoords(Texture, @r, @TextureBuffer);
   244 ComputeTexcoords(Texture, @r, @TextureBuffer);
   229 
   245 
   230 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id);
   246 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id);
   231 
   247 
   232 VertexBuffer[0].X:= -hw;
   248 _l:= -hw + Texture^.cropInfo.l;
   233 VertexBuffer[0].Y:= w / -2;
   249 _t:= w/-2 + Texture^.cropInfo.t;
   234 VertexBuffer[1].X:= hw;
   250 _r:= hw - Texture^.cropInfo.l - Texture^.cropInfo.r;
   235 VertexBuffer[1].Y:= w / -2;
   251 _b:= w/2 - Texture^.cropInfo.t - Texture^.cropInfo.b;
   236 VertexBuffer[2].X:= hw;
   252 
   237 VertexBuffer[2].Y:= w / 2;
   253 VertexBuffer[0].X:= _l;
   238 VertexBuffer[3].X:= -hw;
   254 VertexBuffer[0].Y:= _t;
   239 VertexBuffer[3].Y:= w / 2;
   255 VertexBuffer[1].X:= _r;
       
   256 VertexBuffer[1].Y:= _t;
       
   257 VertexBuffer[2].X:= _r;
       
   258 VertexBuffer[2].Y:= _b;
       
   259 VertexBuffer[3].X:= _l;
       
   260 VertexBuffer[3].Y:= _b;
   240 
   261 
   241 SetVertexPointer(@VertexBuffer[0]);
   262 SetVertexPointer(@VertexBuffer[0]);
   242 SetTexCoordPointer(@TextureBuffer[0]);
   263 //SetTexCoordPointer(@TextureBuffer[0]);
       
   264 SetTexCoordPointer(@Texture^.tb[0]);
   243 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   265 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   244 
   266 
   245 ResetModelview;
   267 ResetModelview;
   246 end;
   268 end;
   247 
   269 
   269 ResetModelview;
   291 ResetModelview;
   270 end;
   292 end;
   271 
   293 
   272 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
   294 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
   273 var VertexBuffer: array [0..3] of TVertex2f;
   295 var VertexBuffer: array [0..3] of TVertex2f;
       
   296     _l, _r, _t, _b: GLfloat;
   274 begin
   297 begin
   275 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
   298 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
   276 if (abs(X) > 2 * hw) and ((abs(X) - hw) > cScreenWidth / cScaleFactor) then
   299 if (abs(X) > 2 * hw) and ((abs(X) - hw) > cScreenWidth / cScaleFactor) then
   277     exit;
   300     exit;
   278 if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then
   301 if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then
   289     SetRotation(Angle, 1.0);
   312     SetRotation(Angle, 1.0);
   290 UpdateModelview;
   313 UpdateModelview;
   291 
   314 
   292 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id);
   315 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id);
   293 
   316 
   294 VertexBuffer[0].X:= -hw;
   317 _l:= -hw + Texture^.cropInfo.l;
   295 VertexBuffer[0].Y:= -hh;
   318 _t:= -hh + Texture^.cropInfo.t;
   296 VertexBuffer[1].X:= hw;
   319 _r:= hw - Texture^.cropInfo.l - Texture^.cropInfo.r;
   297 VertexBuffer[1].Y:= -hh;
   320 _b:= hh - Texture^.cropInfo.t - Texture^.cropInfo.b;
   298 VertexBuffer[2].X:= hw;
   321 
   299 VertexBuffer[2].Y:= hh;
   322 VertexBuffer[0].X:= _l;
   300 VertexBuffer[3].X:= -hw;
   323 VertexBuffer[0].Y:= _t;
   301 VertexBuffer[3].Y:= hh;
   324 VertexBuffer[1].X:= _r;
       
   325 VertexBuffer[1].Y:= _t;
       
   326 VertexBuffer[2].X:= _r;
       
   327 VertexBuffer[2].Y:= _b;
       
   328 VertexBuffer[3].X:= _l;
       
   329 VertexBuffer[3].Y:= _b;
   302 
   330 
   303 SetVertexPointer(@VertexBuffer[0]);
   331 SetVertexPointer(@VertexBuffer[0]);
   304 SetTexCoordPointer(@Texture^.tb);
   332 SetTexCoordPointer(@Texture^.tb);
   305 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   333 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   306 
   334 
   307 ResetModelview;
   335 ResetModelview;
   308 end;
   336 end;
   309 
   337 
   310 procedure DrawSprite(Sprite: TSprite; X, Y, Frame: LongInt);
   338 procedure DrawSprite(Sprite: TSprite; X, Y, Frame: LongInt);
   311 var row, col, numFramesFirstCol: LongInt;
   339 var 
       
   340     r: TSDL_Rect;
       
   341     tex: PTexture;
   312 begin
   342 begin
   313     if SpritesData[Sprite].imageHeight = 0 then
   343     if SpritesData[Sprite].imageHeight = 0 then
   314         exit;
   344         exit;
   315     numFramesFirstCol:= SpritesData[Sprite].imageHeight div SpritesData[Sprite].Height;
   345 
   316     row:= Frame mod numFramesFirstCol;
   346     tex:= SpritesData[Sprite].Texture;
   317     col:= Frame div numFramesFirstCol;
   347 
   318     DrawSprite(Sprite, X, Y, col, row);
   348     while (Frame > 0) and (tex <> nil) do
   319 end;
   349     begin
   320 
   350         tex:= tex^.nextFrame;
   321 procedure DrawSprite(Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
   351         dec(Frame);
   322 var r: TSDL_Rect;
   352     end;
   323 begin
   353 
   324     r.x:= FrameX * SpritesData[Sprite].Width;
   354     if (tex = nil) or (tex^.w = 0) or (tex^.h = 0) then
       
   355         exit;
       
   356 
       
   357     r.x:= 0;
   325     r.w:= SpritesData[Sprite].Width;
   358     r.w:= SpritesData[Sprite].Width;
   326     r.y:= FrameY * SpritesData[Sprite].Height;
   359     r.y:= 0;
   327     r.h:= SpritesData[Sprite].Height;
   360     r.h:= SpritesData[Sprite].Height;
   328     DrawTextureFromRect(X, Y, @r, SpritesData[Sprite].Texture)
   361     DrawTextureFromRect(X, Y, @r, tex)
   329 end;
   362 end;
   330 
   363 
   331 procedure DrawSpriteClipped(Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
   364 procedure DrawSpriteClipped(Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
   332 var r: TSDL_Rect;
   365 var r: TSDL_Rect;
   333 begin
   366 begin