# HG changeset patch # User Wolfgang Steffens # Date 1337671503 -7200 # Node ID 5ba5a92d74fb90c8ac8706513a79ccbc42afb924 # Parent eaef11c0d039801d4f112c1d57a9f8a9b97af586 Replaced matrix related FFP code with explicit matrix calculations. The modelview matrices now get uploaded at a single point via glLoadMatrix4 rather than using the GL1 matrix stack. In the GL2 variant this will become a uniform upload. diff -r eaef11c0d039 -r 5ba5a92d74fb hedgewars/hwengine.pas --- 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; diff -r eaef11c0d039 -r 5ba5a92d74fb hedgewars/uGearsRender.pas --- a/hedgewars/uGearsRender.pas Tue May 22 09:18:46 2012 +0200 +++ b/hedgewars/uGearsRender.pas Tue May 22 09:25:03 2012 +0200 @@ -54,9 +54,9 @@ glDisable(GL_TEXTURE_2D); //glEnable(GL_LINE_SMOOTH); - glPushMatrix; - - glTranslatef(WorldDx, WorldDy, 0); + ResetRotation; + SetOffset(WorldDx, WorldDy); + UpdateModelview; glLineWidth(4.0); @@ -66,8 +66,6 @@ glDrawArrays(GL_LINE_STRIP, 0, RopePoints.Count + 2); Tint($FF, $FF, $FF, $FF); - glPopMatrix; - glEnable(GL_TEXTURE_2D); //glDisable(GL_LINE_SMOOTH) end diff -r eaef11c0d039 -r 5ba5a92d74fb hedgewars/uRender.pas --- 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. diff -r eaef11c0d039 -r 5ba5a92d74fb hedgewars/uTypes.pas --- a/hedgewars/uTypes.pas Tue May 22 09:18:46 2012 +0200 +++ b/hedgewars/uTypes.pas Tue May 22 09:25:03 2012 +0200 @@ -199,6 +199,8 @@ X, Y: GLint; end; + TMatrix4x4f = array[0..3, 0..3] of GLfloat; + PAtlas = ^TAtlas; PTexture = ^TTexture;