--- a/hedgewars/hwengine.pas Tue May 22 09:18:46 2012 +0200
+++ b/hedgewars/hwengine.pas Tue May 22 09:25:03 2012 +0200
@@ -31,7 +31,7 @@
uses SDLh, uMisc, uConsole, uGame, uConsts, uLand, uAmmos, uVisualGears, uGears, uStore, uWorld, uInputHandler, uSound,
uScript, uTeams, uStats, uIO, uLocale, uChat, uAI, uAIMisc, uRandom, uLandTexture, uCollisions,
- SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted
+ SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uRender, uDebug, uCommandHandlers, uLandPainted
{$IFDEF SDL13}, uTouch{$ENDIF}{$IFDEF ANDROID}, GLUnit{$ENDIF};
{$IFDEF HWLIBRARY}
@@ -419,6 +419,7 @@
uVisualGears.initModule;
uWorld.initModule;
uCaptions.initModule;
+ uRender.initModule;
end;
end;
--- a/hedgewars/uRender.pas Tue May 22 09:18:46 2012 +0200
+++ b/hedgewars/uRender.pas Tue May 22 09:25:03 2012 +0200
@@ -22,7 +22,9 @@
interface
-uses SDLh, uTypes, GLunit, uConsts, uTextures;
+uses SDLh, uTypes, GLunit, uConsts, uTextures, math;
+
+procedure initModule;
procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt);
procedure DrawSprite (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
@@ -51,11 +53,85 @@
procedure Tint (r, g, b, a: Byte); inline;
procedure Tint (c: Longword); inline;
+// This is just temporary and becomes non public once everything changed to GL2
+procedure UpdateModelview;
+procedure ResetModelview;
+procedure SetOffset(X, Y: Longint);
+procedure ResetRotation;
+
implementation
uses uVariables;
var LastTint: LongWord = 0;
+ Modelview: TMatrix4x4f;
+
+const DegToRad = 0.01745329252; // 2PI / 360
+
+procedure UpdateModelview;
+begin
+glLoadMatrixf(@Modelview[0,0]);
+end;
+
+procedure ResetModelview;
+begin
+Modelview[0,0]:= 1.0; Modelview[1,0]:=0.0; Modelview[3,0]:= 0;
+Modelview[0,1]:= 0.0; Modelview[1,1]:=1.0; Modelview[3,1]:= 0;
+UpdateModelview;
+end;
+
+procedure SetOffset(X, Y: Longint);
+begin
+Modelview[3,0]:= X;
+Modelview[3,1]:= Y;
+end;
+
+procedure AddOffset(X, Y: GLfloat); // probably want to refactor this to use integers
+begin
+Modelview[3,0]:=Modelview[3,0] + Modelview[0,0]*X + Modelview[1,0]*Y;
+Modelview[3,1]:=Modelview[3,1] + Modelview[0,1]*X + Modelview[1,1]*Y;
+end;
+
+procedure SetScale(Scale: GLfloat);
+begin
+Modelview[0,0]:= Scale;
+Modelview[1,1]:= Scale;
+end;
+
+procedure AddScale(Scale: GLfloat);
+begin
+Modelview[0,0]:= Modelview[0,0]*Scale; Modelview[1,0]:= Modelview[1,0]*Scale;
+Modelview[0,1]:= Modelview[0,1]*Scale; Modelview[1,1]:= Modelview[1,1]*Scale;
+end;
+
+procedure AddScale(X, Y: GLfloat);
+begin
+Modelview[0,0]:= Modelview[0,0]*X; Modelview[1,0]:= Modelview[1,0]*Y;
+Modelview[0,1]:= Modelview[0,1]*X; Modelview[1,1]:= Modelview[1,1]*Y;
+end;
+
+
+procedure SetRotation(Angle, ZAxis: GLfloat);
+var s, c: Extended;
+begin
+SinCos(Angle*DegToRad, s, c);
+Modelview[0,0]:= c; Modelview[1,0]:=-s*ZAxis;
+Modelview[0,1]:= s*ZAxis; Modelview[1,1]:= c;
+end;
+
+procedure ResetRotation;
+begin
+Modelview[0,0]:= 1.0; Modelview[1,0]:=0.0;
+Modelview[0,1]:= 0.0; Modelview[1,1]:=1.0;
+end;
+
+procedure LoadIdentity(out Matrix: TMatrix4x4f);
+begin
+Matrix[0,0]:= 1.0; Matrix[1,0]:=0.0; Matrix[2,0]:=0.0; Matrix[3,0]:=0.0;
+Matrix[0,1]:= 0.0; Matrix[1,1]:=1.0; Matrix[2,1]:=0.0; Matrix[3,1]:=0.0;
+Matrix[0,2]:= 0.0; Matrix[1,2]:=0.0; Matrix[2,2]:=1.0; Matrix[3,2]:=0.0;
+Matrix[0,3]:= 0.0; Matrix[1,3]:=0.0; Matrix[2,3]:=0.0; Matrix[3,3]:=1.0;
+end;
procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
begin
@@ -112,18 +188,17 @@
procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
begin
-
-glPushMatrix;
-glTranslatef(X, Y, 0);
-glScalef(Scale, Scale, 1);
+SetOffset(X, Y);
+ResetRotation;
+SetScale(Scale);
+UpdateModelview;
glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id);
glVertexPointer(2, GL_FLOAT, 0, @Texture^.vb);
glTexCoordPointer(2, GL_FLOAT, 0, @Texture^.tb);
glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
-
-glPopMatrix
+ResetModelview;
end;
procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt);
@@ -142,14 +217,13 @@
if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then
exit;
-glPushMatrix;
-glTranslatef(X, Y, 0);
+SetOffset(X, Y);
if Dir = 0 then Dir:= 1;
-glRotatef(Angle, 0, 0, Dir);
-
-glTranslatef(Dir*OffsetX, OffsetY, 0);
-glScalef(Scale, Scale, 1);
+SetRotation(Angle, Dir);
+AddOffset(Dir*OffsetX, OffsetY);
+AddScale(Scale);
+UpdateModelview;
// Any reason for this call? And why only in t direction, not s?
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@@ -180,7 +254,7 @@
glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
-glPopMatrix
+ResetModelview;
end;
procedure DrawSpriteRotated(Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
@@ -193,19 +267,18 @@
procedure DrawSpriteRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
begin
-glPushMatrix;
-glTranslatef(X, Y, 0);
-
+SetOffset(X, Y);
if Dir < 0 then
- glRotatef(Angle, 0, 0, -1)
+ SetRotation(Angle, -1.0)
else
- glRotatef(Angle, 0, 0, 1);
+ SetRotation(Angle, 1.0);
if Dir < 0 then
- glScalef(-1.0, 1.0, 1.0);
+ AddScale(-1.0, 1.0);
+UpdateModelview;
DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame);
-glPopMatrix
+ResetModelview;
end;
procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
@@ -217,17 +290,16 @@
if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then
exit;
-glPushMatrix;
-glTranslatef(X, Y, 0);
+SetOffset(X, Y);
if Dir < 0 then
begin
hw:= - hw;
- glRotatef(Angle, 0, 0, -1);
+ SetRotation(Angle, -1.0);
end
else
- glRotatef(Angle, 0, 0, 1);
-
+ SetRotation(Angle, 1.0);
+UpdateModelview;
glBindTexture(GL_TEXTURE_2D, Texture^.atlas^.id);
@@ -244,7 +316,7 @@
glTexCoordPointer(2, GL_FLOAT, 0, @Texture^.tb);
glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
-glPopMatrix
+ResetModelview;
end;
procedure DrawSprite(Sprite: TSprite; X, Y, Frame: LongInt);
@@ -308,8 +380,9 @@
glDisable(GL_TEXTURE_2D);
glEnable(GL_LINE_SMOOTH);
- glPushMatrix;
- glTranslatef(WorldDx, WorldDy, 0);
+ ResetRotation;
+ SetOffset(WorldDx, WorldDy);
+ UpdateModelview;
glLineWidth(Width);
Tint(r, g, b, a);
@@ -322,7 +395,7 @@
glDrawArrays(GL_LINES, 0, Length(VertexBuffer));
Tint($FF, $FF, $FF, $FF);
- glPopMatrix;
+ ResetModelview;
glEnable(GL_TEXTURE_2D);
glDisable(GL_LINE_SMOOTH);
@@ -331,6 +404,10 @@
procedure DrawFillRect(r: TSDL_Rect);
var VertexBuffer: array [0..3] of TVertex2f;
begin
+SetOffset(0, 0);
+ResetRotation;
+UpdateModelview;
+
// do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs)
if (abs(r.x) > r.w) and ((abs(r.x + r.w / 2) - r.w / 2) * cScaleFactor > cScreenWidth) then
exit;
@@ -354,7 +431,9 @@
glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
Tint($FF, $FF, $FF, $FF);
-glEnable(GL_TEXTURE_2D)
+glEnable(GL_TEXTURE_2D);
+
+ResetModelview;
end;
procedure DrawCircle(X, Y, Radius, Width: LongInt; r, g, b, a: Byte);
@@ -375,13 +454,15 @@
end;
glDisable(GL_TEXTURE_2D);
glEnable(GL_LINE_SMOOTH);
- glPushMatrix;
+ SetOffset(0, 0);
+ ResetRotation;
+ UpdateModelview;
glLineWidth(Width);
glVertexPointer(2, GL_FLOAT, 0, @CircleVertex[0]);
glDrawArrays(GL_LINE_LOOP, 0, 60);
- glPopMatrix;
glEnable(GL_TEXTURE_2D);
glDisable(GL_LINE_SMOOTH);
+ ResetModelview;
end;
@@ -410,9 +491,9 @@
r.h:=32;
ComputeTexcoords(HHTexture, @r, @TextureBuffer);
- glPushMatrix();
- glTranslatef(X, Y, 0);
- glRotatef(Angle, 0, 0, 1);
+ SetOffset(X, Y);
+ SetRotation(Angle, 1.0);
+ UpdateModelview;
glBindTexture(GL_TEXTURE_2D, HHTexture^.atlas^.id);
if Dir = -1 then
@@ -422,7 +503,7 @@
glTexCoordPointer(2, GL_FLOAT, 0, @TextureBuffer[0]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- glPopMatrix
+ ResetModelview;
end;
procedure DrawScreenWidget(widget: POnScreenWidget);
@@ -499,4 +580,9 @@
Tint(((c shr 24) and $FF), ((c shr 16) and $FF), (c shr 8) and $FF, (c and $FF))
end;
+procedure initModule;
+begin
+LoadIdentity(Modelview);
+end;
+
end.