hedgewars/uRender.pas
changeset 12119 3374e0f67f39
parent 11824 3f1f8f79fcdb
child 12189 31184d9b9bfc
equal deleted inserted replaced
12118:4f567f7a08e8 12119:3374e0f67f39
    32 procedure DrawSprite            (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
    32 procedure DrawSprite            (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
    33 procedure DrawSpriteFromRect    (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
    33 procedure DrawSpriteFromRect    (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
    34 procedure DrawSpriteClipped     (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
    34 procedure DrawSpriteClipped     (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
    35 procedure DrawSpriteRotated     (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
    35 procedure DrawSpriteRotated     (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
    36 procedure DrawSpriteRotatedF    (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
    36 procedure DrawSpriteRotatedF    (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
       
    37 procedure DrawSpritePivotedF(Sprite: TSprite; X, Y, Frame, Dir, PivotX, PivotY: LongInt; Angle: real);
    37 
    38 
    38 procedure DrawTexture           (X, Y: LongInt; Texture: PTexture); inline;
    39 procedure DrawTexture           (X, Y: LongInt; Texture: PTexture); inline;
    39 procedure DrawTexture           (X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
    40 procedure DrawTexture           (X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
    40 procedure DrawTexture2          (X, Y: LongInt; Texture: PTexture; Scale, Overlap: GLfloat);
    41 procedure DrawTexture2          (X, Y: LongInt; Texture: PTexture; Scale, Overlap: GLfloat);
    41 procedure DrawTextureFromRect   (X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
    42 procedure DrawTextureFromRect   (X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
    71 
    72 
    72 // call this to finish the rendering of current frame
    73 // call this to finish the rendering of current frame
    73 procedure FinishRender();
    74 procedure FinishRender();
    74 
    75 
    75 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline;
    76 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline;
       
    77 function isCircleOffscreen(X, Y, RadiusSquared: LongInt): boolean; inline;
    76 
    78 
    77 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen
    79 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen
    78 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline;
    80 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline;
    79 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline;
    81 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline;
    80 
    82 
   143 {$ENDIF}
   145 {$ENDIF}
   144 
   146 
   145 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline;
   147 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline;
   146 begin
   148 begin
   147     isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0);
   149     isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0);
       
   150 end;
       
   151 
       
   152 function isCircleOffscreen(X, Y, RadiusSquared: LongInt): boolean; inline;
       
   153 var dRightX, dBottomY, dLeftX, dTopY: LongInt;
       
   154 begin
       
   155     dRightX:= (X - ViewRightX);
       
   156     dBottomY:= (Y - ViewBottomY);
       
   157     dLeftX:= (ViewLeftX - X);
       
   158     dTopY:= (ViewTopY - Y);
       
   159     isCircleOffscreen:= 
       
   160         ((dRightX > 0) and (sqr(dRightX) > RadiusSquared)) or
       
   161         ((dBottomY > 0) and (sqr(dBottomY) > RadiusSquared)) or
       
   162         ((dLeftX > 0) and (sqr(dLeftX) > RadiusSquared)) or
       
   163         ((dTopY > 0) and (sqr(dTopY) > RadiusSquared))
   148 end;
   164 end;
   149 
   165 
   150 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline;
   166 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline;
   151 begin
   167 begin
   152     if X > ViewRightX then exit(1);
   168     if X > ViewRightX then exit(1);
  1129 procedure DrawSpriteRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
  1145 procedure DrawSpriteRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
  1130 begin
  1146 begin
  1131 
  1147 
  1132 if Angle <> 0  then
  1148 if Angle <> 0  then
  1133     begin
  1149     begin
  1134     // sized doubled because the sprite might occupy up to 1.4 * of it's
  1150     // Check the bounding circle 
  1135     // original size in each dimension, because it is rotated
  1151     if isCircleOffscreen(X, Y, sqr(SpritesData[Sprite].Width) + sqr(SpritesData[Sprite].Height)) then
  1136     if isDxAreaOffscreen(X - SpritesData[Sprite].Width, 2 * SpritesData[Sprite].Width) <> 0 then
       
  1137         exit;
       
  1138     if isDYAreaOffscreen(Y - SpritesData[Sprite].Height, 2 * SpritesData[Sprite].Height) <> 0 then
       
  1139         exit;
  1152         exit;
  1140     end
  1153     end
  1141 else
  1154 else
  1142     begin
  1155     begin
  1143     if isDxAreaOffscreen(X - SpritesData[Sprite].Width div 2, SpritesData[Sprite].Width) <> 0 then
  1156     if isDxAreaOffscreen(X - SpritesData[Sprite].Width div 2, SpritesData[Sprite].Width) <> 0 then
  1160 
  1173 
  1161 DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame);
  1174 DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame);
  1162 
  1175 
  1163 openglPopMatrix;
  1176 openglPopMatrix;
  1164 
  1177 
       
  1178 end;
       
  1179 
       
  1180 procedure DrawSpritePivotedF(Sprite: TSprite; X, Y, Frame, Dir, PivotX, PivotY: LongInt; Angle: real);
       
  1181 begin
       
  1182 if Angle <> 0  then
       
  1183     begin
       
  1184     // Check the bounding circle 
       
  1185     // Assuming the pivot point is inside the sprite's rectangle, the farthest possible point is 3/2 of its diagonal away from the center
       
  1186     if isCircleOffscreen(X, Y, 9 * (sqr(SpritesData[Sprite].Width) + sqr(SpritesData[Sprite].Height)) div 4) then
       
  1187         exit;
       
  1188     end
       
  1189 else
       
  1190     begin
       
  1191     if isDxAreaOffscreen(X - SpritesData[Sprite].Width div 2, SpritesData[Sprite].Width) <> 0 then
       
  1192         exit;
       
  1193     if isDYAreaOffscreen(Y - SpritesData[Sprite].Height div 2 , SpritesData[Sprite].Height) <> 0 then
       
  1194         exit;
       
  1195     end;
       
  1196 
       
  1197 openglPushMatrix;
       
  1198 openglTranslatef(X, Y, 0);
       
  1199 
       
  1200 // mirror
       
  1201 if Dir < 0 then
       
  1202     openglScalef(-1.0, 1.0, 1.0);
       
  1203 
       
  1204 // apply rotation around the pivot after (conditional) mirroring
       
  1205 if Angle <> 0  then
       
  1206     begin
       
  1207     openglTranslatef(PivotX, PivotY, 0);
       
  1208     openglRotatef(Angle, 0, 0, 1);
       
  1209     openglTranslatef(-PivotX, -PivotY, 0);
       
  1210     end;
       
  1211 
       
  1212 DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame);
       
  1213 
       
  1214 openglPopMatrix;
  1165 end;
  1215 end;
  1166 
  1216 
  1167 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
  1217 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
  1168 begin
  1218 begin
  1169 
  1219