changeset 10304 | 7e40820b7ed6 |
parent 10302 | ea0b0e2efd95 |
child 10306 | 4fca8bcfaff0 |
10303:f726e36c3e24 | 10304:7e40820b7ed6 |
---|---|
21 |
21 |
22 unit uRender; |
22 unit uRender; |
23 |
23 |
24 interface |
24 interface |
25 |
25 |
26 uses SDLh, uTypes, GLunit, uConsts{$IFDEF GL2}, uMatrix{$ENDIF}; |
26 uses SDLh, uTypes, GLunit; |
27 |
|
28 procedure initModule; |
|
29 procedure freeModule; |
|
27 |
30 |
28 procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); |
31 procedure DrawSprite (Sprite: TSprite; X, Y, Frame: LongInt); |
29 procedure DrawSprite (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); |
32 procedure DrawSprite (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt); |
30 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); inline; |
31 procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
34 procedure DrawSpriteClipped (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt); |
46 procedure DrawCircle (X, Y, Radius, Width: LongInt); |
49 procedure DrawCircle (X, Y, Radius, Width: LongInt); |
47 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); |
48 |
51 |
49 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; |
52 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; |
50 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
53 procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); |
51 procedure DrawFillRect (r: TSDL_Rect); |
54 procedure DrawRect (rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean); |
52 procedure DrawHedgehog (X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
55 procedure DrawHedgehog (X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); |
53 procedure DrawScreenWidget (widget: POnScreenWidget); |
56 procedure DrawScreenWidget (widget: POnScreenWidget); |
54 procedure DrawWaterBody (pVertexBuffer: Pointer); |
57 procedure DrawWaterBody (pVertexBuffer: Pointer); |
55 |
58 |
59 procedure RenderClear (); |
|
60 procedure RenderSetClearColor (r, g, b, a: real); |
|
56 procedure Tint (r, g, b, a: Byte); inline; |
61 procedure Tint (r, g, b, a: Byte); inline; |
57 procedure Tint (c: Longword); inline; |
62 procedure Tint (c: Longword); inline; |
58 procedure untint(); inline; |
63 procedure untint(); inline; |
59 procedure setTintAdd (f: boolean); inline; |
64 procedure setTintAdd (f: boolean); inline; |
60 |
65 |
64 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline; |
69 function isDxAreaOffscreen(X, Width: LongInt): LongInt; inline; |
65 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline; |
70 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline; |
66 |
71 |
67 procedure SetScale(f: GLfloat); |
72 procedure SetScale(f: GLfloat); |
68 procedure UpdateViewLimits(); |
73 procedure UpdateViewLimits(); |
74 |
|
75 procedure RenderSetup(); |
|
76 |
|
77 // TODO everything below this should not need a public interface |
|
69 |
78 |
70 procedure EnableTexture(enable:Boolean); |
79 procedure EnableTexture(enable:Boolean); |
71 |
80 |
72 procedure SetTexCoordPointer(p: Pointer;n: Integer); |
81 procedure SetTexCoordPointer(p: Pointer;n: Integer); |
73 procedure SetVertexPointer(p: Pointer;n: Integer); |
82 procedure SetVertexPointer(p: Pointer;n: Integer); |
84 procedure openglRotatef (RotX, RotY, RotZ: GLfloat; dir: LongInt); inline; |
93 procedure openglRotatef (RotX, RotY, RotZ: GLfloat; dir: LongInt); inline; |
85 procedure openglTint (r, g, b, a: Byte); inline; |
94 procedure openglTint (r, g, b, a: Byte); inline; |
86 |
95 |
87 |
96 |
88 implementation |
97 implementation |
89 uses uVariables; |
98 uses {$IFNDEF PAS2C} StrUtils, {$ENDIF}SysUtils, uVariables, uUtils, uConsts |
99 {$IFDEF GL2}, uMatrix, uConsole{$ENDIF}; |
|
90 |
100 |
91 {$IFDEF USE_TOUCH_INTERFACE} |
101 {$IFDEF USE_TOUCH_INTERFACE} |
92 const |
102 const |
93 FADE_ANIM_TIME = 500; |
103 FADE_ANIM_TIME = 500; |
94 MOVE_ANIM_TIME = 500; |
104 MOVE_ANIM_TIME = 500; |
95 {$ENDIF} |
105 {$ENDIF} |
96 |
106 |
107 {$IFDEF GL2} |
|
108 var |
|
109 shaderMain: GLuint; |
|
110 shaderWater: GLuint; |
|
111 {$ENDIF} |
|
112 |
|
97 var LastTint: LongWord = 0; |
113 var LastTint: LongWord = 0; |
98 |
114 |
99 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
115 function isAreaOffscreen(X, Y, Width, Height: LongInt): boolean; inline; |
100 begin |
116 begin |
101 isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0); |
117 isAreaOffscreen:= (isDxAreaOffscreen(X, Width) <> 0) or (isDyAreaOffscreen(Y, Height) <> 0); |
111 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline; |
127 function isDyAreaOffscreen(Y, Height: LongInt): LongInt; inline; |
112 begin |
128 begin |
113 if Y > ViewBottomY then exit(1); |
129 if Y > ViewBottomY then exit(1); |
114 if Y + Height < ViewTopY then exit(-1); |
130 if Y + Height < ViewTopY then exit(-1); |
115 isDyAreaOffscreen:= 0; |
131 isDyAreaOffscreen:= 0; |
132 end; |
|
133 |
|
134 procedure RenderClear(); |
|
135 begin |
|
136 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); |
|
137 end; |
|
138 |
|
139 procedure RenderSetClearColor(r, g, b, a: real); |
|
140 begin |
|
141 glClearColor(r, g, b, a); |
|
142 end; |
|
143 |
|
144 {$IFDEF GL2} |
|
145 function CompileShader(shaderFile: string; shaderType: GLenum): GLuint; |
|
146 var |
|
147 shader: GLuint; |
|
148 f: Textfile; |
|
149 source, line: AnsiString; |
|
150 sourceA: Pchar; |
|
151 lengthA: GLint; |
|
152 compileResult: GLint; |
|
153 logLength: GLint; |
|
154 log: PChar; |
|
155 begin |
|
156 Assign(f, PathPrefix + cPathz[ptShaders] + '/' + shaderFile); |
|
157 filemode:= 0; // readonly |
|
158 Reset(f); |
|
159 if IOResult <> 0 then |
|
160 begin |
|
161 AddFileLog('Unable to load ' + shaderFile); |
|
162 halt(-1); |
|
163 end; |
|
164 |
|
165 source:=''; |
|
166 while not eof(f) do |
|
167 begin |
|
168 ReadLn(f, line); |
|
169 source:= source + line + #10; |
|
170 end; |
|
171 |
|
172 Close(f); |
|
173 |
|
174 WriteLnToConsole('Compiling shader: ' + PathPrefix + cPathz[ptShaders] + '/' + shaderFile); |
|
175 |
|
176 sourceA:=PChar(source); |
|
177 lengthA:=Length(source); |
|
178 |
|
179 shader:=glCreateShader(shaderType); |
|
180 glShaderSource(shader, 1, @sourceA, @lengthA); |
|
181 glCompileShader(shader); |
|
182 glGetShaderiv(shader, GL_COMPILE_STATUS, @compileResult); |
|
183 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, @logLength); |
|
184 |
|
185 if logLength > 1 then |
|
186 begin |
|
187 log := GetMem(logLength); |
|
188 glGetShaderInfoLog(shader, logLength, nil, log); |
|
189 WriteLnToConsole('========== Compiler log =========='); |
|
190 WriteLnToConsole(shortstring(log)); |
|
191 WriteLnToConsole('==================================='); |
|
192 FreeMem(log, logLength); |
|
193 end; |
|
194 |
|
195 if compileResult <> GL_TRUE then |
|
196 begin |
|
197 WriteLnToConsole('Shader compilation failed, halting'); |
|
198 halt(-1); |
|
199 end; |
|
200 |
|
201 CompileShader:= shader; |
|
202 end; |
|
203 |
|
204 function CompileProgram(shaderName: string): GLuint; |
|
205 var |
|
206 program_: GLuint; |
|
207 vs, fs: GLuint; |
|
208 linkResult: GLint; |
|
209 logLength: GLint; |
|
210 log: PChar; |
|
211 begin |
|
212 program_:= glCreateProgram(); |
|
213 vs:= CompileShader(shaderName + '.vs', GL_VERTEX_SHADER); |
|
214 fs:= CompileShader(shaderName + '.fs', GL_FRAGMENT_SHADER); |
|
215 glAttachShader(program_, vs); |
|
216 glAttachShader(program_, fs); |
|
217 |
|
218 glBindAttribLocation(program_, aVertex, PChar('vertex')); |
|
219 glBindAttribLocation(program_, aTexCoord, PChar('texcoord')); |
|
220 glBindAttribLocation(program_, aColor, PChar('color')); |
|
221 |
|
222 glLinkProgram(program_); |
|
223 glDeleteShader(vs); |
|
224 glDeleteShader(fs); |
|
225 |
|
226 glGetProgramiv(program_, GL_LINK_STATUS, @linkResult); |
|
227 glGetProgramiv(program_, GL_INFO_LOG_LENGTH, @logLength); |
|
228 |
|
229 if logLength > 1 then |
|
230 begin |
|
231 log := GetMem(logLength); |
|
232 glGetProgramInfoLog(program_, logLength, nil, log); |
|
233 WriteLnToConsole('========== Compiler log =========='); |
|
234 WriteLnToConsole(shortstring(log)); |
|
235 WriteLnToConsole('==================================='); |
|
236 FreeMem(log, logLength); |
|
237 end; |
|
238 |
|
239 if linkResult <> GL_TRUE then |
|
240 begin |
|
241 WriteLnToConsole('Linking program failed, halting'); |
|
242 halt(-1); |
|
243 end; |
|
244 |
|
245 CompileProgram:= program_; |
|
246 end; |
|
247 {$ENDIF} |
|
248 |
|
249 procedure RenderSetup(); |
|
250 var AuxBufNum: LongInt = 0; |
|
251 tmpstr: ansistring; |
|
252 tmpint: LongInt; |
|
253 tmpn: LongInt; |
|
254 begin |
|
255 // suppress hint/warning |
|
256 AuxBufNum:= AuxBufNum; |
|
257 |
|
258 // get the max (h and v) size for textures that the gpu can support |
|
259 glGetIntegerv(GL_MAX_TEXTURE_SIZE, @MaxTextureSize); |
|
260 if MaxTextureSize <= 0 then |
|
261 begin |
|
262 MaxTextureSize:= 1024; |
|
263 AddFileLog('OpenGL Warning - driver didn''t provide any valid max texture size; assuming 1024'); |
|
264 end |
|
265 else if (MaxTextureSize < 1024) and (MaxTextureSize >= 512) then |
|
266 begin |
|
267 cReducedQuality := cReducedQuality or rqNoBackground; |
|
268 AddFileLog('Texture size too small for backgrounds, disabling.'); |
|
269 end; |
|
270 // everyone loves debugging |
|
271 // find out which gpu we are using (for extension compatibility maybe?) |
|
272 AddFileLog('OpenGL-- Renderer: ' + shortstring(pchar(glGetString(GL_RENDERER)))); |
|
273 AddFileLog(' |----- Vendor: ' + shortstring(pchar(glGetString(GL_VENDOR)))); |
|
274 AddFileLog(' |----- Version: ' + shortstring(pchar(glGetString(GL_VERSION)))); |
|
275 AddFileLog(' |----- Texture Size: ' + inttostr(MaxTextureSize)); |
|
276 {$IFDEF USE_VIDEO_RECORDING} |
|
277 glGetIntegerv(GL_AUX_BUFFERS, @AuxBufNum); |
|
278 AddFileLog(' |----- Number of auxiliary buffers: ' + inttostr(AuxBufNum)); |
|
279 {$ENDIF} |
|
280 {$IFNDEF PAS2C} |
|
281 AddFileLog(' \----- Extensions: '); |
|
282 |
|
283 // fetch extentions and store them in string |
|
284 tmpstr := StrPas(PChar(glGetString(GL_EXTENSIONS))); |
|
285 tmpn := WordCount(tmpstr, [' ']); |
|
286 tmpint := 1; |
|
287 |
|
288 repeat |
|
289 begin |
|
290 // print up to 3 extentions per row |
|
291 // ExtractWord will return empty string if index out of range |
|
292 AddFileLog(TrimRight( |
|
293 ExtractWord(tmpint, tmpstr, [' ']) + ' ' + |
|
294 ExtractWord(tmpint+1, tmpstr, [' ']) + ' ' + |
|
295 ExtractWord(tmpint+2, tmpstr, [' ']) |
|
296 )); |
|
297 tmpint := tmpint + 3; |
|
298 end; |
|
299 until (tmpint > tmpn); |
|
300 {$ENDIF} |
|
301 AddFileLog(''); |
|
302 |
|
303 defaultFrame:= 0; |
|
304 |
|
305 {$IFDEF USE_VIDEO_RECORDING} |
|
306 if GameType = gmtRecord then |
|
307 begin |
|
308 if glLoadExtension('GL_EXT_framebuffer_object') then |
|
309 begin |
|
310 CreateFramebuffer(defaultFrame, depthv, texv); |
|
311 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame); |
|
312 AddFileLog('Using framebuffer for video recording.'); |
|
313 end |
|
314 else if AuxBufNum > 0 then |
|
315 begin |
|
316 glDrawBuffer(GL_AUX0); |
|
317 glReadBuffer(GL_AUX0); |
|
318 AddFileLog('Using auxiliary buffer for video recording.'); |
|
319 end |
|
320 else |
|
321 begin |
|
322 glDrawBuffer(GL_BACK); |
|
323 glReadBuffer(GL_BACK); |
|
324 AddFileLog('Warning: off-screen rendering is not supported; using back buffer but it may not work.'); |
|
325 end; |
|
326 end; |
|
327 {$ENDIF} |
|
328 |
|
329 {$IFDEF GL2} |
|
330 |
|
331 {$IFDEF PAS2C} |
|
332 err := glewInit(); |
|
333 if err <> GLEW_OK then |
|
334 begin |
|
335 WriteLnToConsole('Failed to initialize GLEW.'); |
|
336 halt; |
|
337 end; |
|
338 {$ENDIF} |
|
339 |
|
340 {$IFNDEF PAS2C} |
|
341 if not Load_GL_VERSION_2_0 then |
|
342 halt; |
|
343 {$ENDIF} |
|
344 |
|
345 shaderWater:= CompileProgram('water'); |
|
346 glUseProgram(shaderWater); |
|
347 glUniform1i(glGetUniformLocation(shaderWater, pchar('tex0')), 0); |
|
348 uWaterMVPLocation:= glGetUniformLocation(shaderWater, pchar('mvp')); |
|
349 |
|
350 shaderMain:= CompileProgram('default'); |
|
351 glUseProgram(shaderMain); |
|
352 glUniform1i(glGetUniformLocation(shaderMain, pchar('tex0')), 0); |
|
353 uMainMVPLocation:= glGetUniformLocation(shaderMain, pchar('mvp')); |
|
354 uMainTintLocation:= glGetUniformLocation(shaderMain, pchar('tint')); |
|
355 |
|
356 uCurrentMVPLocation:= uMainMVPLocation; |
|
357 |
|
358 Tint(255, 255, 255, 255); |
|
359 UpdateModelviewProjection; |
|
360 {$ENDIF} |
|
361 |
|
362 {$IFNDEF USE_S3D_RENDERING} |
|
363 if (cStereoMode = smHorizontal) or (cStereoMode = smVertical) or (cStereoMode = smAFR) then |
|
364 begin |
|
365 // prepare left and right frame buffers and associated textures |
|
366 if glLoadExtension('GL_EXT_framebuffer_object') then |
|
367 begin |
|
368 CreateFramebuffer(framel, depthl, texl); |
|
369 CreateFramebuffer(framer, depthr, texr); |
|
370 |
|
371 // reset |
|
372 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, defaultFrame) |
|
373 end |
|
374 else |
|
375 cStereoMode:= smNone; |
|
376 end; |
|
377 {$ENDIF} |
|
378 |
|
379 // set view port to whole window |
|
380 glViewport(0, 0, cScreenWidth, cScreenHeight); |
|
381 |
|
382 {$IFDEF GL2} |
|
383 uMatrix.initModule; |
|
384 hglMatrixMode(MATRIX_MODELVIEW); |
|
385 // prepare default translation/scaling |
|
386 hglLoadIdentity(); |
|
387 hglScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0); |
|
388 hglTranslatef(0, -cScreenHeight / 2, 0); |
|
389 |
|
390 EnableTexture(True); |
|
391 |
|
392 glEnableVertexAttribArray(aVertex); |
|
393 glEnableVertexAttribArray(aTexCoord); |
|
394 glGenBuffers(1, @vBuffer); |
|
395 glGenBuffers(1, @tBuffer); |
|
396 glGenBuffers(1, @cBuffer); |
|
397 {$ELSE} |
|
398 glMatrixMode(GL_MODELVIEW); |
|
399 // prepare default translation/scaling |
|
400 glLoadIdentity(); |
|
401 glScalef(2.0 / cScreenWidth, -2.0 / cScreenHeight, 1.0); |
|
402 glTranslatef(0, -cScreenHeight / 2, 0); |
|
403 |
|
404 // disable/lower perspective correction (will not need it anyway) |
|
405 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); |
|
406 // disable dithering |
|
407 glDisable(GL_DITHER); |
|
408 // enable common states by default as they save a lot |
|
409 glEnable(GL_TEXTURE_2D); |
|
410 glEnableClientState(GL_VERTEX_ARRAY); |
|
411 glEnableClientState(GL_TEXTURE_COORD_ARRAY); |
|
412 {$ENDIF} |
|
413 |
|
414 // enable alpha blending |
|
415 glEnable(GL_BLEND); |
|
416 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
|
417 // disable/lower perspective correction (will not need it anyway) |
|
116 end; |
418 end; |
117 |
419 |
118 procedure openglLoadIdentity(); inline; |
420 procedure openglLoadIdentity(); inline; |
119 begin |
421 begin |
120 {$IFDEF GL2} |
422 {$IFDEF GL2} |
283 ViewRightX:= round(tmp); // ceil could make more sense |
585 ViewRightX:= round(tmp); // ceil could make more sense |
284 ViewLeftX:= round(-tmp); // floor could make more sense |
586 ViewLeftX:= round(-tmp); // floor could make more sense |
285 tmp:= cScreenHeight / cScaleFactor; |
587 tmp:= cScreenHeight / cScaleFactor; |
286 ViewBottomY:= round(tmp) + cScreenHeight div 2; // ceil could make more sense |
588 ViewBottomY:= round(tmp) + cScreenHeight div 2; // ceil could make more sense |
287 ViewTopY:= round(-tmp) + cScreenHeight div 2; // floor could make more sense |
589 ViewTopY:= round(-tmp) + cScreenHeight div 2; // floor could make more sense |
590 |
|
591 // visual debugging fun :D |
|
592 if cViewLimitsDebug then |
|
593 begin |
|
594 // some margin on each side |
|
595 tmp:= min(cScreenWidth, cScreenHeight) div 2 / cScaleFactor; |
|
596 ViewLeftX := ViewLeftX + trunc(tmp); |
|
597 ViewRightX := ViewRightX - trunc(tmp); |
|
598 ViewBottomY:= ViewBottomY - trunc(tmp); |
|
599 ViewTopY := ViewTopY + trunc(tmp); |
|
600 end; |
|
601 |
|
602 ViewWidth := ViewRightX - ViewLeftX + 1; |
|
603 ViewHeight:= ViewBottomY - ViewTopY + 1; |
|
288 end; |
604 end; |
289 |
605 |
290 procedure SetScale(f: GLfloat); |
606 procedure SetScale(f: GLfloat); |
291 begin |
607 begin |
292 // leave immediately if scale factor did not change |
608 // leave immediately if scale factor did not change |
293 if f = cScaleFactor then |
609 if f = cScaleFactor then |
294 exit; |
610 exit; |
295 |
611 |
296 // for going back to default scaling just pop matrix |
612 // for going back to default scaling just pop matrix |
297 if f = cDefaultZoomLevel then |
613 if f = cDefaultZoomLevel then |
301 else |
617 else |
302 begin |
618 begin |
303 openglPushMatrix; // save default scaling in matrix |
619 openglPushMatrix; // save default scaling in matrix |
304 openglLoadIdentity(); |
620 openglLoadIdentity(); |
305 openglScalef(f / cScreenWidth, -f / cScreenHeight, 1.0); |
621 openglScalef(f / cScreenWidth, -f / cScreenHeight, 1.0); |
306 openglTranslatef(0, -cScreenHeight / 2, 0); |
622 openglTranslatef(0, -cScreenHeight div 2, 0); |
307 end; |
623 end; |
308 |
624 |
309 cScaleFactor:= f; |
625 cScaleFactor:= f; |
310 updateViewLimits(); |
626 updateViewLimits(); |
311 |
627 |
335 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
651 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
336 begin |
652 begin |
337 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then |
653 if (SourceTexture^.h = 0) or (SourceTexture^.w = 0) then |
338 exit; |
654 exit; |
339 |
655 |
656 {if isDxAreaOffscreen(X, W) <> 0 then |
|
657 exit; |
|
658 if isDyAreaOffscreen(Y, H) <> 0 then |
|
659 exit;} |
|
660 |
|
340 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
661 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
341 if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then |
662 {if (abs(X) > W) and ((abs(X + W / 2) - W / 2) > cScreenWidth / cScaleFactor) then |
342 exit; |
663 exit; |
343 if (abs(Y) > H) and ((abs(Y + H / 2 - (0.5 * cScreenHeight)) - H / 2) > cScreenHeight / cScaleFactor) then |
664 if (abs(Y) > H) and ((abs(Y + H / 2 - (0.5 * cScreenHeight)) - H / 2) > cScreenHeight / cScaleFactor) then |
344 exit; |
665 exit;} |
345 |
666 |
346 rr.x:= X; |
667 rr.x:= X; |
347 rr.y:= Y; |
668 rr.y:= Y; |
348 rr.w:= W; |
669 rr.w:= W; |
349 rr.h:= H; |
670 rr.h:= H; |
355 |
676 |
356 glBindTexture(GL_TEXTURE_2D, SourceTexture^.id); |
677 glBindTexture(GL_TEXTURE_2D, SourceTexture^.id); |
357 |
678 |
358 if Dir < 0 then |
679 if Dir < 0 then |
359 begin |
680 begin |
360 VertexBuffer[0].X:= X + rr.w/2; |
681 VertexBuffer[0].X:= X + rr.w div 2; |
361 VertexBuffer[0].Y:= Y; |
682 VertexBuffer[0].Y:= Y; |
362 VertexBuffer[1].X:= X - rr.w/2; |
683 VertexBuffer[1].X:= X - rr.w div 2; |
363 VertexBuffer[1].Y:= Y; |
684 VertexBuffer[1].Y:= Y; |
364 VertexBuffer[2].X:= X - rr.w/2; |
685 VertexBuffer[2].X:= X - rr.w div 2; |
365 VertexBuffer[2].Y:= rr.h + Y; |
686 VertexBuffer[2].Y:= rr.h + Y; |
366 VertexBuffer[3].X:= X + rr.w/2; |
687 VertexBuffer[3].X:= X + rr.w div 2; |
367 VertexBuffer[3].Y:= rr.h + Y; |
688 VertexBuffer[3].Y:= rr.h + Y; |
368 end |
689 end |
369 else |
690 else |
370 begin |
691 begin |
371 VertexBuffer[0].X:= X; |
692 VertexBuffer[0].X:= X; |
400 procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat); |
721 procedure DrawTexture(X, Y: LongInt; Texture: PTexture; Scale: GLfloat); |
401 begin |
722 begin |
402 |
723 |
403 openglPushMatrix; |
724 openglPushMatrix; |
404 openglTranslatef(X, Y, 0); |
725 openglTranslatef(X, Y, 0); |
405 openglScalef(Scale, Scale, 1); |
726 |
727 if Scale <> 1.0 then |
|
728 openglScalef(Scale, Scale, 1); |
|
406 |
729 |
407 glBindTexture(GL_TEXTURE_2D, Texture^.id); |
730 glBindTexture(GL_TEXTURE_2D, Texture^.id); |
408 |
731 |
409 SetVertexPointer(@Texture^.vb, Length(Texture^.vb)); |
732 SetVertexPointer(@Texture^.vb, Length(Texture^.vb)); |
410 SetTexCoordPointer(@Texture^.tb, Length(Texture^.vb)); |
733 SetTexCoordPointer(@Texture^.tb, Length(Texture^.vb)); |
411 |
734 |
412 {$IFDEF GL2} |
|
413 UpdateModelviewProjection; |
735 UpdateModelviewProjection; |
414 {$ENDIF} |
|
415 |
736 |
416 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb)); |
737 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(Texture^.vb)); |
417 openglPopMatrix; |
738 openglPopMatrix; |
418 |
739 |
419 end; |
740 end; |
455 procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
776 procedure DrawTextureRotatedF(Texture: PTexture; Scale, OffsetX, OffsetY: GLfloat; X, Y, Frame, Dir, w, h: LongInt; Angle: real); |
456 var ft, fb, fl, fr: GLfloat; |
777 var ft, fb, fl, fr: GLfloat; |
457 hw, hh, nx, ny: LongInt; |
778 hw, hh, nx, ny: LongInt; |
458 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
779 VertexBuffer, TextureBuffer: array [0..3] of TVertex2f; |
459 begin |
780 begin |
781 |
|
782 if isDxAreaOffscreen(X, w) <> 0 then |
|
783 exit; |
|
784 if isDyAreaOffscreen(Y, h) <> 0 then |
|
785 exit; |
|
786 |
|
460 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
787 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
461 if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then |
788 {if (abs(X) > W) and ((abs(X + dir * OffsetX) - W / 2) * cScaleFactor > cScreenWidth) then |
462 exit; |
789 exit; |
463 if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then |
790 if (abs(Y) > H) and ((abs(Y + OffsetY - (0.5 * cScreenHeight)) - W / 2) * cScaleFactor > cScreenHeight) then |
464 exit; |
791 exit;} |
465 |
792 |
466 openglPushMatrix; |
793 openglPushMatrix; |
467 |
794 |
468 openglTranslatef(X, Y, 0); |
795 openglTranslatef(X, Y, 0); |
469 |
796 |
556 end; |
883 end; |
557 |
884 |
558 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
885 procedure DrawTextureRotated(Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real); |
559 var VertexBuffer: array [0..3] of TVertex2f; |
886 var VertexBuffer: array [0..3] of TVertex2f; |
560 begin |
887 begin |
888 |
|
889 if isDxAreaOffscreen(X, 2 * hw) <> 0 then |
|
890 exit; |
|
891 if isDyAreaOffscreen(Y, 2 * hh) <> 0 then |
|
892 exit; |
|
893 |
|
561 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
894 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
562 if (abs(X) > 2 * hw) and ((abs(X) - hw) > cScreenWidth / cScaleFactor) then |
895 {if (abs(X) > 2 * hw) and ((abs(X) - hw) > cScreenWidth / cScaleFactor) then |
563 exit; |
896 exit; |
564 if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then |
897 if (abs(Y) > 2 * hh) and ((abs(Y - 0.5 * cScreenHeight) - hh) > cScreenHeight / cScaleFactor) then |
565 exit; |
898 exit;} |
566 |
899 |
567 openglPushMatrix; |
900 openglPushMatrix; |
568 openglTranslatef(X, Y, 0); |
901 openglTranslatef(X, Y, 0); |
569 |
902 |
570 if Dir < 0 then |
903 if Dir < 0 then |
645 DrawTextureFromRect(X + r.x, Y + r.y, @r, SpritesData[Sprite].Texture) |
978 DrawTextureFromRect(X + r.x, Y + r.y, @r, SpritesData[Sprite].Texture) |
646 end; |
979 end; |
647 |
980 |
648 procedure DrawTextureCentered(X, Top: LongInt; Source: PTexture); |
981 procedure DrawTextureCentered(X, Top: LongInt; Source: PTexture); |
649 var scale: GLfloat; |
982 var scale: GLfloat; |
650 begin |
983 left : LongInt; |
984 begin |
|
985 // scale down if larger than screen |
|
651 if (Source^.w + 20) > cScreenWidth then |
986 if (Source^.w + 20) > cScreenWidth then |
652 scale:= cScreenWidth / (Source^.w + 20) |
987 begin |
988 scale:= cScreenWidth / (Source^.w + 20); |
|
989 DrawTexture(X - round(Source^.w * scale) div 2, Top, Source, scale); |
|
990 end |
|
653 else |
991 else |
654 scale:= 1.0; |
992 begin |
655 DrawTexture(X - round(Source^.w * scale) div 2, Top, Source, scale) |
993 left:= X - Source^.w div 2; |
994 if (not isAreaOffscreen(left, Top, Source^.w, Source^.h)) then |
|
995 DrawTexture(left, Top, Source); |
|
996 end; |
|
656 end; |
997 end; |
657 |
998 |
658 procedure DrawLine(X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; |
999 procedure DrawLine(X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; |
659 begin |
1000 begin |
660 DrawLine(X0, Y0, X1, Y1, Width, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF) |
1001 DrawLine(X0, Y0, X1, Y1, Width, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF) |
688 EnableTexture(True); |
1029 EnableTexture(True); |
689 |
1030 |
690 glDisable(GL_LINE_SMOOTH); |
1031 glDisable(GL_LINE_SMOOTH); |
691 end; |
1032 end; |
692 |
1033 |
693 procedure DrawFillRect(r: TSDL_Rect); |
1034 procedure DrawRect(rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean); |
694 var VertexBuffer: array [0..3] of TVertex2f; |
1035 var VertexBuffer: array [0..3] of TVertex2f; |
695 begin |
1036 begin |
696 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
1037 // do not draw anything outside the visible screen space (first check fixes some sprite drawing, e.g. hedgehogs) |
697 |
1038 {if (abs(r.x) > r.w) and ((abs(r.x + r.w / 2) - r.w / 2) * cScaleFactor > cScreenWidth) then |
698 if (abs(r.x) > r.w) and ((abs(r.x + r.w / 2) - r.w / 2) * cScaleFactor > cScreenWidth) then |
|
699 exit; |
1039 exit; |
700 if (abs(r.y) > r.h) and ((abs(r.y + r.h / 2 - (0.5 * cScreenHeight)) - r.h / 2) * cScaleFactor > cScreenHeight) then |
1040 if (abs(r.y) > r.h) and ((abs(r.y + r.h / 2 - (0.5 * cScreenHeight)) - r.h / 2) * cScaleFactor > cScreenHeight) then |
701 exit; |
1041 exit;} |
702 |
1042 |
703 EnableTexture(False); |
1043 EnableTexture(False); |
704 |
1044 |
705 Tint($00, $00, $00, $80); |
1045 Tint(r, g, b, a); |
706 |
1046 |
707 VertexBuffer[0].X:= r.x; |
1047 with rect do |
708 VertexBuffer[0].Y:= r.y; |
1048 begin |
709 VertexBuffer[1].X:= r.x + r.w; |
1049 VertexBuffer[0].X:= x; |
710 VertexBuffer[1].Y:= r.y; |
1050 VertexBuffer[0].Y:= y; |
711 VertexBuffer[2].X:= r.x + r.w; |
1051 VertexBuffer[1].X:= x + w; |
712 VertexBuffer[2].Y:= r.y + r.h; |
1052 VertexBuffer[1].Y:= y; |
713 VertexBuffer[3].X:= r.x; |
1053 VertexBuffer[2].X:= x + w; |
714 VertexBuffer[3].Y:= r.y + r.h; |
1054 VertexBuffer[2].Y:= y + h; |
1055 VertexBuffer[3].X:= x; |
|
1056 VertexBuffer[3].Y:= y + h; |
|
1057 end; |
|
715 |
1058 |
716 SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer)); |
1059 SetVertexPointer(@VertexBuffer[0], Length(VertexBuffer)); |
717 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)); |
1060 if Fill then |
1061 glDrawArrays(GL_TRIANGLE_FAN, 0, Length(VertexBuffer)) |
|
1062 else |
|
1063 glDrawArrays(GL_LINE_LOOP, 0, Length(VertexBuffer)); |
|
718 |
1064 |
719 untint; |
1065 untint; |
720 |
1066 |
721 EnableTexture(True); |
1067 EnableTexture(True); |
722 |
1068 |
951 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD) |
1297 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD) |
952 else |
1298 else |
953 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
1299 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); |
954 end; |
1300 end; |
955 |
1301 |
1302 procedure initModule; |
|
1303 begin |
|
1304 end; |
|
1305 |
|
1306 procedure freeModule; |
|
1307 begin |
|
1308 {$IFDEF GL2} |
|
1309 glDeleteProgram(shaderMain); |
|
1310 glDeleteProgram(shaderWater); |
|
1311 glDeleteBuffers(1, @vBuffer); |
|
1312 glDeleteBuffers(1, @tBuffer); |
|
1313 glDeleteBuffers(1, @cBuffer); |
|
1314 {$ENDIF} |
|
1315 end; |
|
956 end. |
1316 end. |