DEADSOFTWARE

render: disable FBO on devices which not support NPOT textures
[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 function r_Render_GetGibRect (m, id: Integer): TRectWH;
40 procedure r_Render_QueueEffect (AnimType, X, Y: Integer);
42 {$IFDEF ENABLE_TOUCH}
43 // touch screen button location and size
44 procedure r_Render_GetKeyRect (key: Integer; out x, y, w, h: Integer; out founded: Boolean);
45 {$ENDIF}
47 procedure r_Render_DrawLoading (force: Boolean); // !!! remove it
49 implementation
51 uses
52 {$INCLUDE ../../nogl/noGLuses.inc}
53 {$IFDEF ENABLE_TOUCH}
54 r_touch,
55 {$ENDIF}
56 SysUtils, Classes, Math,
57 e_log, g_system, utils,
58 g_game, g_options, g_console,
59 r_window, r_graphics, r_console, r_playermodel, r_textures, r_animations,
60 r_weapons, r_items, r_gfx, r_monsters, r_map, r_player, r_game
61 ;
63 var
64 LoadedGL: Boolean = false;
66 function GLExtensionList (): SSArray;
67 var s: PChar; i, j, num: GLint;
68 begin
69 result := nil;
70 s := glGetString(GL_EXTENSIONS);
71 if s <> nil then
72 begin
73 num := 0;
74 i := 0;
75 j := 0;
76 while (s[i] <> #0) and (s[i] = ' ') do Inc(i);
77 while (s[i] <> #0) do
78 begin
79 while (s[i] <> #0) and (s[i] <> ' ') do Inc(i);
80 SetLength(result, num+1);
81 result[num] := Copy(s, j+1, i-j);
82 while (s[i] <> #0) and (s[i] = ' ') do Inc(i);
83 j := i;
84 Inc(num)
85 end
86 end
87 end;
89 function GLExtensionSupported (ext: AnsiString): Boolean;
90 var e: AnsiString;
91 begin
92 {$IFDEF NOGL_INIT}
93 Result := nogl_ExtensionSupported(ext);
94 {$ELSE}
95 result := false;
96 for e in GLExtensionList() do
97 begin
98 if strEquCI1251(e, ext) then
99 begin
100 result := true;
101 exit
102 end
103 end
104 {$ENDIF}
105 end;
107 function HaveNPOTSupport (): Boolean;
108 begin
109 Result := GLExtensionSupported('GL_ARB_texture_non_power_of_two') or
110 GLExtensionSupported('GL_OES_texture_npot')
111 end;
113 function HaveFBOSupport (): Boolean;
114 begin
115 Result := GLExtensionSupported('GL_ARB_framebuffer_object') or
116 GLExtensionSupported('GL_OES_framebuffer_object')
117 end;
119 procedure PrintGLSupportedExtensions;
120 begin
121 e_LogWritefln('GL Vendor: %s', [glGetString(GL_VENDOR)]);
122 e_LogWritefln('GL Renderer: %s', [glGetString(GL_RENDERER)]);
123 e_LogWritefln('GL Version: %s', [glGetString(GL_VERSION)]);
124 e_LogWritefln('GL Shaders: %s', [glGetString(GL_SHADING_LANGUAGE_VERSION)]);
125 e_LogWritefln('GL Extensions: %s', [glGetString(GL_EXTENSIONS)]);
126 end;
128 procedure r_Window_Initialize;
129 begin
130 {$IFNDEF USE_SYSSTUB}
131 PrintGLSupportedExtensions;
132 glLegacyNPOT := not HaveNPOTSupport();
133 {$ELSE}
134 glLegacyNPOT := False;
135 glRenderToFBO := False;
136 {$ENDIF}
137 if glNPOTOverride and glLegacyNPOT then
138 begin
139 glLegacyNPOT := true;
140 e_logWriteln('NPOT texture emulation: FORCED')
141 end
142 else
143 begin
144 if glLegacyNPOT then
145 e_logWriteln('NPOT texture emulation: enabled')
146 else
147 e_logWriteln('NPOT texture emulation: disabled')
148 end
149 end;
151 procedure LoadGL;
152 var fboload: Boolean;
153 begin
154 if LoadedGL = false then
155 begin
156 {$IFDEF NOGL_INIT}
157 nogl_Init;
158 {$ENDIF}
159 if glRenderToFBO then
160 begin
161 fboload := True;
162 {$IFDEF NOGL_INIT}
163 fboload := True; // !!! but if not?
164 {$ELSE}
165 fboload := Load_GL_ARB_framebuffer_object();
166 {$ENDIF}
167 if (fboload = False) or (HaveFBOSupport() = False) or (HaveNPOTSupport() = False) then
168 begin
169 e_LogWriteln('GL: framebuffer objects not supported; disabling FBO rendering');
170 glRenderToFBO := false
171 end;
172 end;
173 LoadedGL := true
174 end
175 end;
177 procedure FreeGL;
178 begin
179 if LoadedGL = true then
180 begin
181 {$IFDEF NOGL_INIT}
182 nogl_Quit;
183 {$ENDIF}
184 LoadedGL := false
185 end
186 end;
188 procedure r_Render_LoadTextures;
189 begin
190 r_Game_LoadTextures;
191 r_Map_LoadTextures;
192 end;
194 procedure r_Render_FreeTextures;
195 begin
196 r_Map_FreeTextures;
197 r_Game_FreeTextures;
198 end;
200 procedure r_Render_Load;
201 begin
202 r_Game_Load; // load first!
203 r_Player_Load;
204 r_Map_Load;
205 r_PlayerModel_Load;
206 r_Monsters_Load;
207 r_Weapon_Load;
208 r_Items_Load;
209 r_GFX_Load;
210 end;
212 procedure r_Render_Free;
213 begin
214 r_GFX_Free;
215 r_Items_Free;
216 r_Weapon_Free;
217 r_Monsters_Free;
218 r_PlayerModel_Free;
219 r_Map_Free;
220 r_Player_Free;
221 r_Game_Free;
222 g_Texture_DeleteAll;
223 g_Frames_DeleteAll;
224 end;
226 procedure r_Render_Initialize;
227 begin
228 if sys_SetDisplayMode(gRC_Width, gRC_Height, gBPP, gRC_FullScreen, gRC_Maximized) = False then
229 raise Exception.Create('Failed to set videomode on startup.');
230 LoadGL;
231 r_Window_Initialize;
232 r_Console_Init;
233 r_PlayerModel_Initialize;
234 r_Map_Initialize;
235 end;
237 procedure r_Render_Finalize;
238 begin
239 r_Map_Finalize;
240 r_PlayerModel_Finalize;
241 FreeGL;
242 e_ReleaseEngine
243 end;
245 procedure r_Render_Update;
246 begin
247 r_GFX_Update;
248 r_Map_Update;
249 r_PlayerModel_Update;
250 r_Console_Update;
251 end;
253 procedure r_Render_Draw;
254 begin
255 r_Game_Draw;
256 {$IFDEF ENABLE_TOUCH}
257 r_Touch_Draw;
258 {$ENDIF}
259 end;
261 procedure r_Render_Resize (w, h: Integer);
262 begin
263 LoadGL;
264 gWinSizeX := w;
265 gWinSizeY := h;
266 gRC_Width := w;
267 gRC_Height := h;
268 if glRenderToFBO then
269 begin
270 // store real window size in gWinSize, downscale resolution now
271 w := round(w / r_pixel_scale);
272 h := round(h / r_pixel_scale);
273 if not e_ResizeFramebuffer(w, h) then
274 begin
275 e_LogWriteln('GL: could not create framebuffer, falling back to --no-fbo');
276 glRenderToFBO := False;
277 w := gWinSizeX;
278 h := gWinSizeY;
279 end;
280 end;
281 gScreenWidth := w;
282 gScreenHeight := h;
283 e_ResizeWindow(w, h);
284 e_InitGL;
285 r_Game_SetupScreenSize;
286 end;
288 procedure r_Render_Apply;
289 begin
290 if sys_SetDisplayMode(Max(1, gRC_Width), Max(1, gRC_Height), Max(1, gBPP), gRC_FullScreen, gRC_Maximized) then
291 e_LogWriteln('resolution changed')
292 else
293 e_LogWriteln('resolution not changed');
294 sys_EnableVSync(gVSync)
295 end;
297 function r_Render_WriteScreenShot (filename: String): Boolean;
298 var s: TStream;
299 begin
300 Result := False;
301 try
302 s := CreateDiskFile(filename);
303 try
304 e_MakeScreenshot(s, gScreenWidth, gScreenHeight);
305 Result := True;
306 except
307 DeleteFile(filename)
308 end;
309 s.Free;
310 finally
311 end
312 end;
314 function r_Render_GetGibRect (m, id: Integer): TRectWH;
315 begin
316 Result := r_PlayerModel_GetGibRect(m, id)
317 end;
319 procedure r_Render_QueueEffect (AnimType, X, Y: Integer);
320 begin
321 r_GFX_OnceAnim(AnimType, X, Y)
322 end;
324 {$IFDEF ENABLE_TOUCH}
325 procedure r_Render_GetKeyRect (key: Integer; out x, y, w, h: Integer; out founded: Boolean);
326 begin
327 r_Touch_GetKeyRect (key, x, y, w, h, founded)
328 end;
329 {$ENDIF}
331 procedure r_Render_DrawLoading (force: Boolean);
332 begin
333 r_Window_DrawLoading(force)
334 end;
336 end.