hedgewars/uRender.pas
changeset 10275 6c91047f59b6
parent 10266 a90a55ec5b98
child 10276 89056c7254ef
--- a/hedgewars/uRender.pas	Wed Jun 11 00:35:23 2014 +0400
+++ b/hedgewars/uRender.pas	Tue Jun 10 23:21:22 2014 +0200
@@ -51,8 +51,8 @@
 procedure DrawFillRect          (r: TSDL_Rect);
 procedure DrawHedgehog          (X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real);
 procedure DrawScreenWidget      (widget: POnScreenWidget);
+procedure DrawWaterBody         (pVertexBuffer: Pointer; length: LongInt);
 
-procedure openglTint            (r, g, b, a: Byte); inline;
 procedure Tint                  (r, g, b, a: Byte); inline;
 procedure Tint                  (c: Longword); inline;
 procedure untint(); inline;
@@ -64,6 +64,16 @@
 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline;
 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline;
 
+
+procedure openglTranslProjMatrix(X, Y, Z: GLFloat); inline;
+procedure openglPushMatrix      (); inline;
+procedure openglPopMatrix       (); inline;
+procedure openglTranslatef      (X, Y, Z: GLfloat); inline;
+procedure openglScalef          (ScaleX, ScaleY, ScaleZ: GLfloat); inline;
+procedure openglRotatef         (RotX, RotY, RotZ: GLfloat; dir: LongInt); inline;
+procedure openglTint            (r, g, b, a: Byte); inline;
+
+
 implementation
 uses uVariables;
 
@@ -94,6 +104,68 @@
     isDyAreaOffscreen:= 0;
 end;
 
+procedure openglTranslProjMatrix(X, Y, Z: GLfloat); inline;
+begin
+{$IFDEF GL2}
+    hglMatrixMode(MATRIX_PROJECTION);
+    hglTranslatef(X, Y, Z);
+    hglMatrixMode(MATRIX_MODELVIEW);
+{$ELSE}
+    glMatrixMode(GL_PROJECTION);
+    glTranslatef(X, Y, Z);
+    glMatrixMode(GL_MODELVIEW);
+{$ENDIF}
+end;
+
+procedure openglPushMatrix(); inline;
+begin
+{$IFDEF GL2}h{$ENDIF}glPushMatrix();
+end;
+
+procedure openglPopMatrix(); inline;
+begin
+{$IFDEF GL2}h{$ENDIF}glPopMatrix();
+end;
+
+procedure openglTranslatef(X, Y, Z: GLfloat); inline;
+begin
+{$IFDEF GL2}h{$ENDIF}glTranslatef(X, Y, Z);
+end;
+
+procedure openglScalef(ScaleX, ScaleY, ScaleZ: GLfloat); inline;
+begin
+{$IFDEF GL2}h{$ENDIF}glScalef(ScaleX, ScaleY, ScaleZ);
+end;
+
+procedure openglRotatef(RotX, RotY, RotZ: GLfloat; dir: LongInt); inline;
+begin
+{$IFDEF GL2}h{$ENDIF}glRotatef(RotX, RotY, RotZ, dir);
+end;
+
+procedure openglUseColorOnly(b :boolean); inline;
+begin
+    if b then
+        begin
+        {$IFDEF GL2}
+        glDisableVertexAttribArray(aTexCoord);
+        glEnableVertexAttribArray(aColor);
+        {$ELSE}
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+        glEnableClientState(GL_COLOR_ARRAY);
+        {$ENDIF}
+        end
+    else
+        begin
+        {$IFDEF GL2}
+        glDisableVertexAttribArray(aColor);
+        glEnableVertexAttribArray(aTexCoord);
+        {$ELSE}
+        glDisableClientState(GL_COLOR_ARRAY);
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+        {$ENDIF}
+        end;
+end;
+
 procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
 begin
 r.y:= r.y + Height * Position;
@@ -182,15 +254,9 @@
 procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
 begin
 
-{$IFDEF GL2}
-hglPushMatrix;
-hglTranslatef(X, Y, 0);
-hglScalef(Scale, Scale, 1);
-{$ELSE}
-glPushMatrix;
-glTranslatef(X, Y, 0);
-glScalef(Scale, Scale, 1);
-{$ENDIF}
+openglPushMatrix;
+openglTranslatef(X, Y, 0);
+openglScalef(Scale, Scale, 1);
 
 glBindTexture(GL_TEXTURE_2D, Texture^.id);
 
@@ -199,12 +265,10 @@
 
 {$IFDEF GL2}
 UpdateModelviewProjection;
+{$ENDIF}
+
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
-hglPopMatrix;
-{$ELSE}
-glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
-glPopMatrix;
-{$ENDIF}
+openglPopMatrix;
 
 end;
 
@@ -213,15 +277,9 @@
 var
     TextureBuffer: array [0..3] of TVertex2f;
 begin
-{$IFDEF GL2}
-hglPushMatrix;
-hglTranslatef(X, Y, 0);
-hglScalef(Scale, Scale, 1);
-{$ELSE}
-glPushMatrix;
-glTranslatef(X, Y, 0);
-glScalef(Scale, Scale, 1);
-{$ENDIF}
+openglPushMatrix;
+openglTranslatef(X, Y, 0);
+openglScalef(Scale, Scale, 1);
 
 glBindTexture(GL_TEXTURE_2D, Texture^.id);
 
@@ -239,12 +297,10 @@
 
 {$IFDEF GL2}
 UpdateModelviewProjection;
+{$ENDIF}
+
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
-hglPopMatrix;
-{$ELSE}
-glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb));
-glPopMatrix;
-{$ENDIF}
+openglPopMatrix;
 end;
 
 procedure DrawTextureF(Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt);
@@ -263,25 +319,15 @@
 if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then
     exit;
 
-{$IFDEF GL2}
-hglPushMatrix;
-hglTranslatef(X, Y, 0);
-{$ELSE}
-glPushMatrix;
-glTranslatef(X, Y, 0);
-{$ENDIF}
+openglPushMatrix;
+openglTranslatef(X, Y, 0);
 
 if Dir = 0 then Dir:= 1;
 
-{$IFDEF GL2}
-hglRotatef(Angle, 0, 0, Dir);
-hglTranslatef(Dir*OffsetX, OffsetY, 0);
-hglScalef(Scale, Scale, 1);
-{$ELSE}
-glRotatef(Angle, 0, 0, Dir);
-glTranslatef(Dir*OffsetX, OffsetY, 0);
-glScalef(Scale, Scale, 1);
-{$ENDIF}
+openglRotatef(Angle, 0, 0, Dir);
+
+openglTranslatef(Dir*OffsetX, OffsetY, 0);
+openglScalef(Scale, Scale, 1);
 
 // 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);
@@ -325,11 +371,7 @@
 
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
 
-{$IFDEF GL2}
-hglPopMatrix;
-{$ELSE}
-glPopMatrix;
-{$ENDIF}
+openglPopMatrix;
 
 end;
 
@@ -344,40 +386,20 @@
 procedure DrawSpriteRotatedF(Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
 begin
 
-{$IFDEF GL2}
-hglPushMatrix;
-hglTranslatef(X, Y, 0);
-{$ELSE}
-glPushMatrix;
-glTranslatef(X, Y, 0);
-{$ENDIF}
+openglPushMatrix;
+openglTranslatef(X, Y, 0);
 
 if Dir < 0 then
-{$IFDEF GL2}
-    hglRotatef(Angle, 0, 0, -1)
-{$ELSE}
-    glRotatef(Angle, 0, 0, -1)
-{$ENDIF}
+    begin
+    openglRotatef(Angle, 0, 0, -1);
+    openglScalef(-1.0, 1.0, 1.0);
+    end
 else
-{$IFDEF GL2}
-    hglRotatef(Angle, 0, 0,  1);
-{$ELSE}
-    glRotatef(Angle, 0, 0,  1);
-{$ENDIF}
-if Dir < 0 then
-{$IFDEF GL2}
-    hglScalef(-1.0, 1.0, 1.0);
-{$ELSE}
-    glScalef(-1.0, 1.0, 1.0);
-{$ENDIF}
+    openglRotatef(Angle, 0, 0,  1);
 
 DrawSprite(Sprite, -SpritesData[Sprite].Width div 2, -SpritesData[Sprite].Height div 2, Frame);
 
-{$IFDEF GL2}
-hglPopMatrix;
-{$ELSE}
-glPopMatrix;
-{$ENDIF}
+openglPopMatrix;
 
 end;
 
@@ -390,29 +412,16 @@
 if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then
     exit;
 
-{$IFDEF GL2}
-hglPushMatrix;
-hglTranslatef(X, Y, 0);
-{$ELSE}
-glPushMatrix;
-glTranslatef(X, Y, 0);
-{$ENDIF}
+openglPushMatrix;
+openglTranslatef(X, Y, 0);
 
 if Dir < 0 then
     begin
     hw:= - hw;
-{$IFDEF GL2}
-    hglRotatef(Angle, 0, 0, -1);
-{$ELSE}
-    glRotatef(Angle, 0, 0, -1);
-{$ENDIF}
+    openglRotatef(Angle, 0, 0, -1);
     end
 else
-{$IFDEF GL2}
-    hglRotatef(Angle, 0, 0,  1);
-{$ELSE}
-    glRotatef(Angle, 0, 0, 1);
-{$ENDIF}
+    openglRotatef(Angle, 0, 0, 1);
 
 glBindTexture(GL_TEXTURE_2D, Texture^.id);
 
@@ -434,11 +443,7 @@
 
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
 
-{$IFDEF GL2}
-hglPopMatrix;
-{$ELSE}
-glPopMatrix;
-{$ENDIF}
+openglPopMatrix;
 
 end;
 
@@ -509,13 +514,17 @@
 var VertexBuffer: array [0..1] of TVertex2f;
 begin
     glEnable(GL_LINE_SMOOTH);
-{$IFNDEF GL2}
-    glDisable(GL_TEXTURE_2D);
+
+    EnableTexture(False);
 
-    glPushMatrix;
-    glTranslatef(WorldDx, WorldDy, 0);
+    openglPushMatrix;
+    openglTranslatef(WorldDx, WorldDy, 0);
     glLineWidth(Width);
 
+    {$IFDEF GL2}
+    UpdateModelviewProjection;
+    {$ENDIF}
+
     Tint(r, g, b, a);
     VertexBuffer[0].X:= X0;
     VertexBuffer[0].Y:= Y0;
@@ -526,33 +535,10 @@
     glDrawArrays(GL_LINES, 0, Length(VertexBuffer));
     untint;
 
-    glPopMatrix;
-
-    glEnable(GL_TEXTURE_2D);
-
-{$ELSE}
-    EnableTexture(False);
-
-    hglPushMatrix;
-    hglTranslatef(WorldDx, WorldDy, 0);
-    glLineWidth(Width);
+    openglPopMatrix;
 
-    UpdateModelviewProjection;
-
-    Tint(r, g, b, a);
-    VertexBuffer[0].X:= X0;
-    VertexBuffer[0].Y:= Y0;
-    VertexBuffer[1].X:= X1;
-    VertexBuffer[1].Y:= Y1;
-
-    SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
-    glDrawArrays(GL_LINES, 0, Length(VertexBuffer));
-    Tint($FF, $FF, $FF, $FF);
-
-    hglPopMatrix;
     EnableTexture(True);
 
-{$ENDIF}
     glDisable(GL_LINE_SMOOTH);
 end;
 
@@ -566,11 +552,7 @@
 if (abs(r.y) > r.h) and ((abs(r.y + r.h / 2 - (0.5 * cScreenHeight)) - r.h / 2) * cScaleFactor > cScreenHeight) then
     exit;
 
-{$IFDEF GL2}
 EnableTexture(False);
-{$ELSE}
-glDisable(GL_TEXTURE_2D);
-{$ENDIF}
 
 Tint($00, $00, $00, $80);
 
@@ -587,11 +569,8 @@
 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
 
 untint;
-{$IFDEF GL2}
+
 EnableTexture(True);
-{$ELSE}
-glEnable(GL_TEXTURE_2D)
-{$ENDIF}
 
 end;
 
@@ -612,29 +591,15 @@
         CircleVertex[i].Y := Y + Radius*sin(i*pi/30);
     end;
 
-{$IFNDEF GL2}
-
-    glDisable(GL_TEXTURE_2D);
-    glEnable(GL_LINE_SMOOTH);
-    glPushMatrix;
-    glLineWidth(Width);
-    glVertexPointer(2, GL_FLOAT, 0, @CircleVertex[0]);
-    glDrawArrays(GL_LINE_LOOP, 0, 60);
-    glPopMatrix;
-    glEnable(GL_TEXTURE_2D);
-    glDisable(GL_LINE_SMOOTH);
-
-{$ELSE}
     EnableTexture(False);
     glEnable(GL_LINE_SMOOTH);
-    hglPushMatrix;
+    openglPushMatrix;
     glLineWidth(Width);
     SetVertexPointer(@CircleVertex[0], 60);
     glDrawArrays(GL_LINE_LOOP, 0, 60);
-    hglPopMatrix;
+    openglPopMatrix;
     EnableTexture(True);
     glDisable(GL_LINE_SMOOTH);
-{$ENDIF}
 end;
 
 
@@ -667,15 +632,9 @@
         r:= (Step + 1) * 32 / HHTexture^.w
     end;
 
-{$IFDEF GL2}
-    hglPushMatrix();
-    hglTranslatef(X, Y, 0);
-    hglRotatef(Angle, 0, 0, 1);
-{$ELSE}
-    glPushMatrix();
-    glTranslatef(X, Y, 0);
-    glRotatef(Angle, 0, 0, 1);
-{$ENDIF}
+    openglPushMatrix();
+    openglTranslatef(X, Y, 0);
+    openglRotatef(Angle, 0, 0, 1);
 
     glBindTexture(GL_TEXTURE_2D, HHTexture^.id);
 
@@ -697,11 +656,7 @@
 
     glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
 
-{$IFDEF GL2}
-    hglPopMatrix;
-{$ELSE}
-    glPopMatrix;
-{$ENDIF}
+    openglPopMatrix;
 end;
 
 procedure DrawScreenWidget(widget: POnScreenWidget);
@@ -751,6 +706,51 @@
 {$ENDIF}
 end;
 
+procedure BeginWater;
+begin
+{$IFDEF GL2}
+    glUseProgram(shaderWater);
+    uCurrentMVPLocation:=uWaterMVPLocation;
+    UpdateModelviewProjection;
+    glDisableVertexAttribArray(aTexCoord);
+    glEnableVertexAttribArray(aColor);
+{$ENDIF}
+
+    openglUseColorOnly(true);
+end;
+
+procedure EndWater;
+begin
+{$IFDEF GL2}
+    glUseProgram(shaderMain);
+    uCurrentMVPLocation:=uMainMVPLocation;
+    UpdateModelviewProjection;
+    glDisableVertexAttribArray(aColor);
+    glEnableVertexAttribArray(aTexCoord);
+{$ENDIF}
+
+    openglUseColorOnly(false);
+end;
+
+procedure DrawWaterBody(pVertexBuffer: Pointer; length: LongInt);
+begin
+{$IFDEF GL2}
+        UpdateModelviewProjection;
+{$ENDIF}
+
+        BeginWater;
+        if SuddenDeathDmg then
+            SetColorPointer(@SDWaterColorArray[0], 4)
+        else
+            SetColorPointer(@WaterColorArray[0], 4);
+
+        SetVertexPointer(pVertexBuffer, 4);
+
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+        EndWater;
+end;
+
 procedure openglTint(r, g, b, a: Byte); inline;
 {$IFDEF GL2}
 const