46 procedure DrawTextureRotated (Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
46 procedure DrawTextureRotated (Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
47 procedure DrawTextureRotatedF (Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
47 procedure DrawTextureRotatedF (Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
48 |
48 |
49 procedure DrawCircle (X, Y, Radius, Width: LongInt); |
49 procedure DrawCircle (X, Y, Radius, Width: LongInt); |
50 procedure DrawCircle (X, Y, Radius, Width: LongInt; r, g, b, a: Byte); |
50 procedure DrawCircle (X, Y, Radius, Width: LongInt; r, g, b, a: Byte); |
|
51 procedure DrawCircleFilled (X, Y, Radius: LongInt; r, g, b, a: Byte); |
51 |
52 |
52 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; |
53 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; |
53 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
54 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
54 procedure DrawLineOnScreen (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
55 procedure DrawLineOnScreen (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
55 procedure DrawRect (rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean); |
56 procedure DrawRect (rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean); |
57 procedure DrawScreenWidget (widget: POnScreenWidget); |
58 procedure DrawScreenWidget (widget: POnScreenWidget); |
58 procedure DrawWater (Alpha: byte; OffsetY, OffsetX: LongInt); |
59 procedure DrawWater (Alpha: byte; OffsetY, OffsetX: LongInt); |
59 procedure DrawWaves (Dir, dX, dY, oX: LongInt; tnt: Byte); |
60 procedure DrawWaves (Dir, dX, dY, oX: LongInt; tnt: Byte); |
60 |
61 |
61 procedure RenderClear (); |
62 procedure RenderClear (); |
62 procedure RenderSetClearColor (r, g, b, a: real); |
63 procedure RenderClear (mode: TRenderMode); |
|
64 procedure RenderSetClearColor (r, g, b, a: real); |
63 procedure Tint (r, g, b, a: Byte); inline; |
65 procedure Tint (r, g, b, a: Byte); inline; |
64 procedure Tint (c: Longword); inline; |
66 procedure Tint (c: Longword); inline; |
65 procedure untint(); inline; |
67 procedure untint(); inline; |
66 procedure setTintAdd (f: boolean); inline; |
68 procedure setTintAdd (f: boolean); inline; |
67 |
69 |
|
70 // call this to finish the rendering of current frame |
|
71 procedure FinishRender(); |
|
72 |
68 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
73 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
69 |
74 |
70 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen |
75 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen |
71 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline; |
76 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline; |
72 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline; |
77 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline; |
73 |
78 |
74 procedure SetScale(f: GLfloat); |
79 procedure SetScale(f: GLfloat); |
75 procedure UpdateViewLimits(); |
80 procedure UpdateViewLimits(); |
76 |
81 |
77 procedure RenderSetup(); |
82 procedure RendererSetup(); |
|
83 procedure RendererCleanup(); |
|
84 |
|
85 procedure ChangeDepth(rm: TRenderMode; d: GLfloat); |
|
86 procedure ResetDepth(rm: TRenderMode); |
78 |
87 |
79 // TODO everything below this should not need a public interface |
88 // TODO everything below this should not need a public interface |
80 |
|
81 procedure CreateFramebuffer(var frame, depth, tex: GLuint); |
|
82 procedure DeleteFramebuffer(var frame, depth, tex: GLuint); |
|
83 |
89 |
84 procedure EnableTexture(enable:Boolean); |
90 procedure EnableTexture(enable:Boolean); |
85 |
91 |
86 procedure SetTexCoordPointer(p: Pointer;n: Integer); inline; |
92 procedure SetTexCoordPointer(p: Pointer;n: Integer); inline; |
87 procedure SetVertexPointer(p: Pointer;n: Integer); inline; |
93 procedure SetVertexPointer(p: Pointer;n: Integer); inline; |
88 procedure SetColorPointer(p: Pointer;n: Integer); inline; |
94 procedure SetColorPointer(p: Pointer;n: Integer); inline; |
89 |
95 |
90 procedure UpdateModelviewProjection(); inline; |
96 procedure UpdateModelviewProjection(); inline; |
91 |
97 |
92 procedure openglLoadIdentity (); inline; |
|
93 procedure openglTranslProjMatrix(X, Y, Z: GLFloat); inline; |
|
94 procedure openglPushMatrix (); inline; |
98 procedure openglPushMatrix (); inline; |
95 procedure openglPopMatrix (); inline; |
99 procedure openglPopMatrix (); inline; |
96 procedure openglTranslatef (X, Y, Z: GLfloat); inline; |
100 procedure openglTranslatef (X, Y, Z: GLfloat); inline; |
97 procedure openglScalef (ScaleX, ScaleY, ScaleZ: GLfloat); inline; |
|
98 procedure openglRotatef (RotX, RotY, RotZ: GLfloat; dir: LongInt); inline; |
|
99 procedure openglTint (r, g, b, a: Byte); inline; |
|
100 |
101 |
101 |
102 |
102 implementation |
103 implementation |
103 uses {$IFNDEF PAS2C} StrUtils, {$ENDIF}SysUtils, uVariables, uUtils, uConsts |
104 uses {$IFNDEF PAS2C} StrUtils, {$ENDIF}SysUtils, uVariables, uUtils, uConsts |
104 {$IFDEF GL2}, uMatrix, uConsole{$ENDIF}; |
105 {$IFDEF GL2}, uMatrix, uConsole{$ENDIF}; |
121 LastColorPointer , LastTexCoordPointer , LastVertexPointer : Pointer; |
122 LastColorPointer , LastTexCoordPointer , LastVertexPointer : Pointer; |
122 {$IFDEF GL2} |
123 {$IFDEF GL2} |
123 LastColorPointerN, LastTexCoordPointerN, LastVertexPointerN: Integer; |
124 LastColorPointerN, LastTexCoordPointerN, LastVertexPointerN: Integer; |
124 {$ENDIF} |
125 {$ENDIF} |
125 |
126 |
|
127 {$IFDEF USE_S3D_RENDERING} |
|
128 // texture/vertex buffers for left/right/default eye modes |
|
129 texLRDtb, texLvb, texRvb: array [0..3] of TVertex2f; |
|
130 {$ENDIF} |
|
131 |
|
132 procedure openglLoadIdentity (); forward; |
|
133 procedure openglTranslProjMatrix(X, Y, Z: GLFloat); forward; |
|
134 procedure openglScalef (ScaleX, ScaleY, ScaleZ: GLfloat); forward; |
|
135 procedure openglRotatef (RotX, RotY, RotZ: GLfloat; dir: LongInt); forward; |
|
136 procedure openglTint (r, g, b, a: Byte); forward; |
|
137 |
|
138 procedure CreateFramebuffer(var frame, depth, tex: GLuint); forward; |
|
139 procedure DeleteFramebuffer(var frame, depth, tex: GLuint); forward; |
|
140 |
126 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
141 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
127 begin |
142 begin |
128 isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0); |
143 isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0); |
129 end; |
144 end; |
130 |
145 |
145 procedure RenderClear(); |
160 procedure RenderClear(); |
146 begin |
161 begin |
147 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); |
162 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); |
148 end; |
163 end; |
149 |
164 |
|
165 {$IFDEF USE_S3D_RENDERING} |
|
166 procedure RenderClear(mode: TRenderMode); |
|
167 var frame: GLuint; |
|
168 begin |
|
169 if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then |
|
170 begin |
|
171 case mode of |
|
172 rmLeftEye: frame:= frameL; |
|
173 rmRightEye: frame:= frameR; |
|
174 else |
|
175 frame:= defaultFrame; |
|
176 end; |
|
177 |
|
178 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame); |
|
179 |
|
180 RenderClear(); |
|
181 end |
|
182 else |
|
183 begin |
|
184 // draw left eye in red channel only |
|
185 if mode = rmLeftEye then |
|
186 begin |
|
187 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
|
188 RenderClear(); |
|
189 if cStereoMode = smGreenRed then |
|
190 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE) |
|
191 else if cStereoMode = smBlueRed then |
|
192 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE) |
|
193 else if cStereoMode = smCyanRed then |
|
194 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE) |
|
195 else |
|
196 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); |
|
197 end |
|
198 else |
|
199 begin |
|
200 // draw right eye in selected channel(s) only |
|
201 if cStereoMode = smRedGreen then |
|
202 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE) |
|
203 else if cStereoMode = smRedBlue then |
|
204 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE) |
|
205 else if cStereoMode = smRedCyan then |
|
206 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE) |
|
207 else |
|
208 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); |
|
209 end; |
|
210 end; |
|
211 end; |
|
212 {$ENDIF} |
|
213 |
150 procedure RenderSetClearColor(r, g, b, a: real); |
214 procedure RenderSetClearColor(r, g, b, a: real); |
151 begin |
215 begin |
152 glClearColor(r, g, b, a); |
216 glClearColor(r, g, b, a); |
|
217 end; |
|
218 |
|
219 procedure FinishRender(); |
|
220 begin |
|
221 |
|
222 {$IFDEF USE_S3D_RENDERING} |
|
223 if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then |
|
224 begin |
|
225 RenderClear(rmDefault); |
|
226 |
|
227 SetScale(cDefaultZoomLevel); |
|
228 |
|
229 |
|
230 // same for all |
|
231 SetTexCoordPointer(@texLRDtb, Length(texLRDtb)); |
|
232 |
|
233 |
|
234 // draw left frame |
|
235 glBindTexture(GL_TEXTURE_2D, texl); |
|
236 SetVertexPointer(@texLvb, Length(texLvb)); |
|
237 //UpdateModelviewProjection; |
|
238 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(texLvb)); |
|
239 |
|
240 // draw right frame |
|
241 glBindTexture(GL_TEXTURE_2D, texl); |
|
242 SetVertexPointer(@texRvb, Length(texRvb)); |
|
243 //UpdateModelviewProjection; |
|
244 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(texRvb)); |
|
245 |
|
246 SetScale(zoom); |
|
247 end; |
|
248 {$ENDIF} |
153 end; |
249 end; |
154 |
250 |
155 {$IFDEF GL2} |
251 {$IFDEF GL2} |
156 function CompileShader(shaderFile: string; shaderType: GLenum): GLuint; |
252 function CompileShader(shaderFile: string; shaderType: GLenum): GLuint; |
157 var |
253 var |
300 begin |
396 begin |
301 glDeleteTextures(1, @tex); |
397 glDeleteTextures(1, @tex); |
302 glDeleteRenderbuffersEXT(1, @depth); |
398 glDeleteRenderbuffersEXT(1, @depth); |
303 glDeleteFramebuffersEXT(1, @frame); |
399 glDeleteFramebuffersEXT(1, @frame); |
304 end; |
400 end; |
305 |
401 {$ENDIF} |
306 {$ENDIF} |
402 |
307 procedure RenderSetup(); |
403 procedure RendererCleanup(); |
|
404 begin |
|
405 {$IFNDEF PAS2C} |
|
406 {$IFDEF USE_VIDEO_RECORDING} |
|
407 if defaultFrame <> 0 then |
|
408 DeleteFramebuffer(defaultFrame, depthv, texv); |
|
409 {$ENDIF} |
|
410 {$IFDEF USE_S3D_RENDERING} |
|
411 if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then |
|
412 begin |
|
413 DeleteFramebuffer(framel, depthl, texl); |
|
414 DeleteFramebuffer(framer, depthr, texr); |
|
415 end |
|
416 {$ENDIF} |
|
417 {$ENDIF} |
|
418 end; |
|
419 |
|
420 procedure RendererSetup(); |
308 var AuxBufNum: LongInt = 0; |
421 var AuxBufNum: LongInt = 0; |
309 tmpstr: ansistring; |
422 tmpstr: ansistring; |
310 tmpint: LongInt; |
423 tmpint: LongInt; |
311 tmpn: LongInt; |
424 tmpn: LongInt; |
312 begin |
425 begin |
|
426 {$IFDEF MOBILE} |
|
427 // TODO: this function creates an opengles1.1 context |
|
428 // un-comment below and add proper logic to support opengles2.0 |
|
429 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); |
|
430 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); |
|
431 if SDLGLcontext = nil then |
|
432 SDLGLcontext:= SDL_GL_CreateContext(SDLwindow); |
|
433 SDLTry(SDLGLcontext <> nil, true); |
|
434 SDL_GL_SetSwapInterval(1); |
|
435 {$ENDIF} |
|
436 |
313 // suppress hint/warning |
437 // suppress hint/warning |
314 AuxBufNum:= AuxBufNum; |
438 AuxBufNum:= AuxBufNum; |
315 |
439 |
316 // get the max (h and v) size for textures that the gpu can support |
440 // get the max (h and v) size for textures that the gpu can support |
317 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize); |
441 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize); |
424 if glLoadExtension('GL_EXT_framebuffer_object') then |
548 if glLoadExtension('GL_EXT_framebuffer_object') then |
425 begin |
549 begin |
426 CreateFramebuffer(framel, depthl, texl); |
550 CreateFramebuffer(framel, depthl, texl); |
427 CreateFramebuffer(framer, depthr, texr); |
551 CreateFramebuffer(framer, depthr, texr); |
428 |
552 |
|
553 |
|
554 |
|
555 |
429 // reset |
556 // reset |
430 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame) |
557 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame) |
431 end |
558 end |
432 else |
559 else |
433 cStereoMode:= smNone; |
560 cStereoMode:= smNone; |
434 end; |
561 end; |
|
562 |
|
563 // set up vertex/texture buffers for frame textures |
|
564 texLRDtb[0].X:= 0.0; |
|
565 texLRDtb[0].Y:= 0.0; |
|
566 texLRDtb[1].X:= 1.0; |
|
567 texLRDtb[1].Y:= 0.0; |
|
568 texLRDtb[2].X:= 1.0; |
|
569 texLRDtb[2].Y:= 1.0; |
|
570 texLRDtb[3].X:= 0.0; |
|
571 texLRDtb[3].Y:= 1.0; |
|
572 |
|
573 if cStereoMode = smHorizontal then |
|
574 begin |
|
575 texLvb[0].X:= cScreenWidth / -2; |
|
576 texLvb[0].Y:= cScreenHeight; |
|
577 texLvb[1].X:= 0; |
|
578 texLvb[1].Y:= cScreenHeight; |
|
579 texLvb[2].X:= 0; |
|
580 texLvb[2].Y:= 0; |
|
581 texLvb[3].X:= cScreenWidth / -2; |
|
582 texLvb[3].Y:= 0; |
|
583 |
|
584 texRvb[0].X:= 0; |
|
585 texRvb[0].Y:= cScreenHeight; |
|
586 texRvb[1].X:= cScreenWidth / 2; |
|
587 texRvb[1].Y:= cScreenHeight; |
|
588 texRvb[2].X:= cScreenWidth / 2; |
|
589 texRvb[2].Y:= 0; |
|
590 texRvb[3].X:= 0; |
|
591 texRvb[3].Y:= 0; |
|
592 end |
|
593 else |
|
594 begin |
|
595 texLvb[0].X:= cScreenWidth / -2; |
|
596 texLvb[0].Y:= cScreenHeight / 2; |
|
597 texLvb[1].X:= cScreenWidth / 2; |
|
598 texLvb[1].Y:= cScreenHeight / 2; |
|
599 texLvb[2].X:= cScreenWidth / 2; |
|
600 texLvb[2].Y:= 0; |
|
601 texLvb[3].X:= cScreenWidth / -2; |
|
602 texLvb[3].Y:= 0; |
|
603 |
|
604 texRvb[0].X:= cScreenWidth / -2; |
|
605 texRvb[0].Y:= cScreenHeight; |
|
606 texRvb[1].X:= cScreenWidth / 2; |
|
607 texRvb[1].Y:= cScreenHeight; |
|
608 texRvb[2].X:= cScreenWidth / 2; |
|
609 texRvb[2].Y:= cScreenHeight / 2; |
|
610 texRvb[3].X:= cScreenWidth / -2; |
|
611 texRvb[3].Y:= cScreenHeight / 2; |
|
612 end; |
435 {$ENDIF} |
613 {$ENDIF} |
436 |
614 |
437 // set view port to whole window |
615 // set view port to whole window |
438 glViewport(0, 0, cScreenWidth, cScreenHeight); |
616 glViewport(0, 0, cScreenWidth, cScreenHeight); |
439 |
617 |
1218 //openglPopMatrix; |
1396 //openglPopMatrix; |
1219 EnableTexture(True); |
1397 EnableTexture(True); |
1220 glDisable(GL_LINE_SMOOTH); |
1398 glDisable(GL_LINE_SMOOTH); |
1221 end; |
1399 end; |
1222 |
1400 |
|
1401 procedure DrawCircleFilled(X, Y, Radius: LongInt; r, g, b, a: Byte); |
|
1402 var |
|
1403 i: LongInt; |
|
1404 begin |
|
1405 VertexBuffer[0].X := X; |
|
1406 VertexBuffer[0].Y := Y; |
|
1407 |
|
1408 for i := 1 to 19 do begin |
|
1409 VertexBuffer[i].X := X + Radius*cos(i*pi/9); |
|
1410 VertexBuffer[i].Y := Y + Radius*sin(i*pi/9); |
|
1411 end; |
|
1412 |
|
1413 EnableTexture(False); |
|
1414 Tint(r, g, b, a); |
|
1415 SetVertexPointer(@VertexBuffer[0], 20); |
|
1416 glDrawArrays(GL_TRIANGLE_FAN, 0, 20); |
|
1417 Untint(); |
|
1418 EnableTexture(True); |
|
1419 end; |
1223 |
1420 |
1224 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
1421 procedure DrawHedgehog(X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
1225 const VertexBuffer: array [0..3] of TVertex2f = ( |
1422 const VertexBuffer: array [0..3] of TVertex2f = ( |
1226 (X: -16; Y: -16), |
1423 (X: -16; Y: -16), |
1227 (X: 16; Y: -16), |
1424 (X: 16; Y: -16), |
1710 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD) |
1909 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD) |
1711 else |
1910 else |
1712 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
1911 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
1713 end; |
1912 end; |
1714 |
1913 |
|
1914 procedure ChangeDepth(rm: TRenderMode; d: GLfloat); |
|
1915 var tmp: LongInt; |
|
1916 begin |
|
1917 {$IFNDEF USE_S3D_RENDERING} |
|
1918 rm:= rm; d:= d; tmp:= tmp; // avoid hint |
|
1919 {$ELSE} |
|
1920 d:= d / 5; |
|
1921 if rm = rmDefault then |
|
1922 exit |
|
1923 else if rm = rmLeftEye then |
|
1924 d:= -d; |
|
1925 cStereoDepth:= cStereoDepth + d; |
|
1926 openglTranslProjMatrix(d, 0, 0); |
|
1927 tmp:= round(d / cScaleFactor * cScreenWidth); |
|
1928 ViewLeftX := ViewLeftX - tmp; |
|
1929 ViewRightX:= ViewRightX - tmp; |
|
1930 {$ENDIF} |
|
1931 end; |
|
1932 |
|
1933 procedure ResetDepth(rm: TRenderMode); |
|
1934 var tmp: LongInt; |
|
1935 begin |
|
1936 {$IFNDEF USE_S3D_RENDERING} |
|
1937 rm:= rm; tmp:= tmp; // avoid hint |
|
1938 {$ELSE} |
|
1939 if rm = rmDefault then |
|
1940 exit; |
|
1941 openglTranslProjMatrix(-cStereoDepth, 0, 0); |
|
1942 tmp:= round(cStereoDepth / cScaleFactor * cScreenWidth); |
|
1943 ViewLeftX := ViewLeftX + tmp; |
|
1944 ViewRightX:= ViewRightX + tmp; |
|
1945 cStereoDepth:= 0; |
|
1946 {$ENDIF} |
|
1947 end; |
|
1948 |
|
1949 |
1715 procedure initModule; |
1950 procedure initModule; |
1716 begin |
1951 begin |
1717 LastTint:= cWhiteColor + 1; |
1952 LastTint:= cWhiteColor + 1; |
1718 LastColorPointer := nil; |
1953 LastColorPointer := nil; |
1719 LastTexCoordPointer := nil; |
1954 LastTexCoordPointer := nil; |