DEADSOFTWARE

2a4c3e7247226170373c12d4ce38ea07ca61444e
[d2df-sdl.git] / src / game / opengl / r_render.pas
1 (* Copyright (C) Doom 2D: Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License ONLY.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *)
15 {$INCLUDE ../../shared/a_modes.inc}
16 unit r_render;
18 interface
20 uses g_base; // TRectWH
22 procedure r_Render_Initialize;
23 procedure r_Render_Finalize;
25 procedure r_Render_Load;
26 procedure r_Render_Free;
28 procedure r_Render_LoadTextures;
29 procedure r_Render_FreeTextures;
31 procedure r_Render_Update;
32 procedure r_Render_Draw;
34 procedure r_Render_Resize (w, h: Integer);
35 procedure r_Render_Apply;
37 function r_Render_WriteScreenShot (filename: String): Boolean;
39 {$IFDEF ENABLE_GIBS}
40 function r_Render_GetGibRect (m, id: Integer): TRectWH;
41 {$ENDIF}
43 {$IFDEF ENABLE_GFX}
44 procedure r_Render_QueueEffect (AnimType, X, Y: Integer);
45 {$ENDIF}
47 {$IFDEF ENABLE_TOUCH}
48 // touch screen button location and size
49 procedure r_Render_GetKeyRect (key: Integer; out x, y, w, h: Integer; out founded: Boolean);
50 {$ENDIF}
52 procedure r_Render_DrawLoading (force: Boolean); // !!! remove it
54 implementation
56 uses
57 {$INCLUDE ../../nogl/noGLuses.inc}
58 {$IFDEF ENABLE_TOUCH}
59 r_touch,
60 {$ENDIF}
61 {$IFDEF ENABLE_GFX}
62 r_gfx,
63 {$ENDIF}
64 {$IFDEF ENABLE_SYSTEM}
65 g_system,
66 {$ENDIF}
67 SysUtils, Classes, Math,
68 e_log, utils,
69 g_game, g_options, g_console,
70 r_window, r_graphics, r_console, r_playermodel, r_textures, r_animations,
71 r_weapons, r_items, r_monsters, r_map, r_player, r_game
72 ;
74 var
75 LoadedGL: Boolean = false;
77 function GLExtensionList (): SSArray;
78 var s: PChar; i, j, num: GLint;
79 begin
80 result := nil;
81 s := glGetString(GL_EXTENSIONS);
82 if s <> nil then
83 begin
84 num := 0;
85 i := 0;
86 j := 0;
87 while (s[i] <> #0) and (s[i] = ' ') do Inc(i);
88 while (s[i] <> #0) do
89 begin
90 while (s[i] <> #0) and (s[i] <> ' ') do Inc(i);
91 SetLength(result, num+1);
92 result[num] := Copy(s, j+1, i-j);
93 while (s[i] <> #0) and (s[i] = ' ') do Inc(i);
94 j := i;
95 Inc(num)
96 end
97 end
98 end;
100 function GLExtensionSupported (ext: AnsiString): Boolean;
101 var e: AnsiString;
102 begin
103 {$IFDEF NOGL_INIT}
104 Result := nogl_ExtensionSupported(ext);
105 {$ELSE}
106 result := false;
107 for e in GLExtensionList() do
108 begin
109 if strEquCI1251(e, ext) then
110 begin
111 result := true;
112 exit
113 end
114 end
115 {$ENDIF}
116 end;
118 function HaveNPOTSupport (): Boolean;
119 begin
120 Result := GLExtensionSupported('GL_ARB_texture_non_power_of_two') or
121 GLExtensionSupported('GL_OES_texture_npot')
122 end;
124 function HaveFBOSupport (): Boolean;
125 begin
126 Result := GLExtensionSupported('GL_ARB_framebuffer_object') or
127 GLExtensionSupported('GL_OES_framebuffer_object')
128 end;
130 procedure PrintGLSupportedExtensions;
131 begin
132 e_LogWritefln('GL Vendor: %s', [glGetString(GL_VENDOR)]);
133 e_LogWritefln('GL Renderer: %s', [glGetString(GL_RENDERER)]);
134 e_LogWritefln('GL Version: %s', [glGetString(GL_VERSION)]);
135 e_LogWritefln('GL Shaders: %s', [glGetString(GL_SHADING_LANGUAGE_VERSION)]);
136 e_LogWritefln('GL Extensions: %s', [glGetString(GL_EXTENSIONS)]);
137 end;
139 procedure r_Window_Initialize;
140 begin
141 {$IFNDEF USE_SYSSTUB}
142 PrintGLSupportedExtensions;
143 glLegacyNPOT := not HaveNPOTSupport();
144 {$ELSE}
145 glLegacyNPOT := False;
146 glRenderToFBO := False;
147 {$ENDIF}
148 if glNPOTOverride and glLegacyNPOT then
149 begin
150 glLegacyNPOT := true;
151 e_logWriteln('NPOT texture emulation: FORCED')
152 end
153 else
154 begin
155 if glLegacyNPOT then
156 e_logWriteln('NPOT texture emulation: enabled')
157 else
158 e_logWriteln('NPOT texture emulation: disabled')
159 end
160 end;
162 procedure LoadGL;
163 var fboload: Boolean;
164 begin
165 if LoadedGL = false then
166 begin
167 {$IFDEF NOGL_INIT}
168 nogl_Init;
169 {$ENDIF}
170 if glRenderToFBO then
171 begin
172 fboload := True;
173 {$IFDEF NOGL_INIT}
174 fboload := True; // !!! but if not?
175 {$ELSE}
176 fboload := Load_GL_ARB_framebuffer_object();
177 {$ENDIF}
178 if (fboload = False) or (HaveFBOSupport() = False) or (HaveNPOTSupport() = False) then
179 begin
180 e_LogWriteln('GL: framebuffer objects not supported; disabling FBO rendering');
181 glRenderToFBO := false
182 end;
183 end;
184 LoadedGL := true
185 end
186 end;
188 procedure FreeGL;
189 begin
190 if LoadedGL = true then
191 begin
192 {$IFDEF NOGL_INIT}
193 nogl_Quit;
194 {$ENDIF}
195 LoadedGL := false
196 end
197 end;
199 procedure r_Render_LoadTextures;
200 begin
201 r_Game_LoadTextures;
202 r_Map_LoadTextures;
203 end;
205 procedure r_Render_FreeTextures;
206 begin
207 r_Map_FreeTextures;
208 r_Game_FreeTextures;
209 end;
211 procedure r_Render_Load;
212 begin
213 r_Game_Load; // load first!
214 r_Player_Load;
215 r_Map_Load;
216 r_PlayerModel_Load;
217 r_Monsters_Load;
218 r_Weapon_Load;
219 r_Items_Load;
220 {$IFDEF ENABLE_GFX}
221 r_GFX_Load;
222 {$ENDIF}
223 end;
225 procedure r_Render_Free;
226 begin
227 {$IFDEF ENABLE_GFX}
228 r_GFX_Free;
229 {$ENDIF}
230 r_Items_Free;
231 r_Weapon_Free;
232 r_Monsters_Free;
233 r_PlayerModel_Free;
234 r_Map_Free;
235 r_Player_Free;
236 r_Game_Free;
237 g_Texture_DeleteAll;
238 g_Frames_DeleteAll;
239 end;
241 procedure r_Render_Initialize;
242 begin
243 {$IFDEF ENABLE_SYSTEM}
244 if sys_SetDisplayMode(gRC_Width, gRC_Height, gBPP, gRC_FullScreen, gRC_Maximized) = False then
245 raise Exception.Create('Failed to set videomode on startup.');
246 {$ENDIF}
247 LoadGL;
248 r_Window_Initialize;
249 r_Console_Init;
250 r_PlayerModel_Initialize;
251 r_Map_Initialize;
252 end;
254 procedure r_Render_Finalize;
255 begin
256 r_Map_Finalize;
257 r_PlayerModel_Finalize;
258 FreeGL;
259 e_ReleaseEngine
260 end;
262 procedure r_Render_Update;
263 begin
264 {$IFDEF ENABLE_GFX}
265 r_GFX_Update;
266 {$ENDIF}
267 r_Map_Update;
268 r_PlayerModel_Update;
269 r_Console_Update;
270 end;
272 procedure r_Render_Draw;
273 begin
274 r_Game_Draw;
275 {$IFDEF ENABLE_TOUCH}
276 r_Touch_Draw;
277 {$ENDIF}
278 end;
280 procedure r_Render_Resize (w, h: Integer);
281 begin
282 LoadGL;
283 gWinSizeX := w;
284 gWinSizeY := h;
285 gRC_Width := w;
286 gRC_Height := h;
287 if glRenderToFBO then
288 begin
289 // store real window size in gWinSize, downscale resolution now
290 w := round(w / r_pixel_scale);
291 h := round(h / r_pixel_scale);
292 if not e_ResizeFramebuffer(w, h) then
293 begin
294 e_LogWriteln('GL: could not create framebuffer, falling back to --no-fbo');
295 glRenderToFBO := False;
296 w := gWinSizeX;
297 h := gWinSizeY;
298 end;
299 end;
300 gScreenWidth := w;
301 gScreenHeight := h;
302 e_ResizeWindow(w, h);
303 e_InitGL;
304 r_Game_SetupScreenSize;
305 end;
307 procedure r_Render_Apply;
308 begin
309 {$IFDEF ENABLE_SYSTEM}
310 if sys_SetDisplayMode(Max(1, gRC_Width), Max(1, gRC_Height), Max(1, gBPP), gRC_FullScreen, gRC_Maximized) then
311 e_LogWriteln('resolution changed')
312 else
313 e_LogWriteln('resolution not changed');
314 sys_EnableVSync(gVSync)
315 {$ENDIF}
316 end;
318 function r_Render_WriteScreenShot (filename: String): Boolean;
319 var s: TStream;
320 begin
321 Result := False;
322 try
323 s := CreateDiskFile(filename);
324 try
325 e_MakeScreenshot(s, gScreenWidth, gScreenHeight);
326 Result := True;
327 except
328 DeleteFile(filename)
329 end;
330 s.Free;
331 finally
332 end
333 end;
335 {$IFDEF ENABLE_GIBS}
336 function r_Render_GetGibRect (m, id: Integer): TRectWH;
337 begin
338 Result := r_PlayerModel_GetGibRect(m, id)
339 end;
340 {$ENDIF}
342 {$IFDEF ENABLE_GFX}
343 procedure r_Render_QueueEffect (AnimType, X, Y: Integer);
344 begin
345 r_GFX_OnceAnim(AnimType, X, Y)
346 end;
347 {$ENDIF}
349 {$IFDEF ENABLE_TOUCH}
350 procedure r_Render_GetKeyRect (key: Integer; out x, y, w, h: Integer; out founded: Boolean);
351 begin
352 r_Touch_GetKeyRect (key, x, y, w, h, founded)
353 end;
354 {$ENDIF}
356 procedure r_Render_DrawLoading (force: Boolean);
357 begin
358 r_Window_DrawLoading(force)
359 end;
361 end.