DEADSOFTWARE

869b27ff25f9b645d5e5c0a43e506c9aa2ea2dca
[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 {$IFDEF ENABLE_MENU}
68 r_gui,
69 {$ENDIF}
70 SysUtils, Classes, Math,
71 e_log, utils,
72 g_game, g_options, g_console,
73 r_window, r_graphics, r_console, r_playermodel, r_textures, r_animations,
74 r_weapons, r_items, r_monsters, r_map, r_player, r_game
75 ;
77 var
78 LoadedGL: Boolean = false;
80 function GLExtensionList (): SSArray;
81 var s: PChar; i, j, num: GLint;
82 begin
83 result := nil;
84 s := glGetString(GL_EXTENSIONS);
85 if s <> nil then
86 begin
87 num := 0;
88 i := 0;
89 j := 0;
90 while (s[i] <> #0) and (s[i] = ' ') do Inc(i);
91 while (s[i] <> #0) do
92 begin
93 while (s[i] <> #0) and (s[i] <> ' ') do Inc(i);
94 SetLength(result, num+1);
95 result[num] := Copy(s, j+1, i-j);
96 while (s[i] <> #0) and (s[i] = ' ') do Inc(i);
97 j := i;
98 Inc(num)
99 end
100 end
101 end;
103 function GLExtensionSupported (ext: AnsiString): Boolean;
104 var e: AnsiString;
105 begin
106 {$IFDEF NOGL_INIT}
107 Result := nogl_ExtensionSupported(ext);
108 {$ELSE}
109 result := false;
110 for e in GLExtensionList() do
111 begin
112 if strEquCI1251(e, ext) then
113 begin
114 result := true;
115 exit
116 end
117 end
118 {$ENDIF}
119 end;
121 function HaveNPOTSupport (): Boolean;
122 begin
123 Result := GLExtensionSupported('GL_ARB_texture_non_power_of_two') or
124 GLExtensionSupported('GL_OES_texture_npot')
125 end;
127 function HaveFBOSupport (): Boolean;
128 begin
129 Result := GLExtensionSupported('GL_ARB_framebuffer_object') or
130 GLExtensionSupported('GL_OES_framebuffer_object')
131 end;
133 procedure PrintGLSupportedExtensions;
134 begin
135 e_LogWritefln('GL Vendor: %s', [glGetString(GL_VENDOR)]);
136 e_LogWritefln('GL Renderer: %s', [glGetString(GL_RENDERER)]);
137 e_LogWritefln('GL Version: %s', [glGetString(GL_VERSION)]);
138 e_LogWritefln('GL Shaders: %s', [glGetString(GL_SHADING_LANGUAGE_VERSION)]);
139 e_LogWritefln('GL Extensions: %s', [glGetString(GL_EXTENSIONS)]);
140 end;
142 procedure r_Window_Initialize;
143 begin
144 {$IFNDEF USE_SYSSTUB}
145 PrintGLSupportedExtensions;
146 glLegacyNPOT := not HaveNPOTSupport();
147 {$ELSE}
148 glLegacyNPOT := False;
149 glRenderToFBO := False;
150 {$ENDIF}
151 if glNPOTOverride and glLegacyNPOT then
152 begin
153 glLegacyNPOT := true;
154 e_logWriteln('NPOT texture emulation: FORCED')
155 end
156 else
157 begin
158 if glLegacyNPOT then
159 e_logWriteln('NPOT texture emulation: enabled')
160 else
161 e_logWriteln('NPOT texture emulation: disabled')
162 end
163 end;
165 procedure LoadGL;
166 var fboload: Boolean;
167 begin
168 if LoadedGL = false then
169 begin
170 {$IFDEF NOGL_INIT}
171 nogl_Init;
172 {$ENDIF}
173 if glRenderToFBO then
174 begin
175 fboload := True;
176 {$IFDEF NOGL_INIT}
177 fboload := True; // !!! but if not?
178 {$ELSE}
179 fboload := Load_GL_ARB_framebuffer_object();
180 {$ENDIF}
181 if (fboload = False) or (HaveFBOSupport() = False) or (HaveNPOTSupport() = False) then
182 begin
183 e_LogWriteln('GL: framebuffer objects not supported; disabling FBO rendering');
184 glRenderToFBO := false
185 end;
186 end;
187 LoadedGL := true
188 end
189 end;
191 procedure FreeGL;
192 begin
193 if LoadedGL = true then
194 begin
195 {$IFDEF NOGL_INIT}
196 nogl_Quit;
197 {$ENDIF}
198 LoadedGL := false
199 end
200 end;
202 procedure r_Render_LoadTextures;
203 begin
204 r_Game_LoadTextures;
205 r_Map_LoadTextures;
206 end;
208 procedure r_Render_FreeTextures;
209 begin
210 r_Map_FreeTextures;
211 r_Game_FreeTextures;
212 end;
214 procedure r_Render_Load;
215 begin
216 r_Game_Load; // load first!
217 r_Player_Load;
218 r_Map_Load;
219 r_PlayerModel_Load;
220 r_Monsters_Load;
221 r_Weapon_Load;
222 r_Items_Load;
223 {$IFDEF ENABLE_GFX}
224 r_GFX_Load;
225 {$ENDIF}
226 {$IFDEF ENABLE_MENU}
227 r_GUI_Load;
228 {$ENDIF}
229 end;
231 procedure r_Render_Free;
232 begin
233 {$IFDEF ENABLE_MENU}
234 r_GUI_Free;
235 {$ENDIF}
236 {$IFDEF ENABLE_GFX}
237 r_GFX_Free;
238 {$ENDIF}
239 r_Items_Free;
240 r_Weapon_Free;
241 r_Monsters_Free;
242 r_PlayerModel_Free;
243 r_Map_Free;
244 r_Player_Free;
245 r_Game_Free;
246 g_Texture_DeleteAll;
247 g_Frames_DeleteAll;
248 end;
250 procedure r_Render_Initialize;
251 begin
252 {$IFDEF ENABLE_SYSTEM}
253 if sys_SetDisplayMode(gRC_Width, gRC_Height, gBPP, gRC_FullScreen, gRC_Maximized) = False then
254 raise Exception.Create('Failed to set videomode on startup.');
255 {$ENDIF}
256 LoadGL;
257 r_Window_Initialize;
258 r_Console_Init;
259 r_PlayerModel_Initialize;
260 r_Map_Initialize;
261 end;
263 procedure r_Render_Finalize;
264 begin
265 r_Map_Finalize;
266 r_PlayerModel_Finalize;
267 FreeGL;
268 e_ReleaseEngine
269 end;
271 procedure r_Render_Update;
272 begin
273 {$IFDEF ENABLE_GFX}
274 r_GFX_Update;
275 {$ENDIF}
276 r_Map_Update;
277 r_PlayerModel_Update;
278 r_Console_Update;
279 end;
281 procedure r_Render_Draw;
282 begin
283 r_Game_Draw;
284 {$IFDEF ENABLE_TOUCH}
285 r_Touch_Draw;
286 {$ENDIF}
287 end;
289 procedure r_Render_Resize (w, h: Integer);
290 begin
291 LoadGL;
292 gWinSizeX := w;
293 gWinSizeY := h;
294 gRC_Width := w;
295 gRC_Height := h;
296 if glRenderToFBO then
297 begin
298 // store real window size in gWinSize, downscale resolution now
299 w := round(w / r_pixel_scale);
300 h := round(h / r_pixel_scale);
301 if not e_ResizeFramebuffer(w, h) then
302 begin
303 e_LogWriteln('GL: could not create framebuffer, falling back to --no-fbo');
304 glRenderToFBO := False;
305 w := gWinSizeX;
306 h := gWinSizeY;
307 end;
308 end;
309 gScreenWidth := w;
310 gScreenHeight := h;
311 e_ResizeWindow(w, h);
312 e_InitGL;
313 r_Game_SetupScreenSize;
314 end;
316 procedure r_Render_Apply;
317 begin
318 {$IFDEF ENABLE_SYSTEM}
319 if sys_SetDisplayMode(Max(1, gRC_Width), Max(1, gRC_Height), Max(1, gBPP), gRC_FullScreen, gRC_Maximized) then
320 e_LogWriteln('resolution changed')
321 else
322 e_LogWriteln('resolution not changed');
323 sys_EnableVSync(gVSync)
324 {$ENDIF}
325 end;
327 function r_Render_WriteScreenShot (filename: String): Boolean;
328 var s: TStream;
329 begin
330 Result := False;
331 try
332 s := CreateDiskFile(filename);
333 try
334 e_MakeScreenshot(s, gScreenWidth, gScreenHeight);
335 Result := True;
336 except
337 DeleteFile(filename)
338 end;
339 s.Free;
340 finally
341 end
342 end;
344 {$IFDEF ENABLE_GIBS}
345 function r_Render_GetGibRect (m, id: Integer): TRectWH;
346 begin
347 Result := r_PlayerModel_GetGibRect(m, id)
348 end;
349 {$ENDIF}
351 {$IFDEF ENABLE_GFX}
352 procedure r_Render_QueueEffect (AnimType, X, Y: Integer);
353 begin
354 r_GFX_OnceAnim(AnimType, X, Y)
355 end;
356 {$ENDIF}
358 {$IFDEF ENABLE_TOUCH}
359 procedure r_Render_GetKeyRect (key: Integer; out x, y, w, h: Integer; out founded: Boolean);
360 begin
361 r_Touch_GetKeyRect (key, x, y, w, h, founded)
362 end;
363 {$ENDIF}
365 procedure r_Render_DrawLoading (force: Boolean);
366 begin
367 r_Window_DrawLoading(force)
368 end;
370 end.