DEADSOFTWARE

render: disable FBO on devices which not support NPOT textures
[d2df-sdl.git] / src / game / opengl / r_render.pas
index b6bb016f74410f1cf5dd53fa0e57c355ccd35720..1773ba729dd1090331bb415d4cc8efbb35bbd5bc 100644 (file)
@@ -17,50 +17,159 @@ unit r_render;
 
 interface
 
+  uses g_base; // TRectWH
+
   procedure r_Render_Initialize;
   procedure r_Render_Finalize;
 
-  procedure r_Render_Resize (w, h: Integer);
-
   procedure r_Render_Load;
   procedure r_Render_Free;
 
+  procedure r_Render_LoadTextures;
+  procedure r_Render_FreeTextures;
+
   procedure r_Render_Update;
+  procedure r_Render_Draw;
 
+  procedure r_Render_Resize (w, h: Integer);
   procedure r_Render_Apply;
 
+  function r_Render_WriteScreenShot (filename: String): Boolean;
+
+  function r_Render_GetGibRect (m, id: Integer): TRectWH;
+  procedure r_Render_QueueEffect (AnimType, X, Y: Integer);
+
+{$IFDEF ENABLE_TOUCH}
+  // touch screen button location and size
+  procedure r_Render_GetKeyRect (key: Integer; out x, y, w, h: Integer; out founded: Boolean);
+{$ENDIF}
+
+  procedure r_Render_DrawLoading (force: Boolean); // !!! remove it
+
 implementation
 
   uses
     {$INCLUDE ../../nogl/noGLuses.inc}
+    {$IFDEF ENABLE_TOUCH}
+      r_touch,
+    {$ENDIF}
     SysUtils, Classes, Math,
-    e_log, g_system,
+    e_log, g_system, utils,
     g_game, g_options, g_console,
-    r_window, r_graphics, r_console, r_playermodel,
-    r_weapons, r_items, r_gfx, r_monsters, r_map, r_player
+    r_window, r_graphics, r_console, r_playermodel, r_textures, r_animations,
+    r_weapons, r_items, r_gfx, r_monsters, r_map, r_player, r_game
   ;
 
   var
     LoadedGL: Boolean = false;
 
+  function GLExtensionList (): SSArray;
+    var s: PChar; i, j, num: GLint;
+  begin
+    result := nil;
+    s := glGetString(GL_EXTENSIONS);
+    if s <> nil then
+    begin
+      num := 0;
+      i := 0;
+      j := 0;
+      while (s[i] <> #0) and (s[i] = ' ') do Inc(i);
+      while (s[i] <> #0) do
+      begin
+        while (s[i] <> #0) and (s[i] <> ' ') do Inc(i);
+        SetLength(result, num+1);
+        result[num] := Copy(s, j+1, i-j);
+        while (s[i] <> #0) and (s[i] = ' ') do Inc(i);
+        j := i;
+        Inc(num)
+      end
+    end
+  end;
+
+  function GLExtensionSupported (ext: AnsiString): Boolean;
+    var e: AnsiString;
+  begin
+    {$IFDEF NOGL_INIT}
+      Result := nogl_ExtensionSupported(ext);
+    {$ELSE}
+      result := false;
+      for e in GLExtensionList() do
+      begin
+        if strEquCI1251(e, ext) then
+        begin
+          result := true;
+          exit
+        end
+      end
+    {$ENDIF}
+  end;
+
+  function HaveNPOTSupport (): Boolean;
+  begin
+    Result := GLExtensionSupported('GL_ARB_texture_non_power_of_two') or
+              GLExtensionSupported('GL_OES_texture_npot')
+  end;
+
+  function HaveFBOSupport (): Boolean;
+  begin
+    Result := GLExtensionSupported('GL_ARB_framebuffer_object') or
+              GLExtensionSupported('GL_OES_framebuffer_object')
+  end;
+
+  procedure PrintGLSupportedExtensions;
+  begin
+    e_LogWritefln('GL Vendor: %s', [glGetString(GL_VENDOR)]);
+    e_LogWritefln('GL Renderer: %s', [glGetString(GL_RENDERER)]);
+    e_LogWritefln('GL Version: %s', [glGetString(GL_VERSION)]);
+    e_LogWritefln('GL Shaders: %s', [glGetString(GL_SHADING_LANGUAGE_VERSION)]);
+    e_LogWritefln('GL Extensions: %s', [glGetString(GL_EXTENSIONS)]);
+  end;
+
+  procedure r_Window_Initialize;
+  begin
+{$IFNDEF USE_SYSSTUB}
+    PrintGLSupportedExtensions;
+    glLegacyNPOT := not HaveNPOTSupport();
+{$ELSE}
+    glLegacyNPOT := False;
+    glRenderToFBO := False;
+{$ENDIF}
+    if glNPOTOverride and glLegacyNPOT then
+    begin
+      glLegacyNPOT := true;
+      e_logWriteln('NPOT texture emulation: FORCED')
+    end
+    else
+    begin
+      if glLegacyNPOT then
+        e_logWriteln('NPOT texture emulation: enabled')
+      else
+        e_logWriteln('NPOT texture emulation: disabled')
+    end
+  end;
+
   procedure LoadGL;
+    var fboload: Boolean;
   begin
     if LoadedGL = false then
     begin
       {$IFDEF NOGL_INIT}
         nogl_Init;
-        if glRenderToFBO and (not nogl_ExtensionSupported('GL_OES_framebuffer_object')) then
-        begin
-          e_LogWriteln('GL: framebuffer objects not supported; disabling FBO rendering');
-          glRenderToFBO := false
-        end;
-      {$ELSE}
-        if glRenderToFBO and (not Load_GL_ARB_framebuffer_object) then
+      {$ENDIF}
+      if glRenderToFBO then
+      begin
+        fboload := True;
+        {$IFDEF NOGL_INIT}
+          fboload := True; // !!! but if not?
+        {$ELSE}
+          fboload := Load_GL_ARB_framebuffer_object();
+        {$ENDIF}
+        if (fboload = False) or (HaveFBOSupport() = False) or (HaveNPOTSupport() = False) then
         begin
           e_LogWriteln('GL: framebuffer objects not supported; disabling FBO rendering');
           glRenderToFBO := false
         end;
-      {$ENDIF}
+      end;
       LoadedGL := true
     end
   end;
@@ -76,8 +185,21 @@ implementation
     end
   end;
 
+  procedure r_Render_LoadTextures;
+  begin
+    r_Game_LoadTextures;
+    r_Map_LoadTextures;
+  end;
+
+  procedure r_Render_FreeTextures;
+  begin
+    r_Map_FreeTextures;
+    r_Game_FreeTextures;
+  end;
+
   procedure r_Render_Load;
   begin
+    r_Game_Load; // load first!
     r_Player_Load;
     r_Map_Load;
     r_PlayerModel_Load;
@@ -96,6 +218,9 @@ implementation
     r_PlayerModel_Free;
     r_Map_Free;
     r_Player_Free;
+    r_Game_Free;
+    g_Texture_DeleteAll;
+    g_Frames_DeleteAll;
   end;
 
   procedure r_Render_Initialize;
@@ -119,8 +244,18 @@ implementation
 
   procedure r_Render_Update;
   begin
+    r_GFX_Update;
     r_Map_Update;
     r_PlayerModel_Update;
+    r_Console_Update;
+  end;
+
+  procedure r_Render_Draw;
+  begin
+    r_Game_Draw;
+    {$IFDEF ENABLE_TOUCH}
+      r_Touch_Draw;
+    {$ENDIF}
   end;
 
   procedure r_Render_Resize (w, h: Integer);
@@ -146,7 +281,8 @@ implementation
     gScreenWidth := w;
     gScreenHeight := h;
     e_ResizeWindow(w, h);
-    e_InitGL
+    e_InitGL;
+    r_Game_SetupScreenSize;
   end;
 
   procedure r_Render_Apply;
@@ -158,4 +294,43 @@ implementation
     sys_EnableVSync(gVSync)
   end;
 
+  function r_Render_WriteScreenShot (filename: String): Boolean;
+    var s: TStream;
+  begin
+    Result := False;
+    try
+      s := CreateDiskFile(filename);
+      try
+        e_MakeScreenshot(s, gScreenWidth, gScreenHeight);
+        Result := True;
+      except
+        DeleteFile(filename)
+      end;
+      s.Free;
+    finally
+    end
+  end;
+
+  function r_Render_GetGibRect (m, id: Integer): TRectWH;
+  begin
+    Result := r_PlayerModel_GetGibRect(m, id)
+  end;
+
+  procedure r_Render_QueueEffect (AnimType, X, Y: Integer);
+  begin
+    r_GFX_OnceAnim(AnimType, X, Y)
+  end;
+
+{$IFDEF ENABLE_TOUCH}
+  procedure r_Render_GetKeyRect (key: Integer; out x, y, w, h: Integer; out founded: Boolean);
+  begin
+    r_Touch_GetKeyRect (key, x, y, w, h, founded)
+  end;
+{$ENDIF}
+
+  procedure r_Render_DrawLoading (force: Boolean);
+  begin
+    r_Window_DrawLoading(force)
+  end;
+
 end.