788 if (AMShiftX = 0) and (AMShiftY = 0) then |
788 if (AMShiftX = 0) and (AMShiftY = 0) then |
789 DrawSprite(sprArrow, CursorPoint.X, cScreenHeight - CursorPoint.Y, (RealTicks shr 6) mod 8); |
789 DrawSprite(sprArrow, CursorPoint.X, cScreenHeight - CursorPoint.Y, (RealTicks shr 6) mod 8); |
790 {$ENDIF} |
790 {$ENDIF} |
791 end; |
791 end; |
792 |
792 |
793 procedure DrawWaves(Dir, dX, dY, oX: LongInt; tnt: Byte); |
|
794 var VertexBuffer, TextureBuffer: array [0..7] of TVertex2f; |
|
795 lw, waves, shift: GLfloat; |
|
796 sprite: TSprite; |
|
797 topy: LongInt; |
|
798 begin |
|
799 |
|
800 dY:= -cWaveHeight + dy; |
|
801 ox:= -cWaveHeight + ox; |
|
802 |
|
803 topy:= cWaterLine + WorldDy + dY; |
|
804 |
|
805 if (WorldEdge <> weSea) and (topY > ViewBottomY) then |
|
806 exit; |
|
807 |
|
808 if SuddenDeathDmg then |
|
809 sprite:= sprSDWater |
|
810 else |
|
811 sprite:= sprWater; |
|
812 |
|
813 cWaveWidth:= SpritesData[sprite].Width; |
|
814 |
|
815 if WorldEdge = weSea then |
|
816 lw:= playWidth div 2 |
|
817 else |
|
818 lw:= ViewWidth; |
|
819 |
|
820 if SuddenDeathDmg then |
|
821 Tint(LongInt(tnt) * SDWaterColorArray[2].r div 255 + 255 - tnt, |
|
822 LongInt(tnt) * SDWaterColorArray[2].g div 255 + 255 - tnt, |
|
823 LongInt(tnt) * SDWaterColorArray[2].b div 255 + 255 - tnt, |
|
824 255 |
|
825 ) |
|
826 else |
|
827 Tint(LongInt(tnt) * WaterColorArray[2].r div 255 + 255 - tnt, |
|
828 LongInt(tnt) * WaterColorArray[2].g div 255 + 255 - tnt, |
|
829 LongInt(tnt) * WaterColorArray[2].b div 255 + 255 - tnt, |
|
830 255 |
|
831 ); |
|
832 |
|
833 glBindTexture(GL_TEXTURE_2D, SpritesData[sprite].Texture^.id); |
|
834 |
|
835 if WorldEdge <> weSea then |
|
836 begin |
|
837 if topY < ViewBottomY then |
|
838 begin |
|
839 VertexBuffer[0].X:= -lw; |
|
840 VertexBuffer[0].Y:= cWaterLine + WorldDy + dY; |
|
841 VertexBuffer[1].X:= lw; |
|
842 VertexBuffer[1].Y:= VertexBuffer[0].Y; |
|
843 VertexBuffer[2].X:= lw; |
|
844 VertexBuffer[2].Y:= VertexBuffer[0].Y + SpritesData[sprite].Height; |
|
845 VertexBuffer[3].X:= -lw; |
|
846 VertexBuffer[3].Y:= VertexBuffer[2].Y; |
|
847 |
|
848 waves:= lw * 2 / cWaveWidth; |
|
849 shift:= - lw / cWaveWidth; |
|
850 TextureBuffer[0].X:= shift + (( - WorldDx + LongInt(RealTicks shr 6) * Dir + dX) mod cWaveWidth) / (cWaveWidth - 1); |
|
851 TextureBuffer[0].Y:= 0; |
|
852 TextureBuffer[1].X:= TextureBuffer[0].X + waves; |
|
853 TextureBuffer[1].Y:= TextureBuffer[0].Y; |
|
854 TextureBuffer[2].X:= TextureBuffer[1].X; |
|
855 TextureBuffer[2].Y:= SpritesData[sprite].Texture^.ry; |
|
856 TextureBuffer[3].X:= TextureBuffer[0].X; |
|
857 TextureBuffer[3].Y:= TextureBuffer[2].Y; |
|
858 |
|
859 |
|
860 SetVertexPointer(@VertexBuffer[0], 4); |
|
861 SetTexCoordPointer(@TextureBuffer[0], 4); |
|
862 |
|
863 {$IFDEF GL2} |
|
864 UpdateModelviewProjection; |
|
865 {$ENDIF} |
|
866 |
|
867 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
|
868 end; |
|
869 end |
|
870 else // weSea: with waterwalls |
|
871 begin |
|
872 topy := cWaterLine + WorldDy; |
|
873 |
|
874 // We will draw both bottom water and the water walls with a single call, |
|
875 // by rendering a GL_TRIANGLE_STRIP of eight points. |
|
876 // |
|
877 // GL_TRIANGLE_STRIP works like this: "always create triangle between |
|
878 // newest point and the two points that were specified before it." |
|
879 // |
|
880 // To get the result we want we will order the points like this: |
|
881 // ^ -Y |
|
882 // | |
|
883 // 0-------1 7-------6 <---------------------- ViewTopY -| |
|
884 // | /| | _/| | |
|
885 // | / | | / | | |
|
886 // | / | | _/ | | |
|
887 // | / | | / | | |
|
888 // | / _.3---------5{ | <--- topy = cWaterLine + WorldDy -| |
|
889 // | / _/ `---.___ `--._ | | |
|
890 // |/_/ `---.___\| | |
|
891 // 2-------------------------4 <------------ topy + wave height -| |
|
892 // | |
|
893 // ^ ^ ^ ^ V +Y |
|
894 // | | | | |
|
895 // | | | RightX + WorldDx + wave height |
|
896 // | | | . |
|
897 // | | RightX + WorldDx. |
|
898 // | | . . |
|
899 // | LeftX + WorldDx . . |
|
900 // | . . . |
|
901 // LeftX - wave height + WorldDx |
|
902 // | . . . |
|
903 // <--------------------------------> |
|
904 // -X +X |
|
905 // |
|
906 // Note: additionally the parameters ox and dy are used to create different |
|
907 // horizontal and vertical offsets between wave layers |
|
908 |
|
909 |
|
910 VertexBuffer[0].X:= LeftX + WorldDx - SpritesData[sprite].Height - ox; |
|
911 VertexBuffer[0].Y:= ViewTopY; |
|
912 VertexBuffer[1].X:= LeftX + WorldDx - ox; |
|
913 VertexBuffer[1].Y:= ViewTopY; |
|
914 VertexBuffer[2].X:= VertexBuffer[0].X; |
|
915 VertexBuffer[2].Y:= topy + SpritesData[sprite].Height + dy; |
|
916 VertexBuffer[3].X:= VertexBuffer[1].X; |
|
917 VertexBuffer[3].Y:= topy + dy; |
|
918 VertexBuffer[4].X:= RightX + WorldDx + SpritesData[sprite].Height + ox; |
|
919 VertexBuffer[4].Y:= topy + SpritesData[sprite].Height + dy; |
|
920 VertexBuffer[5].X:= RightX + WorldDx + ox; |
|
921 VertexBuffer[5].Y:= topy + dy; |
|
922 VertexBuffer[6].X:= VertexBuffer[4].X; |
|
923 VertexBuffer[6].Y:= ViewTopY; |
|
924 VertexBuffer[7].X:= VertexBuffer[5].X; |
|
925 VertexBuffer[7].Y:= ViewTopY; |
|
926 |
|
927 waves:= 2 * lw / cWaveWidth; |
|
928 shift:= - lw / cWaveWidth; |
|
929 TextureBuffer[3].X:= shift + ((LongInt(RealTicks shr 6) * Dir + ox) mod cWaveWidth) / (cWaveWidth - 1); |
|
930 TextureBuffer[3].Y:= 0; |
|
931 TextureBuffer[5].X:= TextureBuffer[3].X + waves; |
|
932 TextureBuffer[5].Y:= 0; |
|
933 TextureBuffer[4].X:= TextureBuffer[5].X; |
|
934 TextureBuffer[4].Y:= SpritesData[sprite].Texture^.ry; |
|
935 TextureBuffer[2].X:= TextureBuffer[3].X; |
|
936 TextureBuffer[2].Y:= SpritesData[sprite].Texture^.ry; |
|
937 |
|
938 waves:= (topy + dy - ViewTopY) / cWaveWidth; |
|
939 |
|
940 // left side |
|
941 TextureBuffer[1].X:= TextureBuffer[3].X - waves; |
|
942 TextureBuffer[1].Y:= 0; |
|
943 TextureBuffer[0].X:= TextureBuffer[1].X; |
|
944 TextureBuffer[0].Y:= SpritesData[sprite].Texture^.ry; |
|
945 |
|
946 // right side |
|
947 TextureBuffer[7].X:= TextureBuffer[5].X + waves; |
|
948 TextureBuffer[7].Y:= 0; |
|
949 TextureBuffer[6].X:= TextureBuffer[7].X; |
|
950 TextureBuffer[6].Y:= SpritesData[sprite].Texture^.ry; |
|
951 |
|
952 |
|
953 SetVertexPointer(@VertexBuffer[0], 8); |
|
954 SetTexCoordPointer(@TextureBuffer[0], 8); |
|
955 |
|
956 {$IFDEF GL2} |
|
957 UpdateModelviewProjection; |
|
958 {$ENDIF} |
|
959 |
|
960 glDrawArrays(GL_TRIANGLE_STRIP, 0, 8); |
|
961 end; |
|
962 |
|
963 untint; |
|
964 |
|
965 {for i:= -1 to cWaterSprCount do |
|
966 DrawSprite(sprWater, |
|
967 i * cWaveWidth + ((WorldDx + (RealTicks shr 6) * Dir + dX) mod cWaveWidth) - (cScreenWidth div 2), |
|
968 cWaterLine + WorldDy + dY, |
|
969 0)} |
|
970 end; |
|
971 |
|
972 procedure DrawRepeated(spr, sprL, sprR: TSprite; Shift, OffsetY: LongInt); |
793 procedure DrawRepeated(spr, sprL, sprR: TSprite; Shift, OffsetY: LongInt); |
973 var i, w, h, lw, lh, rw, rh, sw: LongInt; |
794 var i, w, h, lw, lh, rw, rh, sw: LongInt; |
974 begin |
795 begin |
975 sw:= round(cScreenWidth / cScaleFactor); |
796 sw:= round(cScreenWidth / cScaleFactor); |
976 if (SpritesData[sprL].Texture = nil) and (SpritesData[spr].Texture <> nil) then |
797 if (SpritesData[sprL].Texture = nil) and (SpritesData[spr].Texture <> nil) then |