moved generic matrix code to uMatrix.pas
updated shader and client logic to use a mat4 rather than
ftransform or gl_ModelViewProjectionMatrix.
--- a/hedgewars/hwengine.pas Mon May 28 10:34:33 2012 +0200
+++ b/hedgewars/hwengine.pas Mon May 28 10:38:27 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, uRender, uDebug, uCommandHandlers, uLandPainted
+ SysUtils, uTypes, uVariables, uCommands, uUtils, uCaptions, uDebug, uCommandHandlers, uLandPainted
{$IFDEF SDL13}, uTouch{$ENDIF}{$IFDEF ANDROID}, GLUnit{$ENDIF};
{$IFDEF HWLIBRARY}
@@ -419,7 +419,6 @@
uVisualGears.initModule;
uWorld.initModule;
uCaptions.initModule;
- uRender.initModule;
end;
end;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hedgewars/uMatrix.pas Mon May 28 10:38:27 2012 +0200
@@ -0,0 +1,123 @@
+(*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *)
+
+{$INCLUDE "options.inc"}
+
+unit uMatrix;
+
+interface
+
+uses uTypes, gl;
+
+procedure MatrixLoadIdentity(out Result: TMatrix4x4f);
+procedure MatrixMultiply(out Result: TMatrix4x4f; const lhs, rhs: TMatrix4x4f);
+
+implementation
+
+procedure MatrixLoadIdentity(out Result: TMatrix4x4f);
+begin
+ Result[0,0]:= 1.0; Result[1,0]:=0.0; Result[2,0]:=0.0; Result[3,0]:=0.0;
+ Result[0,1]:= 0.0; Result[1,1]:=1.0; Result[2,1]:=0.0; Result[3,1]:=0.0;
+ Result[0,2]:= 0.0; Result[1,2]:=0.0; Result[2,2]:=1.0; Result[3,2]:=0.0;
+ Result[0,3]:= 0.0; Result[1,3]:=0.0; Result[2,3]:=0.0; Result[3,3]:=1.0;
+end;
+
+procedure MatrixMultiply(out Result: TMatrix4x4f; const lhs, rhs: TMatrix4x4f);
+var
+ test: TMatrix4x4f;
+ i, j: Integer;
+ error: boolean;
+begin
+ Result[0,0]:=lhs[0,0]*rhs[0,0] + lhs[1,0]*rhs[0,1] + lhs[2,0]*rhs[0,2] + lhs[3,0]*rhs[0,3];
+ Result[0,1]:=lhs[0,1]*rhs[0,0] + lhs[1,1]*rhs[0,1] + lhs[2,1]*rhs[0,2] + lhs[3,1]*rhs[0,3];
+ Result[0,2]:=lhs[0,2]*rhs[0,0] + lhs[1,2]*rhs[0,1] + lhs[2,2]*rhs[0,2] + lhs[3,2]*rhs[0,3];
+ Result[0,3]:=lhs[0,3]*rhs[0,0] + lhs[1,3]*rhs[0,1] + lhs[2,3]*rhs[0,2] + lhs[3,3]*rhs[0,3];
+
+ Result[1,0]:=lhs[0,0]*rhs[1,0] + lhs[1,0]*rhs[1,1] + lhs[2,0]*rhs[1,2] + lhs[3,0]*rhs[1,3];
+ Result[1,1]:=lhs[0,1]*rhs[1,0] + lhs[1,1]*rhs[1,1] + lhs[2,1]*rhs[1,2] + lhs[3,1]*rhs[1,3];
+ Result[1,2]:=lhs[0,2]*rhs[1,0] + lhs[1,2]*rhs[1,1] + lhs[2,2]*rhs[1,2] + lhs[3,2]*rhs[1,3];
+ Result[1,3]:=lhs[0,3]*rhs[1,0] + lhs[1,3]*rhs[1,1] + lhs[2,3]*rhs[1,2] + lhs[3,3]*rhs[1,3];
+
+ Result[2,0]:=lhs[0,0]*rhs[2,0] + lhs[1,0]*rhs[2,1] + lhs[2,0]*rhs[2,2] + lhs[3,0]*rhs[2,3];
+ Result[2,1]:=lhs[0,1]*rhs[2,0] + lhs[1,1]*rhs[2,1] + lhs[2,1]*rhs[2,2] + lhs[3,1]*rhs[2,3];
+ Result[2,2]:=lhs[0,2]*rhs[2,0] + lhs[1,2]*rhs[2,1] + lhs[2,2]*rhs[2,2] + lhs[3,2]*rhs[2,3];
+ Result[2,3]:=lhs[0,3]*rhs[2,0] + lhs[1,3]*rhs[2,1] + lhs[2,3]*rhs[2,2] + lhs[3,3]*rhs[2,3];
+
+ Result[3,0]:=lhs[0,0]*rhs[3,0] + lhs[1,0]*rhs[3,1] + lhs[2,0]*rhs[3,2] + lhs[3,0]*rhs[3,3];
+ Result[3,1]:=lhs[0,1]*rhs[3,0] + lhs[1,1]*rhs[3,1] + lhs[2,1]*rhs[3,2] + lhs[3,1]*rhs[3,3];
+ Result[3,2]:=lhs[0,2]*rhs[3,0] + lhs[1,2]*rhs[3,1] + lhs[2,2]*rhs[3,2] + lhs[3,2]*rhs[3,3];
+ Result[3,3]:=lhs[0,3]*rhs[3,0] + lhs[1,3]*rhs[3,1] + lhs[2,3]*rhs[3,2] + lhs[3,3]*rhs[3,3];
+
+{
+ Result[0,0]:=lhs[0,0]*rhs[0,0] + lhs[1,0]*rhs[0,1] + lhs[2,0]*rhs[0,2] + lhs[3,0]*rhs[0,3];
+ Result[0,1]:=lhs[0,0]*rhs[1,0] + lhs[1,0]*rhs[1,1] + lhs[2,0]*rhs[1,2] + lhs[3,0]*rhs[1,3];
+ Result[0,2]:=lhs[0,0]*rhs[2,0] + lhs[1,0]*rhs[2,1] + lhs[2,0]*rhs[2,2] + lhs[3,0]*rhs[2,3];
+ Result[0,3]:=lhs[0,0]*rhs[3,0] + lhs[1,0]*rhs[3,1] + lhs[2,0]*rhs[3,2] + lhs[3,0]*rhs[3,3];
+
+ Result[1,0]:=lhs[0,1]*rhs[0,0] + lhs[1,1]*rhs[0,1] + lhs[2,1]*rhs[0,2] + lhs[3,1]*rhs[0,3];
+ Result[1,1]:=lhs[0,1]*rhs[1,0] + lhs[1,1]*rhs[1,1] + lhs[2,1]*rhs[1,2] + lhs[3,1]*rhs[1,3];
+ Result[1,2]:=lhs[0,1]*rhs[2,0] + lhs[1,1]*rhs[2,1] + lhs[2,1]*rhs[2,2] + lhs[3,1]*rhs[2,3];
+ Result[1,3]:=lhs[0,1]*rhs[3,0] + lhs[1,1]*rhs[3,1] + lhs[2,1]*rhs[3,2] + lhs[3,1]*rhs[3,3];
+
+ Result[2,0]:=lhs[0,2]*rhs[0,0] + lhs[1,2]*rhs[0,1] + lhs[2,2]*rhs[0,2] + lhs[3,2]*rhs[0,3];
+ Result[2,1]:=lhs[0,2]*rhs[1,0] + lhs[1,2]*rhs[1,1] + lhs[2,2]*rhs[1,2] + lhs[3,2]*rhs[1,3];
+ Result[2,2]:=lhs[0,2]*rhs[2,0] + lhs[1,2]*rhs[2,1] + lhs[2,2]*rhs[2,2] + lhs[3,2]*rhs[2,3];
+ Result[2,3]:=lhs[0,2]*rhs[3,0] + lhs[1,2]*rhs[3,1] + lhs[2,2]*rhs[3,2] + lhs[3,2]*rhs[3,3];
+
+ Result[3,0]:=lhs[0,3]*rhs[0,0] + lhs[1,3]*rhs[0,1] + lhs[2,3]*rhs[0,2] + lhs[3,3]*rhs[0,3];
+ Result[3,1]:=lhs[0,3]*rhs[1,0] + lhs[1,3]*rhs[1,1] + lhs[2,3]*rhs[1,2] + lhs[3,3]*rhs[1,3];
+ Result[3,2]:=lhs[0,3]*rhs[2,0] + lhs[1,3]*rhs[2,1] + lhs[2,3]*rhs[2,2] + lhs[3,3]*rhs[2,3];
+ Result[3,3]:=lhs[0,3]*rhs[3,0] + lhs[1,3]*rhs[3,1] + lhs[2,3]*rhs[3,2] + lhs[3,3]*rhs[3,3];
+}
+ glPushMatrix;
+ glLoadMatrixf(@lhs[0, 0]);
+ glMultMatrixf(@rhs[0, 0]);
+ glGetFloatv(GL_MODELVIEW_MATRIX, @test[0, 0]);
+ glPopMatrix;
+
+ error:=false;
+ for i:=0 to 3 do
+ for j:=0 to 3 do
+ if Abs(test[i, j] - Result[i, j]) > 0.000001 then
+ error:=true;
+
+ if error then
+ begin
+ writeln('shall:');
+ for i:=0 to 3 do
+ begin
+ for j:=0 to 3 do
+ write(test[i, j]);
+ writeln;
+ end;
+
+ writeln('is:');
+ for i:=0 to 3 do
+ begin
+ for j:=0 to 3 do
+ write(Result[i, j]);
+ writeln;
+ end;
+ halt(0);
+ end;
+
+
+end;
+
+
+end.
--- a/hedgewars/uRender.pas Mon May 28 10:34:33 2012 +0200
+++ b/hedgewars/uRender.pas Mon May 28 10:38:27 2012 +0200
@@ -24,8 +24,6 @@
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);
procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
@@ -61,76 +59,71 @@
implementation
-uses uVariables;
+uses uVariables, uStore;
var LastTint: LongWord = 0;
- Modelview: TMatrix4x4f;
const DegToRad = 0.01745329252; // 2PI / 360
procedure UpdateModelview;
begin
-glLoadMatrixf(@Modelview[0,0]);
+{$IFDEF GL2}
+ UpdateModelviewProjection;
+{$ELSE}
+ glLoadMatrixf(@mModelview[0,0]);
+{$ENDIF}
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;
+ mModelview[0,0]:= 1.0; mModelview[1,0]:=0.0; mModelview[3,0]:= 0;
+ mModelview[0,1]:= 0.0; mModelview[1,1]:=1.0; mModelview[3,1]:= 0;
+ UpdateModelview;
end;
procedure SetOffset(X, Y: Longint);
begin
-Modelview[3,0]:= X;
-Modelview[3,1]:= Y;
+ mModelview[3,0]:= X;
+ mModelview[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;
+ mModelview[3,0]:=mModelview[3,0] + mModelview[0,0]*X + mModelview[1,0]*Y;
+ mModelview[3,1]:=mModelview[3,1] + mModelview[0,1]*X + mModelview[1,1]*Y;
end;
procedure SetScale(Scale: GLfloat);
begin
-Modelview[0,0]:= Scale;
-Modelview[1,1]:= Scale;
+ mModelview[0,0]:= Scale;
+ mModelview[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;
+ mModelview[0,0]:= mModelview[0,0]*Scale; mModelview[1,0]:= mModelview[1,0]*Scale;
+ mModelview[0,1]:= mModelview[0,1]*Scale; mModelview[1,1]:= mModelview[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;
+ mModelview[0,0]:= mModelview[0,0]*X; mModelview[1,0]:= mModelview[1,0]*Y;
+ mModelview[0,1]:= mModelview[0,1]*X; mModelview[1,1]:= mModelview[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;
+ SinCos(Angle*DegToRad, s, c);
+ mModelview[0,0]:= c; mModelview[1,0]:=-s*ZAxis;
+ mModelview[0,1]:= s*ZAxis; mModelview[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;
+ mModelview[0,0]:= 1.0; mModelview[1,0]:=0.0;
+ mModelview[0,1]:= 0.0; mModelview[1,1]:=1.0;
end;
procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
@@ -580,9 +573,4 @@
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.
--- a/hedgewars/uStore.pas Mon May 28 10:34:33 2012 +0200
+++ b/hedgewars/uStore.pas Mon May 28 10:38:27 2012 +0200
@@ -45,9 +45,13 @@
procedure SwapBuffers; inline;
procedure UpdateProjection;
+{$IFDEF GL2}
+procedure UpdateModelviewProjection;
+{$ENDIF}
+
implementation
uses uMisc, uConsole, uMobile, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands,
- uDebug{$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF};
+ uDebug{$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF}, uMatrix;
//type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple);
@@ -60,6 +64,7 @@
{$ENDIF}
{$IFDEF GL2}
Shader: GLuint;
+ uMVPLocation: GLint;
{$ENDIF}
function WriteInRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring): TSDL_Rect;
@@ -791,6 +796,8 @@
Shader:= CompileProgram('default');
glUseProgram(Shader);
glUniform1i(glGetUniformLocation(Shader, 'tex'), 0);
+ uMVPLocation:= glGetUniformLocation(Shader, 'mvp');
+
{$ENDIF}
{$IFNDEF S3D_DISABLED}
@@ -855,18 +862,33 @@
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
end;
+{$IFDEF GL2}
+procedure UpdateModelviewProjection;
+var
+ mvp: TMatrix4x4f;
+begin
+ MatrixMultiply(mvp, mProjection, mModelview);
+ glUniformMatrix4fv(uMVPLocation, 1, GL_FALSE, @mvp[0, 0]);
+end;
+{$ENDIF GL2}
+
procedure UpdateProjection;
-var mat: array[0..15] of GLfloat;
+var
s: GLfloat;
begin
s:=cScaleFactor;
+ mProjection[0,0]:= s/cScreenWidth; mProjection[0,1]:= 0.0; mProjection[0,2]:=0.0; mProjection[0,3]:= 0.0;
+ mProjection[1,0]:= 0.0; mProjection[1,1]:= -s/cScreenHeight; mProjection[1,2]:=0.0; mProjection[1,3]:= 0.0;
+ mProjection[2,0]:= 0.0; mProjection[2,1]:= 0.0; mProjection[2,2]:=1.0; mProjection[2,3]:= 0.0;
+ mProjection[3,0]:= cStereoDepth; mProjection[3,1]:= s/2; mProjection[3,2]:=0.0; mProjection[3,3]:= 1.0;
+
+ {$IFDEF GL2}
+ UpdateModelviewProjection;
+ {$ELSE}
glMatrixMode(GL_PROJECTION);
- mat[ 0]:= s/cScreenWidth; mat[ 1]:= 0.0; mat[ 2]:=0.0; mat[ 3]:= 0.0;
- mat[ 4]:= 0.0; mat[ 5]:= -s/cScreenHeight; mat[ 6]:=0.0; mat[ 7]:= 0.0;
- mat[ 8]:= 0.0; mat[ 9]:= 0.0; mat[10]:=1.0; mat[11]:= 0.0;
- mat[12]:= cStereoDepth; mat[13]:= s/2; mat[14]:=0.0; mat[15]:= 1.0;
- glLoadMatrixf(@mat);
+ glLoadMatrixf(@mProjection[0, 0]);
glMatrixMode(GL_MODELVIEW);
+ {$ENDIF}
end;
procedure SetScale(f: GLfloat);
--- a/hedgewars/uVariables.pas Mon May 28 10:34:33 2012 +0200
+++ b/hedgewars/uVariables.pas Mon May 28 10:38:27 2012 +0200
@@ -21,7 +21,7 @@
unit uVariables;
interface
-uses SDLh, uTypes, uFloat, GLunit, uConsts, Math, uMobile;
+uses SDLh, uTypes, uFloat, GLunit, uConsts, Math, uMobile, uMatrix;
var
/////// init flags ///////
@@ -2465,6 +2465,9 @@
lastTurnChecksum : Longword;
+ mModelview: TMatrix4x4f;
+ mProjection: TMatrix4x4f;
+
var trammo: array[TAmmoStrId] of ansistring; // name of the weapon
trammoc: array[TAmmoStrId] of ansistring; // caption of the weapon
trammod: array[TAmmoStrId] of ansistring; // description of the weapon
@@ -2614,6 +2617,9 @@
GrayScale:= false;
LuaGoals:= '';
+
+ MatrixLoadIdentity(mModelview);
+ MatrixLoadIdentity(mProjection);
end;
procedure freeModule;
--- a/share/hedgewars/Data/Shaders/default.vs Mon May 28 10:34:33 2012 +0200
+++ b/share/hedgewars/Data/Shaders/default.vs Mon May 28 10:38:27 2012 +0200
@@ -1,10 +1,11 @@
// !!!just testing!!!
// This is not GLSL 1.3+ compatible, as its using the compatibility profile!
+uniform mat4 mvp;
varying vec4 tint;
void main()
{
- gl_Position = ftransform();
+ gl_Position = mvp * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
tint = gl_Color;
}