28 procedure initModule; |
28 procedure initModule; |
29 procedure freeModule; |
29 procedure freeModule; |
30 |
30 |
31 procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); |
31 procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); |
32 procedure DrawSprite (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); |
32 procedure DrawSprite (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); |
33 procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline; |
33 procedure DrawSpriteFromRect (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); |
34 procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
34 procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
35 procedure DrawSpriteRotated (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); |
35 procedure DrawSpriteRotated (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real); |
36 procedure DrawSpriteRotatedF (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); |
36 procedure DrawSpriteRotatedF (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real); |
37 procedure DrawSpriteRotatedFReal(Sprite: TSprite; X, Y: Real; Frame, Dir: LongInt; Angle: real); |
37 procedure DrawSpriteRotatedFReal(Sprite: TSprite; X, Y: Real; Frame, Dir: LongInt; Angle: real); |
38 procedure DrawSpritePivotedF(Sprite: TSprite; X, Y, Frame, Dir, PivotX, PivotY: LongInt; Angle: real); |
38 procedure DrawSpritePivotedF(Sprite: TSprite; X, Y, Frame, Dir, PivotX, PivotY: LongInt; Angle: real); |
39 |
39 |
40 procedure DrawTexture (X, Y: LongInt; Texture: PTexture); inline; |
40 procedure DrawTexture (X, Y: LongInt; Texture: PTexture); |
41 procedure DrawTexture (X, Y: LongInt; Texture: PTexture; Scale: GLfloat); |
41 procedure DrawTexture (X, Y: LongInt; Texture: PTexture; Scale: GLfloat); |
42 procedure DrawTexture2 (X, Y: LongInt; Texture: PTexture; Scale, Overlap: GLfloat); |
42 procedure DrawTexture2 (X, Y: LongInt; Texture: PTexture; Scale, Overlap: GLfloat); |
43 procedure DrawTextureFromRect (X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline; |
43 procedure DrawTextureFromRect (X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
44 procedure DrawTextureFromRect (X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline; |
44 procedure DrawTextureFromRect (X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
45 procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt); |
45 procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt); |
46 procedure DrawTextureCentered (X, Top: LongInt; Source: PTexture); |
46 procedure DrawTextureCentered (X, Top: LongInt; Source: PTexture); |
47 procedure DrawTextureF (Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt); |
47 procedure DrawTextureF (Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt); |
48 procedure DrawTextureRotated (Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
48 procedure DrawTextureRotated (Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
49 procedure DrawTextureRotatedF (Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
49 procedure DrawTextureRotatedF (Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
51 procedure DrawCircle (X, Y, Radius, Width: LongInt); |
51 procedure DrawCircle (X, Y, Radius, Width: LongInt); |
52 procedure DrawCircle (X, Y, Radius, Width: LongInt; r, g, b, a: Byte); |
52 procedure DrawCircle (X, Y, Radius, Width: LongInt; r, g, b, a: Byte); |
53 procedure DrawCircle (X, Y, Radius, Width: LongInt; color: LongWord); |
53 procedure DrawCircle (X, Y, Radius, Width: LongInt; color: LongWord); |
54 procedure DrawCircleFilled (X, Y, Radius: LongInt; r, g, b, a: Byte); |
54 procedure DrawCircleFilled (X, Y, Radius: LongInt; r, g, b, a: Byte); |
55 |
55 |
56 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; |
56 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; color: LongWord); |
57 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
57 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
58 procedure DrawLineWrapped (X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; color: LongWord); inline; |
58 procedure DrawLineWrapped (X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; color: LongWord); |
59 procedure DrawLineWrapped (X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; r, g, b, a: Byte); |
59 procedure DrawLineWrapped (X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; r, g, b, a: Byte); |
60 procedure DrawLineOnScreen (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
60 procedure DrawLineOnScreen (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
61 procedure DrawRect (rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean); |
61 procedure DrawRect (rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean); |
62 procedure DrawHedgehog (X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
62 procedure DrawHedgehog (X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
63 procedure DrawScreenWidget (widget: POnScreenWidget); |
63 procedure DrawScreenWidget (widget: POnScreenWidget); |
68 {$IFDEF USE_S3D_RENDERING} |
68 {$IFDEF USE_S3D_RENDERING} |
69 procedure RenderClear (mode: TRenderMode); |
69 procedure RenderClear (mode: TRenderMode); |
70 {$ENDIF} |
70 {$ENDIF} |
71 procedure RenderSetClearColor (r, g, b, a: real); |
71 procedure RenderSetClearColor (r, g, b, a: real); |
72 procedure Tint (r, g, b, a: Byte); |
72 procedure Tint (r, g, b, a: Byte); |
73 procedure Tint (c: Longword); inline; |
73 procedure Tint (c: Longword); |
74 procedure untint(); inline; |
74 procedure untint(); |
75 procedure setTintAdd (enable: boolean); inline; |
75 procedure setTintAdd (enable: boolean); |
76 |
76 |
77 // call this to finish the rendering of current frame |
77 // call this to finish the rendering of current frame |
78 procedure FinishRender(); |
78 procedure FinishRender(); |
79 |
79 |
80 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
80 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; |
81 function isCircleOffscreen(X, Y, RadiusSquared: LongInt): boolean; inline; |
81 function isCircleOffscreen(X, Y, RadiusSquared: LongInt): boolean; |
82 |
82 |
83 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen |
83 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen |
84 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline; |
84 function isDxAreaOffscreen(X, Width: LongInt): LongInt; |
85 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline; |
85 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; |
86 |
86 |
87 procedure SetScale(f: GLfloat); |
87 procedure SetScale(f: GLfloat); |
88 procedure UpdateViewLimits(); |
88 procedure UpdateViewLimits(); |
89 |
89 |
90 procedure RendererSetup(); |
90 procedure RendererSetup(); |
95 |
95 |
96 // TODO everything below this should not need a public interface |
96 // TODO everything below this should not need a public interface |
97 |
97 |
98 procedure EnableTexture(enable:Boolean); |
98 procedure EnableTexture(enable:Boolean); |
99 |
99 |
100 procedure SetTexCoordPointer(p: Pointer;n: Integer); inline; |
100 procedure SetTexCoordPointer(p: Pointer;n: Integer); |
101 procedure SetVertexPointer(p: Pointer;n: Integer); inline; |
101 procedure SetVertexPointer(p: Pointer;n: Integer); |
102 procedure SetColorPointer(p: Pointer;n: Integer); inline; |
102 procedure SetColorPointer(p: Pointer;n: Integer); |
103 |
103 |
104 procedure UpdateModelviewProjection(); inline; |
104 procedure UpdateModelviewProjection(); |
105 |
105 |
106 procedure openglPushMatrix (); inline; |
106 procedure openglPushMatrix (); |
107 procedure openglPopMatrix (); inline; |
107 procedure openglPopMatrix (); |
108 procedure openglTranslatef (X, Y, Z: GLfloat); inline; |
108 procedure openglTranslatef (X, Y, Z: GLfloat); |
109 |
109 |
110 |
110 |
111 implementation |
111 implementation |
112 uses {$IFNDEF PAS2C} StrUtils, {$ENDIF}uVariables, uUtils |
112 uses {$IFNDEF PAS2C} StrUtils, {$ENDIF}uVariables, uUtils |
113 {$IFDEF GL2}, uMatrix, uConsole, uPhysFSLayer, uDebug{$ENDIF}, uConsts; |
113 {$IFDEF GL2}, uMatrix, uConsole, uPhysFSLayer, uDebug{$ENDIF}, uConsts; |
145 {$IFDEF USE_S3D_RENDERING OR USE_VIDEO_RECORDING} |
145 {$IFDEF USE_S3D_RENDERING OR USE_VIDEO_RECORDING} |
146 procedure CreateFramebuffer(var frame, depth, tex: GLuint); forward; |
146 procedure CreateFramebuffer(var frame, depth, tex: GLuint); forward; |
147 procedure DeleteFramebuffer(var frame, depth, tex: GLuint); forward; |
147 procedure DeleteFramebuffer(var frame, depth, tex: GLuint); forward; |
148 {$ENDIF} |
148 {$ENDIF} |
149 |
149 |
150 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
150 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; |
151 begin |
151 begin |
152 isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0); |
152 isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0); |
153 end; |
153 end; |
154 |
154 |
155 function isCircleOffscreen(X, Y, RadiusSquared: LongInt): boolean; inline; |
155 function isCircleOffscreen(X, Y, RadiusSquared: LongInt): boolean; |
156 var dRightX, dBottomY, dLeftX, dTopY: LongInt; |
156 var dRightX, dBottomY, dLeftX, dTopY: LongInt; |
157 begin |
157 begin |
158 dRightX:= (X - ViewRightX); |
158 dRightX:= (X - ViewRightX); |
159 dBottomY:= (Y - ViewBottomY); |
159 dBottomY:= (Y - ViewBottomY); |
160 dLeftX:= (ViewLeftX - X); |
160 dLeftX:= (ViewLeftX - X); |
164 ((dBottomY > 0) and (sqr(dBottomY) > RadiusSquared)) or |
164 ((dBottomY > 0) and (sqr(dBottomY) > RadiusSquared)) or |
165 ((dLeftX > 0) and (sqr(dLeftX) > RadiusSquared)) or |
165 ((dLeftX > 0) and (sqr(dLeftX) > RadiusSquared)) or |
166 ((dTopY > 0) and (sqr(dTopY) > RadiusSquared)) |
166 ((dTopY > 0) and (sqr(dTopY) > RadiusSquared)) |
167 end; |
167 end; |
168 |
168 |
169 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline; |
169 function isDxAreaOffscreen(X, Width: LongInt): LongInt; |
170 begin |
170 begin |
171 if X > ViewRightX then exit(1); |
171 if X > ViewRightX then exit(1); |
172 if X + Width < ViewLeftX then exit(-1); |
172 if X + Width < ViewLeftX then exit(-1); |
173 isDxAreaOffscreen:= 0; |
173 isDxAreaOffscreen:= 0; |
174 end; |
174 end; |
175 |
175 |
176 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline; |
176 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; |
177 begin |
177 begin |
178 if Y > ViewBottomY then exit(1); |
178 if Y > ViewBottomY then exit(1); |
179 if Y + Height < ViewTopY then exit(-1); |
179 if Y + Height < ViewTopY then exit(-1); |
180 isDyAreaOffscreen:= 0; |
180 isDyAreaOffscreen:= 0; |
181 end; |
181 end; |
678 glTranslatef(X, Y, Z); |
678 glTranslatef(X, Y, Z); |
679 glMatrixMode(GL_MODELVIEW); |
679 glMatrixMode(GL_MODELVIEW); |
680 {$ENDIF} |
680 {$ENDIF} |
681 end; |
681 end; |
682 |
682 |
683 procedure openglPushMatrix(); inline; |
683 procedure openglPushMatrix(); |
684 begin |
684 begin |
685 {$IFDEF GL2} |
685 {$IFDEF GL2} |
686 hglPushMatrix(); |
686 hglPushMatrix(); |
687 {$ELSE} |
687 {$ELSE} |
688 glPushMatrix(); |
688 glPushMatrix(); |
689 {$ENDIF} |
689 {$ENDIF} |
690 end; |
690 end; |
691 |
691 |
692 procedure openglPopMatrix(); inline; |
692 procedure openglPopMatrix(); |
693 begin |
693 begin |
694 {$IFDEF GL2} |
694 {$IFDEF GL2} |
695 hglPopMatrix(); |
695 hglPopMatrix(); |
696 {$ELSE} |
696 {$ELSE} |
697 glPopMatrix(); |
697 glPopMatrix(); |
698 {$ENDIF} |
698 {$ENDIF} |
699 end; |
699 end; |
700 |
700 |
701 procedure openglTranslatef(X, Y, Z: GLfloat); inline; |
701 procedure openglTranslatef(X, Y, Z: GLfloat); |
702 begin |
702 begin |
703 {$IFDEF GL2} |
703 {$IFDEF GL2} |
704 hglTranslatef(X, Y, Z); |
704 hglTranslatef(X, Y, Z); |
705 {$ELSE} |
705 {$ELSE} |
706 glTranslatef(X, Y, Z); |
706 glTranslatef(X, Y, Z); |
707 {$ENDIF} |
707 {$ENDIF} |
708 end; |
708 end; |
709 |
709 |
710 procedure openglScalef(ScaleX, ScaleY, ScaleZ: GLfloat); inline; |
710 procedure openglScalef(ScaleX, ScaleY, ScaleZ: GLfloat); |
711 begin |
711 begin |
712 {$IFDEF GL2} |
712 {$IFDEF GL2} |
713 hglScalef(ScaleX, ScaleY, ScaleZ); |
713 hglScalef(ScaleX, ScaleY, ScaleZ); |
714 {$ELSE} |
714 {$ELSE} |
715 glScalef(ScaleX, ScaleY, ScaleZ); |
715 glScalef(ScaleX, ScaleY, ScaleZ); |
716 {$ENDIF} |
716 {$ENDIF} |
717 end; |
717 end; |
718 |
718 |
719 procedure openglRotatef(RotX, RotY, RotZ: GLfloat; dir: LongInt); inline; |
719 procedure openglRotatef(RotX, RotY, RotZ: GLfloat; dir: LongInt); |
720 { workaround for pascal bug https://bugs.freepascal.org/view.php?id=27222 } |
720 { workaround for pascal bug https://bugs.freepascal.org/view.php?id=27222 } |
721 var tmpdir: LongInt; |
721 var tmpdir: LongInt; |
722 begin |
722 begin |
723 tmpdir:=dir; |
723 tmpdir:=dir; |
724 {$IFDEF GL2} |
724 {$IFDEF GL2} |
885 updateViewLimits(); |
885 updateViewLimits(); |
886 |
886 |
887 UpdateModelviewProjection; |
887 UpdateModelviewProjection; |
888 end; |
888 end; |
889 |
889 |
890 procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline; |
890 procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); |
891 begin |
891 begin |
892 r.y:= r.y + Height * Position; |
892 r.y:= r.y + Height * Position; |
893 r.h:= Height; |
893 r.h:= Height; |
894 DrawTextureFromRect(X, Y, @r, SpritesData[Sprite].Texture) |
894 DrawTextureFromRect(X, Y, @r, SpritesData[Sprite].Texture) |
895 end; |
895 end; |
896 |
896 |
897 procedure DrawTextureFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline; |
897 procedure DrawTextureFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
898 begin |
898 begin |
899 DrawTextureFromRectDir(X, Y, r^.w, r^.h, r, SourceTexture, 1) |
899 DrawTextureFromRectDir(X, Y, r^.w, r^.h, r, SourceTexture, 1) |
900 end; |
900 end; |
901 |
901 |
902 procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline; |
902 procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); |
903 begin |
903 begin |
904 DrawTextureFromRectDir(X, Y, W, H, r, SourceTexture, 1) |
904 DrawTextureFromRectDir(X, Y, W, H, r, SourceTexture, 1) |
905 end; |
905 end; |
906 |
906 |
907 procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt); |
907 procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt); |
1373 DrawTexture(left, Top, Source); |
1373 DrawTexture(left, Top, Source); |
1374 end; |
1374 end; |
1375 end; |
1375 end; |
1376 |
1376 |
1377 // Same as below, but with color as LongWord |
1377 // Same as below, but with color as LongWord |
1378 procedure DrawLine(X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; |
1378 procedure DrawLine(X0, Y0, X1, Y1, Width: Single; color: LongWord); |
1379 begin |
1379 begin |
1380 DrawLine(X0, Y0, X1, Y1, Width, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF) |
1380 DrawLine(X0, Y0, X1, Y1, Width, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF) |
1381 end; |
1381 end; |
1382 |
1382 |
1383 // Draw line between 2 points |
1383 // Draw line between 2 points |
1398 |
1398 |
1399 UpdateModelviewProjection; |
1399 UpdateModelviewProjection; |
1400 end; |
1400 end; |
1401 |
1401 |
1402 // Same as below, but with color as a longword |
1402 // Same as below, but with color as a longword |
1403 procedure DrawLineWrapped(X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; color: LongWord); inline; |
1403 procedure DrawLineWrapped(X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; color: LongWord); |
1404 begin |
1404 begin |
1405 DrawLineWrapped(X0, Y0, X1, Y1, Width, goesLeft, Wraps, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF); |
1405 DrawLineWrapped(X0, Y0, X1, Y1, Width, goesLeft, Wraps, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF); |
1406 end; |
1406 end; |
1407 |
1407 |
1408 // Draw a line between 2 points, but it wraps around the |
1408 // Draw a line between 2 points, but it wraps around the |
2107 |
2107 |
2108 openglTint(r, g, b, a); |
2108 openglTint(r, g, b, a); |
2109 LastTint:= nc; |
2109 LastTint:= nc; |
2110 end; |
2110 end; |
2111 |
2111 |
2112 procedure Tint(c: Longword); inline; |
2112 procedure Tint(c: Longword); |
2113 begin |
2113 begin |
2114 if c = LastTint then exit; |
2114 if c = LastTint then exit; |
2115 Tint(((c shr 24) and $FF), ((c shr 16) and $FF), (c shr 8) and $FF, (c and $FF)) |
2115 Tint(((c shr 24) and $FF), ((c shr 16) and $FF), (c shr 8) and $FF, (c and $FF)) |
2116 end; |
2116 end; |
2117 |
2117 |
2118 procedure untint(); inline; |
2118 procedure untint(); |
2119 begin |
2119 begin |
2120 if cWhiteColor = LastTint then exit; |
2120 if cWhiteColor = LastTint then exit; |
2121 openglTint($FF, $FF, $FF, $FF); |
2121 openglTint($FF, $FF, $FF, $FF); |
2122 LastTint:= cWhiteColor; |
2122 LastTint:= cWhiteColor; |
2123 end; |
2123 end; |
2124 |
2124 |
2125 procedure setTintAdd(enable: boolean); inline; |
2125 procedure setTintAdd(enable: boolean); |
2126 begin |
2126 begin |
2127 {$IFDEF GL2} |
2127 {$IFDEF GL2} |
2128 if enable then |
2128 if enable then |
2129 glUniform1i(glGetUniformLocation(shaderMain, pchar('tintAdd')), 1) |
2129 glUniform1i(glGetUniformLocation(shaderMain, pchar('tintAdd')), 1) |
2130 else |
2130 else |