hedgewars/uStore.pas
changeset 7188 580cd247511e
parent 7186 013deb83086b
child 7291 ad4b6c2b09e8
--- 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();