57 procedure DrawScreenWidget (widget: POnScreenWidget); |
57 procedure DrawScreenWidget (widget: POnScreenWidget); |
58 procedure DrawWater (Alpha: byte; OffsetY, OffsetX: LongInt); |
58 procedure DrawWater (Alpha: byte; OffsetY, OffsetX: LongInt); |
59 procedure DrawWaves (Dir, dX, dY, oX: LongInt; tnt: Byte); |
59 procedure DrawWaves (Dir, dX, dY, oX: LongInt; tnt: Byte); |
60 |
60 |
61 procedure RenderClear (); |
61 procedure RenderClear (); |
62 procedure RenderSetClearColor (r, g, b, a: real); |
62 procedure RenderClear (mode: TRenderMode); |
|
63 procedure RenderSetClearColor (r, g, b, a: real); |
63 procedure Tint (r, g, b, a: Byte); inline; |
64 procedure Tint (r, g, b, a: Byte); inline; |
64 procedure Tint (c: Longword); inline; |
65 procedure Tint (c: Longword); inline; |
65 procedure untint(); inline; |
66 procedure untint(); inline; |
66 procedure setTintAdd (f: boolean); inline; |
67 procedure setTintAdd (f: boolean); inline; |
67 |
68 |
|
69 // call this to finish the rendering of current frame |
|
70 procedure FinishRender(); |
|
71 |
68 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
72 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
69 |
73 |
70 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen |
74 // 0 => not offscreen, <0 => left/top of screen >0 => right/below of screen |
71 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline; |
75 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline; |
72 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline; |
76 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline; |
73 |
77 |
74 procedure SetScale(f: GLfloat); |
78 procedure SetScale(f: GLfloat); |
75 procedure UpdateViewLimits(); |
79 procedure UpdateViewLimits(); |
76 |
80 |
77 procedure RenderSetup(); |
81 procedure RendererSetup(); |
|
82 procedure RendererCleanup(); |
78 |
83 |
79 // TODO everything below this should not need a public interface |
84 // TODO everything below this should not need a public interface |
80 |
85 |
81 procedure CreateFramebuffer(var frame, depth, tex: GLuint); |
86 procedure CreateFramebuffer(var frame, depth, tex: GLuint); |
82 procedure DeleteFramebuffer(var frame, depth, tex: GLuint); |
87 procedure DeleteFramebuffer(var frame, depth, tex: GLuint); |
122 LastColorPointer , LastTexCoordPointer , LastVertexPointer : Pointer; |
127 LastColorPointer , LastTexCoordPointer , LastVertexPointer : Pointer; |
123 {$IFDEF GL2} |
128 {$IFDEF GL2} |
124 LastColorPointerN, LastTexCoordPointerN, LastVertexPointerN: Integer; |
129 LastColorPointerN, LastTexCoordPointerN, LastVertexPointerN: Integer; |
125 {$ENDIF} |
130 {$ENDIF} |
126 |
131 |
|
132 {$IFDEF USE_S3D_RENDERING} |
|
133 // texture/vertex buffers for left/right/default eye modes |
|
134 texLRDtb, texLvb, texRvb: array [0..3] of TVertex2f; |
|
135 {$ENDIF} |
|
136 |
127 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
137 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
128 begin |
138 begin |
129 isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0); |
139 isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0); |
130 end; |
140 end; |
131 |
141 |
146 procedure RenderClear(); |
156 procedure RenderClear(); |
147 begin |
157 begin |
148 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); |
158 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); |
149 end; |
159 end; |
150 |
160 |
|
161 {$IFDEF USE_S3D_RENDERING} |
|
162 procedure RenderClear(mode: TRenderMode); |
|
163 var frame: GLuint; |
|
164 begin |
|
165 if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then |
|
166 begin |
|
167 case mode of |
|
168 rmLeftEye: frame:= frameL; |
|
169 rmRightEye: frame:= frameR; |
|
170 else |
|
171 frame:= defaultFrame; |
|
172 end; |
|
173 |
|
174 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame); |
|
175 |
|
176 RenderClear(); |
|
177 end |
|
178 else |
|
179 begin |
|
180 // draw left eye in red channel only |
|
181 if mode = rmLeftEye then |
|
182 begin |
|
183 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
|
184 RenderClear(); |
|
185 if cStereoMode = smGreenRed then |
|
186 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE) |
|
187 else if cStereoMode = smBlueRed then |
|
188 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE) |
|
189 else if cStereoMode = smCyanRed then |
|
190 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE) |
|
191 else |
|
192 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); |
|
193 end |
|
194 else |
|
195 begin |
|
196 // draw right eye in selected channel(s) only |
|
197 if cStereoMode = smRedGreen then |
|
198 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE) |
|
199 else if cStereoMode = smRedBlue then |
|
200 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE) |
|
201 else if cStereoMode = smRedCyan then |
|
202 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE) |
|
203 else |
|
204 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); |
|
205 end; |
|
206 end; |
|
207 end; |
|
208 {$ENDIF} |
|
209 |
151 procedure RenderSetClearColor(r, g, b, a: real); |
210 procedure RenderSetClearColor(r, g, b, a: real); |
152 begin |
211 begin |
153 glClearColor(r, g, b, a); |
212 glClearColor(r, g, b, a); |
|
213 end; |
|
214 |
|
215 procedure FinishRender(); |
|
216 begin |
|
217 |
|
218 {$IFDEF USE_S3D_RENDERING} |
|
219 if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then |
|
220 begin |
|
221 RenderClear(rmDefault); |
|
222 |
|
223 SetScale(cDefaultZoomLevel); |
|
224 |
|
225 |
|
226 // same for all |
|
227 SetTexCoordPointer(@texLRDtb, Length(texLRDtb)); |
|
228 |
|
229 |
|
230 // draw left frame |
|
231 glBindTexture(GL_TEXTURE_2D, texl); |
|
232 SetVertexPointer(@texLvb, Length(texLvb)); |
|
233 //UpdateModelviewProjection; |
|
234 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(texLvb)); |
|
235 |
|
236 // draw right frame |
|
237 glBindTexture(GL_TEXTURE_2D, texl); |
|
238 SetVertexPointer(@texRvb, Length(texRvb)); |
|
239 //UpdateModelviewProjection; |
|
240 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(texRvb)); |
|
241 |
|
242 SetScale(zoom); |
|
243 end; |
|
244 {$ENDIF} |
154 end; |
245 end; |
155 |
246 |
156 {$IFDEF GL2} |
247 {$IFDEF GL2} |
157 function CompileShader(shaderFile: string; shaderType: GLenum): GLuint; |
248 function CompileShader(shaderFile: string; shaderType: GLenum): GLuint; |
158 var |
249 var |
301 begin |
392 begin |
302 glDeleteTextures(1, @tex); |
393 glDeleteTextures(1, @tex); |
303 glDeleteRenderbuffersEXT(1, @depth); |
394 glDeleteRenderbuffersEXT(1, @depth); |
304 glDeleteFramebuffersEXT(1, @frame); |
395 glDeleteFramebuffersEXT(1, @frame); |
305 end; |
396 end; |
306 |
397 {$ENDIF} |
307 {$ENDIF} |
398 |
308 procedure RenderSetup(); |
399 procedure RendererCleanup(); |
|
400 begin |
|
401 {$IFNDEF PAS2C} |
|
402 {$IFDEF USE_VIDEO_RECORDING} |
|
403 if defaultFrame <> 0 then |
|
404 DeleteFramebuffer(defaultFrame, depthv, texv); |
|
405 {$ENDIF} |
|
406 {$IFDEF USE_S3D_RENDERING} |
|
407 if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) then |
|
408 begin |
|
409 DeleteFramebuffer(framel, depthl, texl); |
|
410 DeleteFramebuffer(framer, depthr, texr); |
|
411 end |
|
412 {$ENDIF} |
|
413 {$ENDIF} |
|
414 end; |
|
415 |
|
416 procedure RendererSetup(); |
309 var AuxBufNum: LongInt = 0; |
417 var AuxBufNum: LongInt = 0; |
310 tmpstr: ansistring; |
418 tmpstr: ansistring; |
311 tmpint: LongInt; |
419 tmpint: LongInt; |
312 tmpn: LongInt; |
420 tmpn: LongInt; |
313 begin |
421 begin |
|
422 {$IFDEF MOBILE} |
|
423 // TODO: this function creates an opengles1.1 context |
|
424 // un-comment below and add proper logic to support opengles2.0 |
|
425 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); |
|
426 //SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); |
|
427 if SDLGLcontext = nil then |
|
428 SDLGLcontext:= SDL_GL_CreateContext(SDLwindow); |
|
429 SDLTry(SDLGLcontext <> nil, true); |
|
430 SDL_GL_SetSwapInterval(1); |
|
431 {$ENDIF} |
|
432 |
314 // suppress hint/warning |
433 // suppress hint/warning |
315 AuxBufNum:= AuxBufNum; |
434 AuxBufNum:= AuxBufNum; |
316 |
435 |
317 // get the max (h and v) size for textures that the gpu can support |
436 // get the max (h and v) size for textures that the gpu can support |
318 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize); |
437 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize); |
425 if glLoadExtension('GL_EXT_framebuffer_object') then |
544 if glLoadExtension('GL_EXT_framebuffer_object') then |
426 begin |
545 begin |
427 CreateFramebuffer(framel, depthl, texl); |
546 CreateFramebuffer(framel, depthl, texl); |
428 CreateFramebuffer(framer, depthr, texr); |
547 CreateFramebuffer(framer, depthr, texr); |
429 |
548 |
|
549 |
|
550 |
|
551 |
430 // reset |
552 // reset |
431 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame) |
553 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame) |
432 end |
554 end |
433 else |
555 else |
434 cStereoMode:= smNone; |
556 cStereoMode:= smNone; |
435 end; |
557 end; |
|
558 |
|
559 // set up vertex/texture buffers for frame textures |
|
560 texLRDtb[0].X:= 0.0; |
|
561 texLRDtb[0].Y:= 0.0; |
|
562 texLRDtb[1].X:= 1.0; |
|
563 texLRDtb[1].Y:= 0.0; |
|
564 texLRDtb[2].X:= 1.0; |
|
565 texLRDtb[2].Y:= 1.0; |
|
566 texLRDtb[3].X:= 0.0; |
|
567 texLRDtb[3].Y:= 1.0; |
|
568 |
|
569 if cStereoMode = smHorizontal then |
|
570 begin |
|
571 texLvb[0].X:= cScreenWidth / -2; |
|
572 texLvb[0].Y:= cScreenHeight; |
|
573 texLvb[1].X:= 0; |
|
574 texLvb[1].Y:= cScreenHeight; |
|
575 texLvb[2].X:= 0; |
|
576 texLvb[2].Y:= 0; |
|
577 texLvb[3].X:= cScreenWidth / -2; |
|
578 texLvb[3].Y:= 0; |
|
579 |
|
580 texRvb[0].X:= 0; |
|
581 texRvb[0].Y:= cScreenHeight; |
|
582 texRvb[1].X:= cScreenWidth / 2; |
|
583 texRvb[1].Y:= cScreenHeight; |
|
584 texRvb[2].X:= cScreenWidth / 2; |
|
585 texRvb[2].Y:= 0; |
|
586 texRvb[3].X:= 0; |
|
587 texRvb[3].Y:= 0; |
|
588 end |
|
589 else |
|
590 begin |
|
591 texLvb[0].X:= cScreenWidth / -2; |
|
592 texLvb[0].Y:= cScreenHeight / 2; |
|
593 texLvb[1].X:= cScreenWidth / 2; |
|
594 texLvb[1].Y:= cScreenHeight / 2; |
|
595 texLvb[2].X:= cScreenWidth / 2; |
|
596 texLvb[2].Y:= 0; |
|
597 texLvb[3].X:= cScreenWidth / -2; |
|
598 texLvb[3].Y:= 0; |
|
599 |
|
600 texRvb[0].X:= cScreenWidth / -2; |
|
601 texRvb[0].Y:= cScreenHeight; |
|
602 texRvb[1].X:= cScreenWidth / 2; |
|
603 texRvb[1].Y:= cScreenHeight; |
|
604 texRvb[2].X:= cScreenWidth / 2; |
|
605 texRvb[2].Y:= cScreenHeight / 2; |
|
606 texRvb[3].X:= cScreenWidth / -2; |
|
607 texRvb[3].Y:= cScreenHeight / 2; |
|
608 end; |
436 {$ENDIF} |
609 {$ENDIF} |
437 |
610 |
438 // set view port to whole window |
611 // set view port to whole window |
439 glViewport(0, 0, cScreenWidth, cScreenHeight); |
612 glViewport(0, 0, cScreenWidth, cScreenHeight); |
440 |
613 |