--- a/hedgewars/uWorld.pas Tue Jun 17 00:41:49 2014 +0200
+++ b/hedgewars/uWorld.pas Tue Jun 17 15:18:07 2014 +0200
@@ -790,16 +790,13 @@
{$ENDIF}
end;
-procedure DrawWater(Alpha: byte; OffsetY: LongInt);
-var VertexBuffer : array [0..3] of TVertex2f;
- topy: LongInt;
+procedure DrawWater(Alpha: byte; OffsetY, OffsetX: LongInt);
+var VertexBuffer : array [0..4] of TVertex2f;
+ topy, lx, rx: LongInt;
begin
// Water
topy:= OffsetY + WorldDy + cWaterLine;
-if topy > ViewBottomY then
- exit;
-
if SuddenDeathDmg then
begin
SDWaterColorArray[0].a := Alpha;
@@ -818,35 +815,89 @@
if topy < 0 then
topy:= 0;
-glDisable(GL_TEXTURE_2D);
-VertexBuffer[0].X:= -ViewWidth;
-VertexBuffer[0].Y:= topy;
-VertexBuffer[1].X:= ViewWidth;
-VertexBuffer[1].Y:= topy;
-VertexBuffer[2].X:= ViewWidth;
-VertexBuffer[2].Y:= ViewBottomY;
-VertexBuffer[3].X:= -ViewWidth;
-VertexBuffer[3].Y:= ViewBottomY;
+// glDisable(GL_TEXTURE_2D);
+
+if (topy < ViewBottomY) and (WorldEdge <> weSea) then
+ begin
+ VertexBuffer[0].X:= ViewLeftX;
+ VertexBuffer[0].Y:= topy;
+ VertexBuffer[1].X:= ViewRightX;
+ VertexBuffer[1].Y:= topy;
+ VertexBuffer[2].X:= ViewRightX;
+ VertexBuffer[2].Y:= ViewBottomY;
+ VertexBuffer[3].X:= ViewLeftX;
+ VertexBuffer[3].Y:= ViewBottomY;
+ DrawWaterBody(@VertexBuffer[0]);
+ end;
+
+// water world edges? draw water body on the sides too
+if WorldEdge = weSea then
+ begin
+
+ lx:= LeftX + WorldDx - OffsetX;
+ rx:= RightX + WorldDx + OffsetX;
-DrawWaterBody(@VertexBuffer[0]);
+ if topy < ViewBottomY then
+ begin
+ VertexBuffer[0].X:= lx;
+ VertexBuffer[0].Y:= topy;
+ VertexBuffer[1].X:= RightX;
+ VertexBuffer[1].Y:= topy;
+ VertexBuffer[2].X:= ViewRightX;
+ VertexBuffer[2].Y:= ViewBottomY;
+ VertexBuffer[3].X:= ViewLeftX;
+ VertexBuffer[3].Y:= ViewBottomY;
+ DrawWaterBody(@VertexBuffer[0]);
+ end;
+
+ if lx > ViewLeftX then
+ begin
+ VertexBuffer[0].X:= lx;
+ VertexBuffer[0].Y:= ViewTopY;
+ VertexBuffer[1].X:= lx;
+ VertexBuffer[1].Y:= topy;
+ VertexBuffer[2].X:= ViewLeftX;
+ VertexBuffer[2].Y:= ViewBottomY;
+ VertexBuffer[3].X:= ViewLeftX;
+ VertexBuffer[3].Y:= ViewTopY;
+ DrawWaterBody(@VertexBuffer[0]);
+ end;
+
+
+ if rx < ViewRightX then
+ begin
+ VertexBuffer[0].X:= rx;
+ VertexBuffer[0].Y:= topy;
+ VertexBuffer[1].X:= rx;
+ VertexBuffer[1].Y:= ViewTopY;
+ VertexBuffer[2].X:= ViewRightX;
+ VertexBuffer[2].Y:= ViewTopY;
+ VertexBuffer[3].X:= ViewRightX;
+ VertexBuffer[3].Y:= ViewBottomY;
+ DrawWaterBody(@VertexBuffer[0]);
+ end;
+ end;
{$IFNDEF GL2}
// must not be Tint() as color array seems to stay active and color reset is required
glColor4ub($FF, $FF, $FF, $FF);
{$ENDIF}
-glEnable(GL_TEXTURE_2D);
+//glEnable(GL_TEXTURE_2D);}
end;
-procedure DrawWaves(Dir, dX, dY: LongInt; tnt: Byte);
-var VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
+procedure DrawWaves(Dir, dX, dY, oX: LongInt; tnt: Byte);
+var VertexBuffer, TextureBuffer: array [0..7] of TVertex2f;
lw, waves, shift: GLfloat;
sprite: TSprite;
topy: LongInt;
begin
+dY:= -cWaveHeight + dy;
+ox:= -cWaveHeight + ox;
+
topy:= cWaterLine + WorldDy + dY;
-if topY > ViewBottomY then
+if (WorldEdge <> weSea) and (topY > ViewBottomY) then
exit;
if SuddenDeathDmg then
@@ -856,8 +907,10 @@
cWaveWidth:= SpritesData[sprite].Width;
-lw:= ViewWidth;
-waves:= lw * 2 / cWaveWidth;
+if WorldEdge = weSea then
+ lw:= playWidth div 2
+else
+ lw:= ViewWidth;
if SuddenDeathDmg then
Tint(LongInt(tnt) * SDWaterColorArray[2].r div 255 + 255 - tnt,
@@ -874,34 +927,99 @@
glBindTexture(GL_TEXTURE_2D, SpritesData[sprite].Texture^.id);
-VertexBuffer[0].X:= -lw;
-VertexBuffer[0].Y:= cWaterLine + WorldDy + dY;
-VertexBuffer[1].X:= lw;
-VertexBuffer[1].Y:= VertexBuffer[0].Y;
-VertexBuffer[2].X:= lw;
-VertexBuffer[2].Y:= VertexBuffer[0].Y + SpritesData[sprite].Height;
-VertexBuffer[3].X:= -lw;
-VertexBuffer[3].Y:= VertexBuffer[2].Y;
+if WorldEdge <> weSea then
+ begin
+ if topY < ViewBottomY then
+ begin
+ VertexBuffer[0].X:= -lw;
+ VertexBuffer[0].Y:= cWaterLine + WorldDy + dY;
+ VertexBuffer[1].X:= lw;
+ VertexBuffer[1].Y:= VertexBuffer[0].Y;
+ VertexBuffer[2].X:= lw;
+ VertexBuffer[2].Y:= VertexBuffer[0].Y + SpritesData[sprite].Height;
+ VertexBuffer[3].X:= -lw;
+ VertexBuffer[3].Y:= VertexBuffer[2].Y;
+ end;
-shift:= - lw / cWaveWidth;
-TextureBuffer[0].X:= shift + (( - WorldDx + LongInt(RealTicks shr 6) * Dir + dX) mod cWaveWidth) / (cWaveWidth - 1);
-TextureBuffer[0].Y:= 0;
-TextureBuffer[1].X:= TextureBuffer[0].X + waves;
-TextureBuffer[1].Y:= TextureBuffer[0].Y;
-TextureBuffer[2].X:= TextureBuffer[1].X;
-TextureBuffer[2].Y:= SpritesData[sprite].Texture^.ry;
-TextureBuffer[3].X:= TextureBuffer[0].X;
-TextureBuffer[3].Y:= TextureBuffer[2].Y;
+ waves:= lw * 2 / cWaveWidth;
+ shift:= - lw / cWaveWidth;
+ TextureBuffer[0].X:= shift + (( - WorldDx + LongInt(RealTicks shr 6) * Dir + dX) mod cWaveWidth) / (cWaveWidth - 1);
+ TextureBuffer[0].Y:= 0;
+ TextureBuffer[1].X:= TextureBuffer[0].X + waves;
+ TextureBuffer[1].Y:= TextureBuffer[0].Y;
+ TextureBuffer[2].X:= TextureBuffer[1].X;
+ TextureBuffer[2].Y:= SpritesData[sprite].Texture^.ry;
+ TextureBuffer[3].X:= TextureBuffer[0].X;
+ TextureBuffer[3].Y:= TextureBuffer[2].Y;
-SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer));
-SetTexCoordPointer(@TextureBuffer[0], Length(VertexBuffer));
+ SetVertexPointer(@VertexBuffer[0], 4);
+ SetTexCoordPointer(@TextureBuffer[0],4);
+
+ {$IFDEF GL2}
+ UpdateModelviewProjection;
+ {$ENDIF}
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
+ end
+else // weSea: with waterwalls
+ begin
+ topy := cWaterLine + WorldDy;
+
+ // for GL_TRIANGLE_STRIP
+
+ VertexBuffer[0].X:= LeftX + WorldDx - SpritesData[sprite].Height - ox;
+ VertexBuffer[0].Y:= ViewTopY;
+ VertexBuffer[1].X:= LeftX + WorldDx - ox;
+ VertexBuffer[1].Y:= ViewTopY;
+ VertexBuffer[2].X:= VertexBuffer[0].X;
+ VertexBuffer[2].Y:= topy + SpritesData[sprite].Height + dy;
+ VertexBuffer[3].X:= VertexBuffer[1].X;
+ VertexBuffer[3].Y:= topy + dy;
+ VertexBuffer[4].X:= RightX + WorldDx + SpritesData[sprite].Height + ox;
+ VertexBuffer[4].Y:= topy + SpritesData[sprite].Height + dy;
+ VertexBuffer[5].X:= RightX + WorldDx + ox;
+ VertexBuffer[5].Y:= topy + dy;
+ VertexBuffer[6].X:= VertexBuffer[4].X;
+ VertexBuffer[6].Y:= ViewTopY;
+ VertexBuffer[7].X:= VertexBuffer[5].X;
+ VertexBuffer[7].Y:= ViewTopY;
-{$IFDEF GL2}
-UpdateModelviewProjection;
-{$ENDIF}
+ waves:= 2 * lw / cWaveWidth;
+ shift:= - lw / cWaveWidth;
+ TextureBuffer[3].X:= shift + ((LongInt(RealTicks shr 6) * Dir + ox) mod cWaveWidth) / (cWaveWidth - 1);
+ TextureBuffer[3].Y:= 0;
+ TextureBuffer[5].X:= TextureBuffer[3].X + waves;
+ TextureBuffer[5].Y:= 0;
+ TextureBuffer[4].X:= TextureBuffer[5].X;
+ TextureBuffer[4].Y:= SpritesData[sprite].Texture^.ry;
+ TextureBuffer[2].X:= TextureBuffer[3].X;
+ TextureBuffer[2].Y:= SpritesData[sprite].Texture^.ry;
+
+ waves:= (topy + dy - ViewTopY) / cWaveWidth;
-glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer));
+ // left side
+ TextureBuffer[1].X:= TextureBuffer[3].X - waves;
+ TextureBuffer[1].Y:= 0;
+ TextureBuffer[0].X:= TextureBuffer[1].X;
+ TextureBuffer[0].Y:= SpritesData[sprite].Texture^.ry;
+
+ // right side
+ TextureBuffer[7].X:= TextureBuffer[5].X + waves;
+ TextureBuffer[7].Y:= 0;
+ TextureBuffer[6].X:= TextureBuffer[7].X;
+ TextureBuffer[6].Y:= SpritesData[sprite].Texture^.ry;
+
+
+ SetVertexPointer(@VertexBuffer[0], 8);
+ SetTexCoordPointer(@TextureBuffer[0], 8);
+
+ {$IFDEF GL2}
+ UpdateModelviewProjection;
+ {$ENDIF}
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
+ end;
untint;
@@ -1130,7 +1248,7 @@
VertexBuffer: array [0..3] of TVertex2f;
c1, c2: LongWord; // couple of colours for edges
begin
-if WorldEdge <> weNone then
+if (WorldEdge <> weNone) and (WorldEdge <> weSea) then
begin
(* I think for a bounded world, will fill the left and right areas with black or something. Also will probably want various border effects/animations based on border type. Prob also, say, trigger a border animation timer on an impact. *)
@@ -1364,11 +1482,14 @@
offsetX, offsetY, screenBottom: LongInt;
VertexBuffer: array [0..3] of TVertex2f;
begin
+ScreenBottom:= (WorldDy - trunc(cScreenHeight/cScaleFactor) - (cScreenHeight div 2) + cWaterLine);
+
+// note: offsetY is negative!
+offsetY:= 5 * max(-145,min(0, CWaterLine + WorldDy - ViewBottomY)); //10 * Min(0, -145 - ScreenBottom);
+
if (cReducedQuality and rqNoBackground) = 0 then
begin
// Offsets relative to camera - spare them to wimpier cpus, no bg or flakes for them anyway
- ScreenBottom:= (WorldDy - trunc(cScreenHeight/cScaleFactor) - (cScreenHeight div 2) + cWaterLine);
- offsetY:= 10 * Min(0, -145 - ScreenBottom);
SkyOffset:= offsetY div 35 + cWaveHeight;
HorizontOffset:= SkyOffset;
if ScreenBottom > SkyOffset then
@@ -1392,18 +1513,18 @@
if (cReducedQuality and rq2DWater) = 0 then
begin
// Waves
- DrawWater(255, SkyOffset);
+ DrawWater(255, SkyOffset, 0);
ChangeDepth(RM, -cStereo_Water_distant);
- DrawWaves( 1, 0 - WorldDx div 32, - cWaveHeight + offsetY div 35, 64);
+ DrawWaves( 1, 0 - WorldDx div 32, offsetY div 35, -49, 64);
ChangeDepth(RM, -cStereo_Water_distant);
- DrawWaves( -1, 25 + WorldDx div 25, - cWaveHeight + offsetY div 38, 48);
+ DrawWaves( -1, 25 + WorldDx div 25, offsetY div 38, -37, 48);
ChangeDepth(RM, -cStereo_Water_distant);
- DrawWaves( 1, 75 - WorldDx div 19, - cWaveHeight + offsetY div 45, 32);
+ DrawWaves( 1, 75 - WorldDx div 19, offsetY div 45, -23, 32);
ChangeDepth(RM, -cStereo_Water_distant);
- DrawWaves(-1, 100 + WorldDx div 14, - cWaveHeight + offsetY div 70, 24);
+ DrawWaves(-1, 100 + WorldDx div 14, offsetY div 70, -7, 24);
end
else
- DrawWaves(-1, 100, - (cWaveHeight + (cWaveHeight shr 1)), 0);
+ DrawWaves(-1, 100, - cWaveHeight div 2, - cWaveHeight div 2, 0);
changeDepth(RM, cStereo_Land);
DrawVisualGears(5);
@@ -1414,7 +1535,7 @@
DrawLand(WorldDx + playWidth, WorldDy);
end;
- DrawWater(255, 0);
+ DrawWater(255, 0, 0);
(*
// Attack bar
@@ -1463,34 +1584,34 @@
if SuddenDeathDmg then
- DrawWater(SDWaterOpacity, 0)
+ DrawWater(SDWaterOpacity, 0, 0)
else
- DrawWater(WaterOpacity, 0);
+ DrawWater(WaterOpacity, 0, 0);
// Waves
ChangeDepth(RM, cStereo_Water_near);
-DrawWaves( 1, 25 - WorldDx div 9, - cWaveHeight, 12);
+DrawWaves( 1, 25 - WorldDx div 9, 0, 0, 12);
if (cReducedQuality and rq2DWater) = 0 then
begin
//DrawWater(WaterOpacity, - offsetY div 40);
ChangeDepth(RM, cStereo_Water_near);
- DrawWaves(-1, 50 + WorldDx div 6, - cWaveHeight - offsetY div 40, 8);
+ DrawWaves(-1, 50 + WorldDx div 6, - offsetY div 40, 23, 8);
if SuddenDeathDmg then
- DrawWater(SDWaterOpacity, - offsetY div 20)
+ DrawWater(SDWaterOpacity, - offsetY div 20, 23)
else
- DrawWater(WaterOpacity, - offsetY div 20);
+ DrawWater(WaterOpacity, - offsetY div 20, 23);
ChangeDepth(RM, cStereo_Water_near);
- DrawWaves( 1, 75 - WorldDx div 4, - cWaveHeight - offsetY div 20, 2);
+ DrawWaves( 1, 75 - WorldDx div 4, - offsetY div 20, 37, 2);
if SuddenDeathDmg then
- DrawWater(SDWaterOpacity, - offsetY div 10)
+ DrawWater(SDWaterOpacity, - offsetY div 10, 47)
else
- DrawWater(WaterOpacity, - offsetY div 10);
+ DrawWater(WaterOpacity, - offsetY div 10, 47);
ChangeDepth(RM, cStereo_Water_near);
- DrawWaves( -1, 25 + WorldDx div 3, - cWaveHeight - offsetY div 10, 0);
+ DrawWaves( -1, 25 + WorldDx div 3, - offsetY div 10, 59, 0);
end
else
- DrawWaves(-1, 50, - (cWaveHeight shr 1), 0);
+ DrawWaves(-1, 50, cWaveHeight div 2, cWaveHeight div 2, 0);
// everything after this ChangeDepth will be drawn outside the screen
// note: negative parallax gears should last very little for a smooth stereo effect