--- a/hedgewars/uStore.pas Tue Jun 05 22:17:06 2012 +0200
+++ b/hedgewars/uStore.pas Tue Jun 05 22:37:36 2012 +0200
@@ -49,6 +49,14 @@
procedure UpdateModelviewProjection;
{$ENDIF}
+procedure Tint(r, g, b, a: Byte); inline;
+procedure Tint(c: Longword); inline;
+procedure SetTexCoordPointer(p: Pointer);
+procedure SetVertexPointer(p: Pointer);
+procedure SetColorPointer(p: Pointer);
+procedure BeginWater;
+procedure EndWater;
+
implementation
uses uMisc, uConsole, uMobile, uVariables, uUtils, uTextures, uRender, uRenderUtils, uCommands,
uDebug{$IFDEF USE_CONTEXT_RESTORE}, uWorld{$ENDIF}, uMatrix;
@@ -63,9 +71,26 @@
SDLPrimSurface: PSDL_Surface;
{$ENDIF}
{$IFDEF GL2}
- Shader: GLuint;
- uMVPLocation: GLint;
+ shaderMain: GLuint;
+ shaderWater: GLuint;
+
+ // attributes
+const
+ aVertex: GLint = 0;
+ aTexCoord: GLint = 1;
+ aColor: GLint = 2;
+
+var
+ uCurrentMVPLocation: GLint;
+
+ uMainMVPLocation: GLint;
+ uMainTintLocation: GLint;
+
+ uWaterMVPLocation: GLint;
+
{$ENDIF}
+ LastTint: LongWord = 0;
+
function WriteInRect(Surface: PSDL_Surface; X, Y: LongInt; Color: LongWord; Font: THWFont; s: ansistring): TSDL_Rect;
var w, h: LongInt;
@@ -664,7 +689,7 @@
CloseFile(f);
- writeln('Compiling shader: ' + Pathz[ptShaders] + '/' + shaderFile);
+ WriteLnToConsole('Compiling shader: ' + Pathz[ptShaders] + '/' + shaderFile);
sourceA:=PChar(source);
lengthA:=Length(source);
@@ -679,15 +704,15 @@
begin
GetMem(log, logLength);
glGetShaderInfoLog(shader, logLength, nil, log);
- writeln('========== Compiler log ==========');
- writeln(log);
- writeln('===================================');
+ WriteLnToConsole('========== Compiler log ==========');
+ WriteLnToConsole(log);
+ WriteLnToConsole('===================================');
FreeMem(log, logLength);
end;
if compileResult <> GL_TRUE then
begin
- writeln('Shader compilation failed, halting');
+ WriteLnToConsole('Shader compilation failed, halting');
halt(-1);
end;
@@ -707,6 +732,11 @@
fs:= CompileShader(shaderName + '.fs', GL_FRAGMENT_SHADER);
glAttachShader(program_, vs);
glAttachShader(program_, fs);
+
+ glBindAttribLocation(program_, aVertex, 'vertex');
+ glBindAttribLocation(program_, aTexCoord, 'texcoord');
+ glBindAttribLocation(program_, aColor, 'color');
+
glLinkProgram(program_);
glDeleteShader(vs);
glDeleteShader(fs);
@@ -718,20 +748,21 @@
begin
GetMem(log, logLength);
glGetProgramInfoLog(program_, logLength, nil, log);
- writeln('========== Compiler log ==========');
- writeln(log);
- writeln('===================================');
+ WriteLnToConsole('========== Compiler log ==========');
+ WriteLnToConsole(log);
+ WriteLnToConsole('===================================');
FreeMem(log, logLength);
end;
if linkResult <> GL_TRUE then
begin
- writeln('Linking program failed, halting');
+ WriteLnToConsole('Linking program failed, halting');
halt(-1);
end;
CompileProgram:= program_;
end;
+
{$ENDIF}
procedure SetupOpenGL;
@@ -793,11 +824,22 @@
{$IFDEF GL2}
Load_GL_VERSION_2_0;
- Shader:= CompileProgram('default');
- glUseProgram(Shader);
- glUniform1i(glGetUniformLocation(Shader, 'tex'), 0);
- uMVPLocation:= glGetUniformLocation(Shader, 'mvp');
+
+ shaderWater:= CompileProgram('water');
+ glUseProgram(shaderWater);
+ glUniform1i(glGetUniformLocation(shaderWater, 'tex0'), 0);
+ uWaterMVPLocation:= glGetUniformLocation(shaderWater, 'mvp');
+ shaderMain:= CompileProgram('default');
+ glUseProgram(shaderMain);
+ glUniform1i(glGetUniformLocation(shaderMain, 'tex0'), 0);
+ uMainMVPLocation:= glGetUniformLocation(shaderMain, 'mvp');
+ uMainTintLocation:= glGetUniformLocation(shaderMain, 'tint');
+
+ uCurrentMVPLocation:= uMainMVPLocation;
+
+ Tint(255, 255, 255, 255);
+ UpdateModelviewProjection;
{$ENDIF}
{$IFNDEF S3D_DISABLED}
@@ -858,8 +900,77 @@
glDisable(GL_DITHER);
// enable common states by default as they save a lot
glEnable(GL_TEXTURE_2D);
+
+{$IFDEF GL2}
+ glEnableVertexAttribArray(aVertex);
+ glEnableVertexAttribArray(aTexCoord);
+{$ELSE}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+{$ENDIF}
+end;
+
+
+procedure Tint(r, g, b, a: Byte); inline;
+var
+ nc, tw: Longword;
+const
+ scale = 1.0/255.0;
+begin
+ nc:= (a shl 24) or (b shl 16) or (g shl 8) or r;
+
+ if nc = lastTint then
+ exit;
+
+ if GrayScale then
+ begin
+ tw:= round(r * RGB_LUMINANCE_RED + g * RGB_LUMINANCE_GREEN + b * RGB_LUMINANCE_BLUE);
+ if tw > 255 then
+ tw:= 255;
+ r:= tw;
+ g:= tw;
+ b:= tw
+ end;
+
+ {$IFDEF GL2}
+ glUniform4f(uMainTintLocation, r*scale, g*scale, b*scale, a*scale);
+ glColor4ub(r, g, b, a);
+ {$ELSE}
+ glColor4ub(r, g, b, a);
+ {$ENDIF}
+ lastTint:= nc;
+end;
+
+procedure Tint(c: Longword); inline;
+begin
+ Tint(((c shr 24) and $FF), ((c shr 16) and $FF), (c shr 8) and $FF, (c and $FF))
+end;
+
+procedure SetTexCoordPointer(p: Pointer);
+begin
+ {$IFDEF GL2}
+ glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, p);
+ {$ELSE}
+ glTexCoordPointer(2, GL_FLOAT, 0, p);
+ {$ENDIF}
+end;
+
+procedure SetVertexPointer(p: Pointer);
+begin
+ {$IFDEF GL2}
+ glVertexAttribPointer(aVertex, 2, GL_FLOAT, GL_FALSE, 0, p);
+ {$ELSE}
+ glVertexPointer(2, GL_FLOAT, 0, p);
+ {$ENDIF}
+end;
+
+procedure SetColorPointer(p: Pointer);
+begin
+ {$IFDEF GL2}
+ glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, p);
+ {$ELSE}
+ glColorPointer(4, GL_UNSIGNED_BYTE, 0, p);
+ {$ENDIF}
end;
{$IFDEF GL2}
@@ -868,7 +979,7 @@
mvp: TMatrix4x4f;
begin
MatrixMultiply(mvp, mProjection, mModelview);
- glUniformMatrix4fv(uMVPLocation, 1, GL_FALSE, @mvp[0, 0]);
+ glUniformMatrix4fv(uCurrentMVPLocation, 1, GL_FALSE, @mvp[0, 0]);
end;
{$ENDIF GL2}
@@ -901,6 +1012,34 @@
//end;
end;
+procedure BeginWater;
+begin
+ {$IFDEF GL2}
+ glUseProgram(shaderWater);
+ uCurrentMVPLocation:=uWaterMVPLocation;
+ UpdateModelviewProjection;
+ glDisableVertexAttribArray(aTexCoord);
+ glEnableVertexAttribArray(aColor);
+ {$ELSE}
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ {$ENDIF}
+end;
+
+procedure EndWater;
+begin
+ {$IFDEF GL2}
+ glUseProgram(shaderMain);
+ uCurrentMVPLocation:=uMainMVPLocation;
+ UpdateModelviewProjection;
+ glDisableVertexAttribArray(aColor);
+ glEnableVertexAttribArray(aTexCoord);
+ {$ELSE}
+ glDisableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ {$ENDIF}
+end;
+
////////////////////////////////////////////////////////////////////////////////
procedure AddProgress;
var r: TSDL_Rect;
@@ -1284,7 +1423,8 @@
procedure freeModule;
begin
{$IFDEF GL2}
- glDeleteProgram(Shader);
+ glDeleteProgram(shaderMain);
+ glDeleteProgram(shaderWater);
{$ENDIF}
StoreRelease(false);
TTF_Quit();