hedgewars/uRender.pas
changeset 7080 dbf43c07a507
parent 7069 bcf9d8e64e92
child 7111 5ba5a92d74fb
equal deleted inserted replaced
7079:939f53515489 7080:dbf43c07a507
    20 
    20 
    21 unit uRender;
    21 unit uRender;
    22 
    22 
    23 interface
    23 interface
    24 
    24 
    25 uses SDLh, uTypes, GLunit, uConsts;
    25 uses SDLh, uTypes, GLunit, uConsts, uTextures;
    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);
    28 procedure DrawSprite            (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
    29 procedure DrawSpriteFromRect    (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
    29 procedure DrawSpriteFromRect    (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
    30 procedure DrawSpriteClipped     (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
    30 procedure DrawSpriteClipped     (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
    69 DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture)
    69 DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture)
    70 end;
    70 end;
    71 
    71 
    72 procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
    72 procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
    73 var rr: TSDL_Rect;
    73 var rr: TSDL_Rect;
    74     _l, _r, _t, _b: real;
    74     VertexBuffer, TextureBuffer: TVertexRect;
    75     VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
       
    76 begin
    75 begin
    77 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then
    76 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then
    78     exit;
    77     exit;
    79 
    78 
    80 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
    79 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
    86 rr.x:= X;
    85 rr.x:= X;
    87 rr.y:= Y;
    86 rr.y:= Y;
    88 rr.w:= W;
    87 rr.w:= W;
    89 rr.h:= H;
    88 rr.h:= H;
    90 
    89 
    91 _l:= r^.x / SourceTexture^.w * SourceTexture^.rx;
    90 glBindTexture(GL_TEXTURE_2D, SourceTexture^.atlas^.id);
    92 _r:= (r^.x + r^.w) / SourceTexture^.w * SourceTexture^.rx;
    91 
    93 _t:= r^.y / SourceTexture^.h * SourceTexture^.ry;
    92 ComputeTexcoords(SourceTexture, r, @TextureBuffer);
    94 _b:= (r^.y + r^.h) / SourceTexture^.h * SourceTexture^.ry;
       
    95 
       
    96 glBindTexture(GL_TEXTURE_2D, SourceTexture^.id);
       
    97 
    93 
    98 VertexBuffer[0].X:= X;
    94 VertexBuffer[0].X:= X;
    99 VertexBuffer[0].Y:= Y;
    95 VertexBuffer[0].Y:= Y;
   100 VertexBuffer[1].X:= rr.w + X;
    96 VertexBuffer[1].X:= rr.w + X;
   101 VertexBuffer[1].Y:= Y;
    97 VertexBuffer[1].Y:= Y;
   102 VertexBuffer[2].X:= rr.w + X;
    98 VertexBuffer[2].X:= rr.w + X;
   103 VertexBuffer[2].Y:= rr.h + Y;
    99 VertexBuffer[2].Y:= rr.h + Y;
   104 VertexBuffer[3].X:= X;
   100 VertexBuffer[3].X:= X;
   105 VertexBuffer[3].Y:= rr.h + Y;
   101 VertexBuffer[3].Y:= rr.h + Y;
   106 
   102 
   107 TextureBuffer[0].X:= _l;
       
   108 TextureBuffer[0].Y:= _t;
       
   109 TextureBuffer[1].X:= _r;
       
   110 TextureBuffer[1].Y:= _t;
       
   111 TextureBuffer[2].X:= _r;
       
   112 TextureBuffer[2].Y:= _b;
       
   113 TextureBuffer[3].X:= _l;
       
   114 TextureBuffer[3].Y:= _b;
       
   115 
       
   116 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
   103 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
   117 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
   104 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
   118 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   105 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   119 end;
   106 end;
   120 
   107 
   128 
   115 
   129 glPushMatrix;
   116 glPushMatrix;
   130 glTranslatef(X, Y, 0);
   117 glTranslatef(X, Y, 0);
   131 glScalef(Scale, Scale, 1);
   118 glScalef(Scale, Scale, 1);
   132 
   119 
   133 glBindTexture(GL_TEXTURE_2D, Texture^.id);
   120 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id);
   134 
   121 
   135 glVertexPointer(2, GL_FLOAT, 0, @Texture^.vb);
   122 glVertexPointer(2, GL_FLOAT, 0, @Texture^.vb);
   136 glTexCoordPointer(2, GL_FLOAT, 0, @Texture^.tb);
   123 glTexCoordPointer(2, GL_FLOAT, 0, @Texture^.tb);
   137 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
   124 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
   138 
   125 
   143 begin
   130 begin
   144     DrawTextureRotatedF(Texture, Scale, 0, 0, X, Y, Frame, Dir, w, h, 0)
   131     DrawTextureRotatedF(Texture, Scale, 0, 0, X, Y, Frame, Dir, w, h, 0)
   145 end;
   132 end;
   146 
   133 
   147 procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real);
   134 procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real);
   148 var ft, fb, fl, fr: GLfloat;
   135 var hw, nx, ny: LongInt;
   149     hw, nx, ny: LongInt;
   136     r: TSDL_Rect;
   150     VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
   137     VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
   151 begin
   138 begin
   152 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
   139 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
   153 if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then
   140 if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then
   154     exit;
   141     exit;
   170 hw:= w div (2 div Dir);
   157 hw:= w div (2 div Dir);
   171 
   158 
   172 nx:= round(Texture^.w / w); // number of horizontal frames
   159 nx:= round(Texture^.w / w); // number of horizontal frames
   173 ny:= round(Texture^.h / h); // number of vertical frames
   160 ny:= round(Texture^.h / h); // number of vertical frames
   174 
   161 
   175 ft:= (Frame mod ny) * Texture^.ry / ny;
   162 r.y:=(Frame mod ny) * h;
   176 fb:= ((Frame mod ny) + 1) * Texture^.ry / ny;
   163 r.x:=(Frame div ny) * w;
   177 fl:= (Frame div ny) * Texture^.rx / nx;
   164 r.w:=w;
   178 fr:= ((Frame div ny) + 1) * Texture^.rx / nx;
   165 r.h:=h;
   179 
   166 ComputeTexcoords(Texture, @r, @TextureBuffer);
   180 glBindTexture(GL_TEXTURE_2D, Texture^.id);
   167 
       
   168 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id);
   181 
   169 
   182 VertexBuffer[0].X:= -hw;
   170 VertexBuffer[0].X:= -hw;
   183 VertexBuffer[0].Y:= w / -2;
   171 VertexBuffer[0].Y:= w / -2;
   184 VertexBuffer[1].X:= hw;
   172 VertexBuffer[1].X:= hw;
   185 VertexBuffer[1].Y:= w / -2;
   173 VertexBuffer[1].Y:= w / -2;
   186 VertexBuffer[2].X:= hw;
   174 VertexBuffer[2].X:= hw;
   187 VertexBuffer[2].Y:= w / 2;
   175 VertexBuffer[2].Y:= w / 2;
   188 VertexBuffer[3].X:= -hw;
   176 VertexBuffer[3].X:= -hw;
   189 VertexBuffer[3].Y:= w / 2;
   177 VertexBuffer[3].Y:= w / 2;
   190 
   178 
   191 TextureBuffer[0].X:= fl;
       
   192 TextureBuffer[0].Y:= ft;
       
   193 TextureBuffer[1].X:= fr;
       
   194 TextureBuffer[1].Y:= ft;
       
   195 TextureBuffer[2].X:= fr;
       
   196 TextureBuffer[2].Y:= fb;
       
   197 TextureBuffer[3].X:= fl;
       
   198 TextureBuffer[3].Y:= fb;
       
   199 
       
   200 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
   179 glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
   201 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
   180 glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
   202 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   181 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   203 
   182 
   204 glPopMatrix
   183 glPopMatrix
   248     end
   227     end
   249 else
   228 else
   250     glRotatef(Angle, 0, 0,  1);
   229     glRotatef(Angle, 0, 0,  1);
   251 
   230 
   252 
   231 
   253 glBindTexture(GL_TEXTURE_2D, Texture^.id);
   232 glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id);
   254 
   233 
   255 VertexBuffer[0].X:= -hw;
   234 VertexBuffer[0].X:= -hw;
   256 VertexBuffer[0].Y:= -hh;
   235 VertexBuffer[0].Y:= -hh;
   257 VertexBuffer[1].X:= hw;
   236 VertexBuffer[1].X:= hw;
   258 VertexBuffer[1].Y:= -hh;
   237 VertexBuffer[1].Y:= -hh;
   405     glDisable(GL_LINE_SMOOTH);
   384     glDisable(GL_LINE_SMOOTH);
   406 end;
   385 end;
   407 
   386 
   408 
   387 
   409 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real);
   388 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real);
   410 const VertexBuffer: array [0..3] of TVertex2f = (
   389 const VertexBuffers: array[0..1] of TVertexRect = (
   411         (X: -16; Y: -16),
   390         ((x: -16; y: -16),
   412         (X:  16; Y: -16),
   391          (x:  16; y: -16),
   413         (X:  16; Y:  16),
   392          (x:  16; y:  16),
   414         (X: -16; Y:  16));
   393          (x: -16; y:  16)),
   415 var l, r, t, b: real;
   394         ((x:  16; y: -16),
       
   395          (x: -16; y: -16),
       
   396          (x: -16; y:  16),
       
   397          (x:  16; y:  16)));
       
   398 var r: TSDL_Rect;
   416     TextureBuffer: array [0..3] of TVertex2f;
   399     TextureBuffer: array [0..3] of TVertex2f;
   417 begin
   400 begin
   418     // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
   401     // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
   419     if (abs(X) > 32) and ((abs(X) - 16) * cScaleFactor > cScreenWidth) then
   402     if (abs(X) > 32) and ((abs(X) - 16) * cScaleFactor > cScreenWidth) then
   420         exit;
   403         exit;
   421     if (abs(Y) > 32) and ((abs(Y - 0.5 * cScreenHeight) - 16) * cScaleFactor > cScreenHeight) then
   404     if (abs(Y) > 32) and ((abs(Y - 0.5 * cScreenHeight) - 16) * cScaleFactor > cScreenHeight) then
   422         exit;
   405         exit;
   423 
   406 
   424     t:= Pos * 32 / HHTexture^.h;
   407     r.x:=Step * 32;
   425     b:= (Pos + 1) * 32 / HHTexture^.h;
   408     r.y:=Pos * 32;
   426 
   409     r.w:=32;
   427     if Dir = -1 then
   410     r.h:=32;
   428         begin
   411     ComputeTexcoords(HHTexture, @r, @TextureBuffer);
   429         l:= (Step + 1) * 32 / HHTexture^.w;
       
   430         r:= Step * 32 / HHTexture^.w
       
   431         end
       
   432     else
       
   433         begin
       
   434         l:= Step * 32 / HHTexture^.w;
       
   435         r:= (Step + 1) * 32 / HHTexture^.w
       
   436     end;
       
   437 
       
   438 
   412 
   439     glPushMatrix();
   413     glPushMatrix();
   440     glTranslatef(X, Y, 0);
   414     glTranslatef(X, Y, 0);
   441     glRotatef(Angle, 0, 0, 1);
   415     glRotatef(Angle, 0, 0, 1);
   442 
   416 
   443     glBindTexture(GL_TEXTURE_2D, HHTexture^.id);
   417     glBindTexture(GL_TEXTURE_2D, HHTexture^.atlas^.id);
   444 
   418     if Dir = -1 then
   445     TextureBuffer[0].X:= l;
   419         glVertexPointer(2, GL_FLOAT, 0, @VertexBuffers[1][0])
   446     TextureBuffer[0].Y:= t;
   420     else
   447     TextureBuffer[1].X:= r;
   421         glVertexPointer(2, GL_FLOAT, 0, @VertexBuffers[0][0]);
   448     TextureBuffer[1].Y:= t;
       
   449     TextureBuffer[2].X:= r;
       
   450     TextureBuffer[2].Y:= b;
       
   451     TextureBuffer[3].X:= l;
       
   452     TextureBuffer[3].Y:= b;
       
   453 
       
   454     glVertexPointer(2, GL_FLOAT, 0, @VertexBuffer[0]);
       
   455     glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
   422     glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
   456     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
   423     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
   457 
   424 
   458     glPopMatrix
   425     glPopMatrix
   459 end;
   426 end;
   460 
   427 
   461 procedure DrawScreenWidget(widget: POnScreenWidget);
   428 procedure DrawScreenWidget(widget: POnScreenWidget);