2022-01-04 14:29:01 +01:00
|
|
|
/* Copyright (C) 2022 Wildfire Games.
|
2009-04-18 19:00:33 +02:00
|
|
|
* This file is part of 0 A.D.
|
|
|
|
*
|
|
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2004-06-03 20:38:14 +02:00
|
|
|
#include "precompiled.h"
|
|
|
|
|
2011-01-29 17:31:48 +01:00
|
|
|
#include "Renderer.h"
|
|
|
|
|
2022-01-04 19:13:45 +01:00
|
|
|
#include "graphics/Canvas2D.h"
|
|
|
|
#include "graphics/CinemaManager.h"
|
|
|
|
#include "graphics/GameView.h"
|
|
|
|
#include "graphics/LightEnv.h"
|
|
|
|
#include "graphics/ModelDef.h"
|
|
|
|
#include "graphics/TerrainTextureManager.h"
|
|
|
|
#include "i18n/L10n.h"
|
|
|
|
#include "lib/allocators/shared_ptr.h"
|
|
|
|
#include "lib/ogl.h"
|
2022-01-07 00:23:36 +01:00
|
|
|
#include "lib/tex/tex.h"
|
2022-01-04 19:13:45 +01:00
|
|
|
#include "gui/GUIManager.h"
|
|
|
|
#include "ps/CConsole.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "ps/CLogger.h"
|
2012-01-29 02:22:22 +01:00
|
|
|
#include "ps/ConfigDB.h"
|
2021-05-18 13:09:54 +02:00
|
|
|
#include "ps/CStrInternStatic.h"
|
2004-09-26 06:05:35 +02:00
|
|
|
#include "ps/Game.h"
|
2022-01-04 19:13:45 +01:00
|
|
|
#include "ps/GameSetup/Config.h"
|
|
|
|
#include "ps/GameSetup/GameSetup.h"
|
|
|
|
#include "ps/Globals.h"
|
|
|
|
#include "ps/Loader.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "ps/Profile.h"
|
2007-12-22 19:15:52 +01:00
|
|
|
#include "ps/Filesystem.h"
|
2006-06-02 04:10:27 +02:00
|
|
|
#include "ps/World.h"
|
2007-12-20 21:21:45 +01:00
|
|
|
#include "ps/ProfileViewer.h"
|
|
|
|
#include "graphics/Camera.h"
|
2013-10-18 17:53:07 +02:00
|
|
|
#include "graphics/FontManager.h"
|
2011-03-26 21:17:21 +01:00
|
|
|
#include "graphics/ShaderManager.h"
|
|
|
|
#include "graphics/Terrain.h"
|
|
|
|
#include "graphics/Texture.h"
|
|
|
|
#include "graphics/TextureManager.h"
|
2022-01-04 19:13:45 +01:00
|
|
|
#include "ps/Util.h"
|
2021-12-14 07:34:02 +01:00
|
|
|
#include "ps/VideoMode.h"
|
2022-01-04 19:13:45 +01:00
|
|
|
#include "renderer/backend/gl/Device.h"
|
2021-04-15 20:07:01 +02:00
|
|
|
#include "renderer/DebugRenderer.h"
|
2014-10-28 04:57:22 +01:00
|
|
|
#include "renderer/PostprocManager.h"
|
2019-08-04 10:28:30 +02:00
|
|
|
#include "renderer/RenderingOptions.h"
|
2005-10-25 03:43:07 +02:00
|
|
|
#include "renderer/RenderModifiers.h"
|
2022-01-04 14:29:01 +01:00
|
|
|
#include "renderer/SceneRenderer.h"
|
2012-08-06 21:10:47 +02:00
|
|
|
#include "renderer/TimeManager.h"
|
2011-03-13 19:58:09 +01:00
|
|
|
#include "renderer/VertexBufferManager.h"
|
2022-01-04 19:13:45 +01:00
|
|
|
#include "tools/atlas/GameInterface/GameLoop.h"
|
|
|
|
#include "tools/atlas/GameInterface/View.h"
|
2005-10-05 18:42:09 +02:00
|
|
|
|
2021-04-15 20:07:01 +02:00
|
|
|
#include <algorithm>
|
2014-10-28 04:57:22 +01:00
|
|
|
|
2022-01-04 19:13:45 +01:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
size_t g_NextScreenShotNumber = 0;
|
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CRendererStatsTable - Profile display of rendering stats
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class CRendererStatsTable: Implementation of AbstractProfileTable to
|
|
|
|
* display the renderer stats in-game.
|
|
|
|
*
|
|
|
|
* Accesses CRenderer::m_Stats by keeping the reference passed to the
|
|
|
|
* constructor.
|
|
|
|
*/
|
2009-01-03 19:40:28 +01:00
|
|
|
class CRendererStatsTable : public AbstractProfileTable
|
2005-11-19 17:15:34 +01:00
|
|
|
{
|
2009-01-03 19:40:28 +01:00
|
|
|
NONCOPYABLE(CRendererStatsTable);
|
2005-11-19 17:15:34 +01:00
|
|
|
public:
|
|
|
|
CRendererStatsTable(const CRenderer::Stats& st);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
// Implementation of AbstractProfileTable interface
|
|
|
|
CStr GetName();
|
|
|
|
CStr GetTitle();
|
2006-09-01 08:59:29 +02:00
|
|
|
size_t GetNumberRows();
|
2005-11-19 17:15:34 +01:00
|
|
|
const std::vector<ProfileColumn>& GetColumns();
|
2006-09-01 08:59:29 +02:00
|
|
|
CStr GetCellText(size_t row, size_t col);
|
|
|
|
AbstractProfileTable* GetChild(size_t row);
|
2005-11-19 17:15:34 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
/// Reference to the renderer singleton's stats
|
|
|
|
const CRenderer::Stats& Stats;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
/// Column descriptions
|
|
|
|
std::vector<ProfileColumn> columnDescriptions;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2022-01-04 14:29:01 +01:00
|
|
|
enum
|
|
|
|
{
|
2011-04-29 14:26:31 +02:00
|
|
|
Row_DrawCalls = 0,
|
2005-11-19 17:15:34 +01:00
|
|
|
Row_TerrainTris,
|
2011-07-13 01:48:05 +02:00
|
|
|
Row_WaterTris,
|
2005-11-19 17:15:34 +01:00
|
|
|
Row_ModelTris,
|
2011-07-30 02:56:45 +02:00
|
|
|
Row_OverlayTris,
|
2005-11-19 17:15:34 +01:00
|
|
|
Row_BlendSplats,
|
2011-04-29 14:26:31 +02:00
|
|
|
Row_Particles,
|
2011-03-13 19:58:09 +01:00
|
|
|
Row_VBReserved,
|
|
|
|
Row_VBAllocated,
|
2013-11-09 02:03:23 +01:00
|
|
|
Row_TextureMemory,
|
2012-04-03 20:44:46 +02:00
|
|
|
Row_ShadersLoaded,
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
// Must be last to count number of rows
|
|
|
|
NumberRows
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// Construction
|
|
|
|
CRendererStatsTable::CRendererStatsTable(const CRenderer::Stats& st)
|
|
|
|
: Stats(st)
|
|
|
|
{
|
|
|
|
columnDescriptions.push_back(ProfileColumn("Name", 230));
|
|
|
|
columnDescriptions.push_back(ProfileColumn("Value", 100));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Implementation of AbstractProfileTable interface
|
|
|
|
CStr CRendererStatsTable::GetName()
|
|
|
|
{
|
|
|
|
return "renderer";
|
|
|
|
}
|
|
|
|
|
|
|
|
CStr CRendererStatsTable::GetTitle()
|
|
|
|
{
|
|
|
|
return "Renderer statistics";
|
|
|
|
}
|
|
|
|
|
2006-09-01 08:59:29 +02:00
|
|
|
size_t CRendererStatsTable::GetNumberRows()
|
2005-11-19 17:15:34 +01:00
|
|
|
{
|
|
|
|
return NumberRows;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::vector<ProfileColumn>& CRendererStatsTable::GetColumns()
|
|
|
|
{
|
|
|
|
return columnDescriptions;
|
|
|
|
}
|
|
|
|
|
2006-09-01 08:59:29 +02:00
|
|
|
CStr CRendererStatsTable::GetCellText(size_t row, size_t col)
|
2005-11-19 17:15:34 +01:00
|
|
|
{
|
|
|
|
char buf[256];
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
switch(row)
|
|
|
|
{
|
|
|
|
case Row_DrawCalls:
|
|
|
|
if (col == 0)
|
|
|
|
return "# draw calls";
|
2009-11-06 11:59:10 +01:00
|
|
|
sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_DrawCalls);
|
2005-11-19 17:15:34 +01:00
|
|
|
return buf;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
case Row_TerrainTris:
|
|
|
|
if (col == 0)
|
|
|
|
return "# terrain tris";
|
2009-11-06 11:59:10 +01:00
|
|
|
sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_TerrainTris);
|
2005-11-19 17:15:34 +01:00
|
|
|
return buf;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2011-07-13 01:48:05 +02:00
|
|
|
case Row_WaterTris:
|
|
|
|
if (col == 0)
|
|
|
|
return "# water tris";
|
|
|
|
sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_WaterTris);
|
|
|
|
return buf;
|
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
case Row_ModelTris:
|
|
|
|
if (col == 0)
|
|
|
|
return "# model tris";
|
2009-11-06 11:59:10 +01:00
|
|
|
sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_ModelTris);
|
2005-11-19 17:15:34 +01:00
|
|
|
return buf;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2011-07-30 02:56:45 +02:00
|
|
|
case Row_OverlayTris:
|
|
|
|
if (col == 0)
|
|
|
|
return "# overlay tris";
|
|
|
|
sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_OverlayTris);
|
|
|
|
return buf;
|
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
case Row_BlendSplats:
|
|
|
|
if (col == 0)
|
|
|
|
return "# blend splats";
|
2009-11-06 11:59:10 +01:00
|
|
|
sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_BlendSplats);
|
2005-11-19 17:15:34 +01:00
|
|
|
return buf;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2011-04-29 14:26:31 +02:00
|
|
|
case Row_Particles:
|
|
|
|
if (col == 0)
|
|
|
|
return "# particles";
|
|
|
|
sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)Stats.m_Particles);
|
|
|
|
return buf;
|
|
|
|
|
2011-03-13 19:58:09 +01:00
|
|
|
case Row_VBReserved:
|
|
|
|
if (col == 0)
|
2013-11-09 02:03:23 +01:00
|
|
|
return "VB reserved";
|
|
|
|
sprintf_s(buf, sizeof(buf), "%lu kB", (unsigned long)g_VBMan.GetBytesReserved() / 1024);
|
2011-03-13 19:58:09 +01:00
|
|
|
return buf;
|
|
|
|
|
|
|
|
case Row_VBAllocated:
|
|
|
|
if (col == 0)
|
2013-11-09 02:03:23 +01:00
|
|
|
return "VB allocated";
|
|
|
|
sprintf_s(buf, sizeof(buf), "%lu kB", (unsigned long)g_VBMan.GetBytesAllocated() / 1024);
|
|
|
|
return buf;
|
|
|
|
|
|
|
|
case Row_TextureMemory:
|
|
|
|
if (col == 0)
|
|
|
|
return "textures uploaded";
|
|
|
|
sprintf_s(buf, sizeof(buf), "%lu kB", (unsigned long)g_Renderer.GetTextureManager().GetBytesUploaded() / 1024);
|
2011-03-13 19:58:09 +01:00
|
|
|
return buf;
|
|
|
|
|
2012-04-03 20:44:46 +02:00
|
|
|
case Row_ShadersLoaded:
|
|
|
|
if (col == 0)
|
|
|
|
return "shader effects loaded";
|
|
|
|
sprintf_s(buf, sizeof(buf), "%lu", (unsigned long)g_Renderer.GetShaderManager().GetNumEffectsLoaded());
|
|
|
|
return buf;
|
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
default:
|
|
|
|
return "???";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-01 08:59:29 +02:00
|
|
|
AbstractProfileTable* CRendererStatsTable::GetChild(size_t UNUSED(row))
|
2005-11-19 17:15:34 +01:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-01-04 19:13:45 +01:00
|
|
|
} // anonymous namespace
|
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CRenderer implementation
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Struct CRendererInternals: Truly hide data that is supposed to be hidden
|
|
|
|
* in this structure so it won't even appear in header files.
|
|
|
|
*/
|
2022-01-03 12:11:58 +01:00
|
|
|
class CRenderer::Internals
|
2005-11-19 17:15:34 +01:00
|
|
|
{
|
2022-01-03 12:11:58 +01:00
|
|
|
NONCOPYABLE(Internals);
|
2009-01-03 19:40:28 +01:00
|
|
|
public:
|
2006-03-28 21:45:44 +02:00
|
|
|
/// true if CRenderer::Open has been called
|
|
|
|
bool IsOpen;
|
|
|
|
|
2011-03-26 21:17:21 +01:00
|
|
|
/// true if shaders need to be reloaded
|
|
|
|
bool ShadersDirty;
|
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
/// Table to display renderer stats in-game via profile system
|
|
|
|
CRendererStatsTable profileTable;
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2011-03-26 21:17:21 +01:00
|
|
|
/// Shader manager
|
|
|
|
CShaderManager shaderManager;
|
|
|
|
|
2010-09-10 23:02:10 +02:00
|
|
|
/// Texture manager
|
|
|
|
CTextureManager textureManager;
|
|
|
|
|
2012-08-06 21:10:47 +02:00
|
|
|
/// Time manager
|
|
|
|
CTimeManager timeManager;
|
2012-04-03 20:44:46 +02:00
|
|
|
|
2012-10-15 12:34:23 +02:00
|
|
|
/// Postprocessing effect manager
|
|
|
|
CPostprocManager postprocManager;
|
2006-01-22 20:12:30 +01:00
|
|
|
|
2022-01-04 14:29:01 +01:00
|
|
|
CSceneRenderer sceneRenderer;
|
|
|
|
|
2021-04-15 20:07:01 +02:00
|
|
|
CDebugRenderer debugRenderer;
|
|
|
|
|
2013-10-18 17:53:07 +02:00
|
|
|
CFontManager fontManager;
|
|
|
|
|
2022-01-05 15:49:54 +01:00
|
|
|
std::unique_ptr<Renderer::Backend::GL::CDeviceCommandContext> deviceCommandContext;
|
|
|
|
|
2022-01-03 12:11:58 +01:00
|
|
|
Internals() :
|
2011-04-03 21:15:15 +02:00
|
|
|
IsOpen(false), ShadersDirty(true), profileTable(g_Renderer.m_Stats), textureManager(g_VFS, false, false)
|
2005-11-19 17:15:34 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2004-06-07 21:53:58 +02:00
|
|
|
CRenderer::CRenderer()
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
2022-01-04 19:13:45 +01:00
|
|
|
TIMER(L"InitRenderer");
|
|
|
|
|
2022-01-03 12:11:58 +01:00
|
|
|
m = std::make_unique<Internals>();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2005-11-19 17:15:34 +01:00
|
|
|
g_ProfileViewer.AddRootTable(&m->profileTable);
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2012-04-24 00:57:51 +02:00
|
|
|
m_Width = 0;
|
|
|
|
m_Height = 0;
|
2011-04-05 22:32:03 +02:00
|
|
|
|
2011-07-16 21:52:48 +02:00
|
|
|
m_Stats.Reset();
|
2022-01-04 19:13:45 +01:00
|
|
|
|
|
|
|
// Create terrain related stuff.
|
|
|
|
new CTerrainTextureManager;
|
|
|
|
|
|
|
|
Open(g_xres, g_yres);
|
|
|
|
|
|
|
|
// Setup lighting environment. Since the Renderer accesses the
|
|
|
|
// lighting environment through a pointer, this has to be done before
|
|
|
|
// the first Frame.
|
|
|
|
GetSceneRenderer().SetLightEnv(&g_LightEnv);
|
|
|
|
|
|
|
|
// I haven't seen the camera affecting GUI rendering and such, but the
|
|
|
|
// viewport has to be updated according to the video mode
|
|
|
|
SViewPort vp;
|
|
|
|
vp.m_X = 0;
|
|
|
|
vp.m_Y = 0;
|
|
|
|
vp.m_Width = g_xres;
|
|
|
|
vp.m_Height = g_yres;
|
|
|
|
SetViewport(vp);
|
|
|
|
ModelDefActivateFastImpl();
|
|
|
|
ColorActivateFastImpl();
|
|
|
|
ModelRenderer::Init();
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
2004-06-07 21:53:58 +02:00
|
|
|
CRenderer::~CRenderer()
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
2022-01-29 09:22:28 +01:00
|
|
|
delete &g_TexMan;
|
|
|
|
|
2021-09-20 14:55:39 +02:00
|
|
|
// We no longer UnloadWaterTextures here -
|
2005-10-31 19:57:03 +01:00
|
|
|
// that is the responsibility of the module that asked for
|
|
|
|
// them to be loaded (i.e. CGameView).
|
2022-01-03 12:11:58 +01:00
|
|
|
m.reset();
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CRenderer::EnumCaps()
|
|
|
|
{
|
|
|
|
// assume support for nothing
|
2011-03-26 21:17:21 +01:00
|
|
|
m_Caps.m_ARBProgram = false;
|
|
|
|
m_Caps.m_ARBProgramShadow = false;
|
2011-02-03 02:12:24 +01:00
|
|
|
m_Caps.m_VertexShader = false;
|
|
|
|
m_Caps.m_FragmentShader = false;
|
|
|
|
m_Caps.m_Shadows = false;
|
2014-09-27 03:32:03 +02:00
|
|
|
m_Caps.m_PrettyWater = false;
|
2004-05-30 02:46:58 +02:00
|
|
|
|
|
|
|
// now start querying extensions
|
2011-03-26 21:17:21 +01:00
|
|
|
if (0 == ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", NULL))
|
|
|
|
{
|
|
|
|
m_Caps.m_ARBProgram = true;
|
|
|
|
if (ogl_HaveExtension("GL_ARB_fragment_program_shadow"))
|
|
|
|
m_Caps.m_ARBProgramShadow = true;
|
|
|
|
}
|
|
|
|
|
2022-01-06 12:41:04 +01:00
|
|
|
// GLSL shaders are in core since GL2.0.
|
|
|
|
if (ogl_HaveVersion(2, 0))
|
|
|
|
m_Caps.m_VertexShader = m_Caps.m_FragmentShader = true;
|
2006-02-15 01:45:16 +01:00
|
|
|
|
2012-03-19 22:10:14 +01:00
|
|
|
#if CONFIG2_GLES
|
|
|
|
m_Caps.m_Shadows = true;
|
|
|
|
#else
|
2022-01-06 12:41:04 +01:00
|
|
|
if (0 == ogl_HaveExtensions(0, "GL_ARB_shadow", "GL_ARB_depth_texture", NULL))
|
2011-02-03 02:12:24 +01:00
|
|
|
{
|
2006-02-15 01:45:16 +01:00
|
|
|
if (ogl_max_tex_units >= 4)
|
2011-04-07 00:08:51 +02:00
|
|
|
m_Caps.m_Shadows = true;
|
2006-03-26 19:36:33 +02:00
|
|
|
}
|
2012-03-19 22:10:14 +01:00
|
|
|
#endif
|
2014-09-27 03:32:03 +02:00
|
|
|
|
|
|
|
#if CONFIG2_GLES
|
|
|
|
m_Caps.m_PrettyWater = true;
|
|
|
|
#else
|
2022-01-06 12:41:04 +01:00
|
|
|
if (m_Caps.m_VertexShader && m_Caps.m_FragmentShader)
|
2014-09-27 03:32:03 +02:00
|
|
|
m_Caps.m_PrettyWater = true;
|
|
|
|
#endif
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
2011-03-26 21:17:21 +01:00
|
|
|
void CRenderer::ReloadShaders()
|
|
|
|
{
|
2011-04-30 15:01:45 +02:00
|
|
|
ENSURE(m->IsOpen);
|
2011-04-23 20:51:47 +02:00
|
|
|
|
2022-01-04 14:29:01 +01:00
|
|
|
m->sceneRenderer.ReloadShaders();
|
2011-03-26 21:17:21 +01:00
|
|
|
m->ShadersDirty = false;
|
|
|
|
}
|
2005-10-01 00:23:48 +02:00
|
|
|
|
2010-06-03 21:07:59 +02:00
|
|
|
bool CRenderer::Open(int width, int height)
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
2006-03-28 21:45:44 +02:00
|
|
|
m->IsOpen = true;
|
|
|
|
|
2006-03-26 19:36:33 +02:00
|
|
|
// Must query card capabilities before creating renderers that depend
|
|
|
|
// on card capabilities.
|
|
|
|
EnumCaps();
|
2011-03-26 21:17:21 +01:00
|
|
|
|
2006-03-26 19:36:33 +02:00
|
|
|
// Dimensions
|
2004-05-30 02:46:58 +02:00
|
|
|
m_Width = width;
|
|
|
|
m_Height = height;
|
|
|
|
|
2006-03-28 21:45:44 +02:00
|
|
|
// Validate the currently selected render path
|
2019-08-04 10:28:30 +02:00
|
|
|
SetRenderPath(g_RenderingOptions.GetRenderPath());
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2022-01-05 15:49:54 +01:00
|
|
|
m->deviceCommandContext = Renderer::Backend::GL::CDeviceCommandContext::Create();
|
|
|
|
|
2022-01-28 07:34:34 +01:00
|
|
|
if (m->postprocManager.IsEnabled())
|
2012-10-15 12:34:23 +02:00
|
|
|
m->postprocManager.Initialize();
|
2012-04-23 20:55:32 +02:00
|
|
|
|
2022-01-04 14:29:01 +01:00
|
|
|
m->sceneRenderer.Initialize();
|
|
|
|
|
2004-05-30 02:46:58 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-10-05 22:50:10 +02:00
|
|
|
void CRenderer::Resize(int width, int height)
|
2004-05-30 02:46:58 +02:00
|
|
|
{
|
2006-01-07 02:04:26 +01:00
|
|
|
m_Width = width;
|
|
|
|
m_Height = height;
|
2016-11-23 15:09:58 +01:00
|
|
|
|
2014-10-05 22:50:10 +02:00
|
|
|
m->postprocManager.Resize();
|
2016-11-23 15:09:58 +01:00
|
|
|
|
2022-01-04 14:29:01 +01:00
|
|
|
m->sceneRenderer.Resize(width, height);
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
2005-10-05 18:42:09 +02:00
|
|
|
void CRenderer::SetRenderPath(RenderPath rp)
|
|
|
|
{
|
2006-03-28 21:45:44 +02:00
|
|
|
if (!m->IsOpen)
|
|
|
|
{
|
|
|
|
// Delay until Open() is called.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Renderer has been opened, so validate the selected renderpath
|
2019-08-04 10:28:30 +02:00
|
|
|
if (rp == RenderPath::DEFAULT)
|
2005-10-05 18:42:09 +02:00
|
|
|
{
|
2021-12-14 07:34:02 +01:00
|
|
|
if (m_Caps.m_ARBProgram || (m_Caps.m_VertexShader && m_Caps.m_FragmentShader && g_VideoMode.GetBackend() != CVideoMode::Backend::GL_ARB))
|
2019-08-04 10:28:30 +02:00
|
|
|
rp = RenderPath::SHADER;
|
2005-10-25 03:43:07 +02:00
|
|
|
else
|
2019-08-04 10:28:30 +02:00
|
|
|
rp = RenderPath::FIXED;
|
2005-10-25 03:43:07 +02:00
|
|
|
}
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2019-08-04 10:28:30 +02:00
|
|
|
if (rp == RenderPath::SHADER)
|
2011-03-26 21:17:21 +01:00
|
|
|
{
|
2021-12-14 07:34:02 +01:00
|
|
|
if (!(m_Caps.m_ARBProgram || (m_Caps.m_VertexShader && m_Caps.m_FragmentShader && g_VideoMode.GetBackend() != CVideoMode::Backend::GL_ARB)))
|
2011-03-26 21:17:21 +01:00
|
|
|
{
|
2015-01-22 21:31:30 +01:00
|
|
|
LOGWARNING("Falling back to fixed function\n");
|
2019-08-04 10:28:30 +02:00
|
|
|
rp = RenderPath::FIXED;
|
2011-03-26 21:17:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-04 10:28:30 +02:00
|
|
|
// TODO: remove this once capabilities have been properly extracted and the above checks have been moved elsewhere.
|
|
|
|
g_RenderingOptions.m_RenderPath = rp;
|
2011-03-26 21:17:21 +01:00
|
|
|
|
2012-04-03 20:44:46 +02:00
|
|
|
MakeShadersDirty();
|
2005-10-05 18:42:09 +02:00
|
|
|
}
|
|
|
|
|
2022-01-04 19:13:45 +01:00
|
|
|
bool CRenderer::ShouldRender() const
|
|
|
|
{
|
|
|
|
return !g_app_minimized && (g_app_has_focus || !g_VideoMode.IsInFullscreen());
|
|
|
|
}
|
|
|
|
|
2022-01-07 21:15:48 +01:00
|
|
|
void CRenderer::RenderFrame(const bool needsPresent)
|
2022-01-04 19:13:45 +01:00
|
|
|
{
|
|
|
|
// Do not render if not focused while in fullscreen or minimised,
|
|
|
|
// as that triggers a difficult-to-reproduce crash on some graphic cards.
|
|
|
|
if (!ShouldRender())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (m_ShouldPreloadResourcesBeforeNextFrame)
|
|
|
|
{
|
|
|
|
m_ShouldPreloadResourcesBeforeNextFrame = false;
|
|
|
|
// We don't meed to render logger for the preload.
|
|
|
|
RenderFrameImpl(true, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_ScreenShotType == ScreenShotType::BIG)
|
|
|
|
{
|
2022-01-07 21:15:48 +01:00
|
|
|
RenderBigScreenShot(needsPresent);
|
2022-01-04 19:13:45 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (m_ScreenShotType == ScreenShotType::DEFAULT)
|
|
|
|
RenderScreenShot();
|
|
|
|
else
|
|
|
|
RenderFrameImpl(true, true);
|
|
|
|
|
2022-01-19 18:28:47 +01:00
|
|
|
m->deviceCommandContext->Flush();
|
2022-01-04 19:13:45 +01:00
|
|
|
if (needsPresent)
|
|
|
|
g_VideoMode.GetBackendDevice()->Present();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-07 21:15:48 +01:00
|
|
|
void CRenderer::RenderFrameImpl(const bool renderGUI, const bool renderLogger)
|
2022-01-04 19:13:45 +01:00
|
|
|
{
|
|
|
|
PROFILE3("render");
|
|
|
|
|
|
|
|
g_Profiler2.RecordGPUFrameStart();
|
|
|
|
ogl_WarnIfError();
|
|
|
|
|
2022-01-07 15:33:54 +01:00
|
|
|
g_TexMan.UploadResourcesIfNeeded(m->deviceCommandContext.get());
|
|
|
|
|
2022-01-04 19:13:45 +01:00
|
|
|
// prepare before starting the renderer frame
|
|
|
|
if (g_Game && g_Game->IsGameStarted())
|
|
|
|
g_Game->GetView()->BeginFrame();
|
|
|
|
|
|
|
|
if (g_Game)
|
|
|
|
m->sceneRenderer.SetSimulation(g_Game->GetSimulation2());
|
|
|
|
|
|
|
|
// start new frame
|
|
|
|
BeginFrame();
|
|
|
|
|
|
|
|
ogl_WarnIfError();
|
|
|
|
|
|
|
|
if (g_Game && g_Game->IsGameStarted())
|
|
|
|
{
|
|
|
|
g_Game->GetView()->Render();
|
|
|
|
ogl_WarnIfError();
|
|
|
|
}
|
|
|
|
|
|
|
|
m->sceneRenderer.RenderTextOverlays();
|
|
|
|
|
|
|
|
// If we're in Atlas game view, render special tools
|
|
|
|
if (g_AtlasGameLoop && g_AtlasGameLoop->view)
|
|
|
|
{
|
|
|
|
g_AtlasGameLoop->view->DrawCinemaPathTool();
|
|
|
|
ogl_WarnIfError();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_Game && g_Game->IsGameStarted())
|
|
|
|
{
|
|
|
|
g_Game->GetView()->GetCinema()->Render();
|
|
|
|
ogl_WarnIfError();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (renderGUI)
|
|
|
|
{
|
|
|
|
OGL_SCOPED_DEBUG_GROUP("Draw GUI");
|
|
|
|
// All GUI elements are drawn in Z order to render semi-transparent
|
|
|
|
// objects correctly.
|
|
|
|
g_GUI->Draw();
|
|
|
|
ogl_WarnIfError();
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we're in Atlas game view, render special overlays (e.g. editor bandbox).
|
|
|
|
if (g_AtlasGameLoop && g_AtlasGameLoop->view)
|
|
|
|
{
|
|
|
|
CCanvas2D canvas;
|
|
|
|
g_AtlasGameLoop->view->DrawOverlays(canvas);
|
|
|
|
ogl_WarnIfError();
|
|
|
|
}
|
|
|
|
|
|
|
|
g_Console->Render();
|
|
|
|
ogl_WarnIfError();
|
|
|
|
|
|
|
|
if (renderLogger)
|
|
|
|
{
|
|
|
|
g_Logger->Render();
|
|
|
|
ogl_WarnIfError();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Profile information
|
|
|
|
g_ProfileViewer.RenderProfile();
|
|
|
|
ogl_WarnIfError();
|
|
|
|
|
|
|
|
EndFrame();
|
|
|
|
|
|
|
|
const Stats& stats = GetStats();
|
|
|
|
PROFILE2_ATTR("draw calls: %zu", stats.m_DrawCalls);
|
|
|
|
PROFILE2_ATTR("terrain tris: %zu", stats.m_TerrainTris);
|
|
|
|
PROFILE2_ATTR("water tris: %zu", stats.m_WaterTris);
|
|
|
|
PROFILE2_ATTR("model tris: %zu", stats.m_ModelTris);
|
|
|
|
PROFILE2_ATTR("overlay tris: %zu", stats.m_OverlayTris);
|
|
|
|
PROFILE2_ATTR("blend splats: %zu", stats.m_BlendSplats);
|
|
|
|
PROFILE2_ATTR("particles: %zu", stats.m_Particles);
|
|
|
|
|
|
|
|
ogl_WarnIfError();
|
|
|
|
|
|
|
|
g_Profiler2.RecordGPUFrameEnd();
|
|
|
|
ogl_WarnIfError();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRenderer::RenderScreenShot()
|
|
|
|
{
|
|
|
|
m_ScreenShotType = ScreenShotType::NONE;
|
|
|
|
|
|
|
|
// get next available numbered filename
|
|
|
|
// note: %04d -> always 4 digits, so sorting by filename works correctly.
|
|
|
|
const VfsPath filenameFormat(L"screenshots/screenshot%04d.png");
|
|
|
|
VfsPath filename;
|
|
|
|
vfs::NextNumberedFilename(g_VFS, filenameFormat, g_NextScreenShotNumber, filename);
|
|
|
|
|
|
|
|
const size_t w = (size_t)g_xres, h = (size_t)g_yres;
|
|
|
|
const size_t bpp = 24;
|
|
|
|
GLenum fmt = GL_RGB;
|
|
|
|
int flags = TEX_BOTTOM_UP;
|
|
|
|
|
|
|
|
// Hide log messages and re-render
|
|
|
|
RenderFrameImpl(true, false);
|
|
|
|
|
|
|
|
const size_t img_size = w * h * bpp / 8;
|
|
|
|
const size_t hdr_size = tex_hdr_size(filename);
|
|
|
|
std::shared_ptr<u8> buf;
|
|
|
|
AllocateAligned(buf, hdr_size + img_size, maxSectorSize);
|
|
|
|
GLvoid* img = buf.get() + hdr_size;
|
|
|
|
Tex t;
|
|
|
|
if (t.wrap(w, h, bpp, flags, buf, hdr_size) < 0)
|
|
|
|
return;
|
|
|
|
glReadPixels(0, 0, (GLsizei)w, (GLsizei)h, fmt, GL_UNSIGNED_BYTE, img);
|
|
|
|
|
|
|
|
if (tex_write(&t, filename) == INFO::OK)
|
|
|
|
{
|
|
|
|
OsPath realPath;
|
|
|
|
g_VFS->GetRealPath(filename, realPath);
|
|
|
|
|
|
|
|
LOGMESSAGERENDER(g_L10n.Translate("Screenshot written to '%s'"), realPath.string8());
|
|
|
|
|
|
|
|
debug_printf(
|
|
|
|
CStr(g_L10n.Translate("Screenshot written to '%s'") + "\n").c_str(),
|
|
|
|
realPath.string8().c_str());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
LOGERROR("Error writing screenshot to '%s'", filename.string8());
|
|
|
|
}
|
|
|
|
|
2022-01-07 21:15:48 +01:00
|
|
|
void CRenderer::RenderBigScreenShot(const bool needsPresent)
|
2022-01-04 19:13:45 +01:00
|
|
|
{
|
|
|
|
m_ScreenShotType = ScreenShotType::NONE;
|
|
|
|
|
|
|
|
// If the game hasn't started yet then use WriteScreenshot to generate the image.
|
|
|
|
if (!g_Game)
|
|
|
|
return RenderScreenShot();
|
|
|
|
|
|
|
|
int tiles = 4, tileWidth = 256, tileHeight = 256;
|
|
|
|
CFG_GET_VAL("screenshot.tiles", tiles);
|
|
|
|
CFG_GET_VAL("screenshot.tilewidth", tileWidth);
|
|
|
|
CFG_GET_VAL("screenshot.tileheight", tileHeight);
|
|
|
|
if (tiles <= 0 || tileWidth <= 0 || tileHeight <= 0 || tileWidth * tiles % 4 != 0 || tileHeight * tiles % 4 != 0)
|
|
|
|
{
|
|
|
|
LOGWARNING("Invalid big screenshot size: tiles=%d tileWidth=%d tileHeight=%d", tiles, tileWidth, tileHeight);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get next available numbered filename
|
|
|
|
// note: %04d -> always 4 digits, so sorting by filename works correctly.
|
|
|
|
const VfsPath filenameFormat(L"screenshots/screenshot%04d.bmp");
|
|
|
|
VfsPath filename;
|
|
|
|
vfs::NextNumberedFilename(g_VFS, filenameFormat, g_NextScreenShotNumber, filename);
|
|
|
|
|
|
|
|
// Slightly ugly and inflexible: Always draw 640*480 tiles onto the screen, and
|
|
|
|
// hope the screen is actually large enough for that.
|
|
|
|
ENSURE(g_xres >= tileWidth && g_yres >= tileHeight);
|
|
|
|
|
2022-01-07 21:15:48 +01:00
|
|
|
const int imageWidth = tileWidth * tiles, imageHeight = tileHeight * tiles;
|
2022-01-04 19:13:45 +01:00
|
|
|
const int bpp = 24;
|
|
|
|
// we want writing BMP to be as fast as possible,
|
|
|
|
// so read data from OpenGL in BMP format to obviate conversion.
|
|
|
|
#if CONFIG2_GLES // GLES doesn't support BGR
|
|
|
|
const GLenum fmt = GL_RGB;
|
|
|
|
const int flags = TEX_BOTTOM_UP;
|
|
|
|
#else
|
|
|
|
const GLenum fmt = GL_BGR;
|
|
|
|
const int flags = TEX_BOTTOM_UP | TEX_BGR;
|
|
|
|
#endif
|
|
|
|
|
2022-01-07 21:15:48 +01:00
|
|
|
const size_t imageSize = imageWidth * imageHeight * bpp / 8;
|
|
|
|
const size_t tileSize = tileWidth * tileHeight * bpp / 8;
|
|
|
|
const size_t headerSize = tex_hdr_size(filename);
|
|
|
|
void* tileData = malloc(tileSize);
|
|
|
|
if (!tileData)
|
2022-01-04 19:13:45 +01:00
|
|
|
{
|
|
|
|
WARN_IF_ERR(ERR::NO_MEM);
|
|
|
|
return;
|
|
|
|
}
|
2022-01-07 21:15:48 +01:00
|
|
|
std::shared_ptr<u8> imageBuffer;
|
|
|
|
AllocateAligned(imageBuffer, headerSize + imageSize, maxSectorSize);
|
2022-01-04 19:13:45 +01:00
|
|
|
|
|
|
|
Tex t;
|
2022-01-07 21:15:48 +01:00
|
|
|
GLvoid* img = imageBuffer.get() + headerSize;
|
|
|
|
if (t.wrap(imageWidth, imageHeight, bpp, flags, imageBuffer, headerSize) < 0)
|
2022-01-04 19:13:45 +01:00
|
|
|
{
|
2022-01-07 21:15:48 +01:00
|
|
|
free(tileData);
|
2022-01-04 19:13:45 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogl_WarnIfError();
|
|
|
|
|
|
|
|
CCamera oldCamera = *g_Game->GetView()->GetCamera();
|
|
|
|
|
|
|
|
// Resize various things so that the sizes and aspect ratios are correct
|
|
|
|
{
|
|
|
|
g_Renderer.Resize(tileWidth, tileHeight);
|
|
|
|
SViewPort vp = { 0, 0, tileWidth, tileHeight };
|
|
|
|
g_Game->GetView()->SetViewport(vp);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Render each tile
|
|
|
|
CMatrix3D projection;
|
|
|
|
projection.SetIdentity();
|
|
|
|
const float aspectRatio = 1.0f * tileWidth / tileHeight;
|
2022-01-07 21:15:48 +01:00
|
|
|
for (int tileY = 0; tileY < tiles; ++tileY)
|
2022-01-04 19:13:45 +01:00
|
|
|
{
|
2022-01-07 21:15:48 +01:00
|
|
|
for (int tileX = 0; tileX < tiles; ++tileX)
|
2022-01-04 19:13:45 +01:00
|
|
|
{
|
|
|
|
// Adjust the camera to render the appropriate region
|
|
|
|
if (oldCamera.GetProjectionType() == CCamera::ProjectionType::PERSPECTIVE)
|
|
|
|
{
|
2022-01-07 21:15:48 +01:00
|
|
|
projection.SetPerspectiveTile(oldCamera.GetFOV(), aspectRatio, oldCamera.GetNearPlane(), oldCamera.GetFarPlane(), tiles, tileX, tileY);
|
2022-01-04 19:13:45 +01:00
|
|
|
}
|
|
|
|
g_Game->GetView()->GetCamera()->SetProjection(projection);
|
|
|
|
|
|
|
|
RenderFrameImpl(false, false);
|
|
|
|
|
|
|
|
// Copy the tile pixels into the main image
|
2022-01-07 21:15:48 +01:00
|
|
|
glReadPixels(0, 0, tileWidth, tileHeight, fmt, GL_UNSIGNED_BYTE, tileData);
|
2022-01-04 19:13:45 +01:00
|
|
|
for (int y = 0; y < tileHeight; ++y)
|
|
|
|
{
|
2022-01-07 21:15:48 +01:00
|
|
|
void* dest = static_cast<char*>(img) + ((tileY * tileHeight + y) * imageWidth + (tileX * tileWidth)) * bpp / 8;
|
|
|
|
void* src = static_cast<char*>(tileData) + y * tileWidth * bpp / 8;
|
2022-01-04 19:13:45 +01:00
|
|
|
memcpy(dest, src, tileWidth * bpp / 8);
|
|
|
|
}
|
2022-01-19 18:28:47 +01:00
|
|
|
|
|
|
|
m->deviceCommandContext->Flush();
|
2022-01-07 21:15:48 +01:00
|
|
|
if (needsPresent)
|
|
|
|
g_VideoMode.GetBackendDevice()->Present();
|
2022-01-04 19:13:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Restore the viewport settings
|
|
|
|
{
|
|
|
|
g_Renderer.Resize(g_xres, g_yres);
|
|
|
|
SViewPort vp = { 0, 0, g_xres, g_yres };
|
|
|
|
g_Game->GetView()->SetViewport(vp);
|
|
|
|
g_Game->GetView()->GetCamera()->SetProjectionFromCamera(oldCamera);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tex_write(&t, filename) == INFO::OK)
|
|
|
|
{
|
|
|
|
OsPath realPath;
|
|
|
|
g_VFS->GetRealPath(filename, realPath);
|
|
|
|
|
|
|
|
LOGMESSAGERENDER(g_L10n.Translate("Screenshot written to '%s'"), realPath.string8());
|
|
|
|
|
|
|
|
debug_printf(
|
|
|
|
CStr(g_L10n.Translate("Screenshot written to '%s'") + "\n").c_str(),
|
|
|
|
realPath.string8().c_str());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
LOGERROR("Error writing screenshot to '%s'", filename.string8());
|
|
|
|
|
2022-01-07 21:15:48 +01:00
|
|
|
free(tileData);
|
2022-01-04 19:13:45 +01:00
|
|
|
}
|
|
|
|
|
2004-05-30 02:46:58 +02:00
|
|
|
void CRenderer::BeginFrame()
|
|
|
|
{
|
2011-03-03 23:38:01 +01:00
|
|
|
PROFILE("begin frame");
|
|
|
|
|
2022-01-04 14:29:01 +01:00
|
|
|
// Zero out all the per-frame stats.
|
2004-05-30 02:46:58 +02:00
|
|
|
m_Stats.Reset();
|
2006-01-07 02:04:26 +01:00
|
|
|
|
2012-04-03 20:44:46 +02:00
|
|
|
if (m->ShadersDirty)
|
|
|
|
ReloadShaders();
|
2016-11-23 15:09:58 +01:00
|
|
|
|
2022-01-04 14:29:01 +01:00
|
|
|
m->sceneRenderer.BeginFrame();
|
2011-01-29 17:31:48 +01:00
|
|
|
}
|
2010-10-02 14:41:29 +02:00
|
|
|
|
2011-01-29 17:31:48 +01:00
|
|
|
void CRenderer::EndFrame()
|
|
|
|
{
|
2011-11-04 02:35:50 +01:00
|
|
|
PROFILE3("end frame");
|
2011-03-03 23:38:01 +01:00
|
|
|
|
2022-01-04 14:29:01 +01:00
|
|
|
m->sceneRenderer.EndFrame();
|
2004-05-30 02:46:58 +02:00
|
|
|
|
2022-01-07 00:23:36 +01:00
|
|
|
BindTexture(0, 0);
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
2004-08-05 15:07:51 +02:00
|
|
|
void CRenderer::SetViewport(const SViewPort &vp)
|
|
|
|
{
|
2013-11-28 01:57:39 +01:00
|
|
|
m_Viewport = vp;
|
had to remove uint and ulong from lib/types.h due to conflict with other library.
this snowballed into a massive search+destroy of the hodgepodge of
mostly equivalent types we had in use (int, uint, unsigned, unsigned
int, i32, u32, ulong, uintN).
it is more efficient to use 64-bit types in 64-bit mode, so the
preferred default is size_t (for anything remotely resembling a size or
index). tile coordinates are ssize_t to allow more efficient conversion
to/from floating point. flags are int because we almost never need more
than 15 distinct bits, bit test/set is not slower and int is fastest to
type. finally, some data that is pretty much directly passed to OpenGL
is now typed accordingly.
after several hours, the code now requires fewer casts and less
guesswork.
other changes:
- unit and player IDs now have an "invalid id" constant in the
respective class to avoid casting and -1
- fix some endian/64-bit bugs in the map (un)packing. added a
convenience function to write/read a size_t.
- ia32: change CPUID interface to allow passing in ecx (required for
cache topology detection, which I need at work). remove some unneeded
functions from asm, replace with intrinsics where possible.
This was SVN commit r5942.
2008-05-11 20:48:32 +02:00
|
|
|
glViewport((GLint)vp.m_X,(GLint)vp.m_Y,(GLsizei)vp.m_Width,(GLsizei)vp.m_Height);
|
2004-08-05 15:07:51 +02:00
|
|
|
}
|
|
|
|
|
2013-11-28 01:57:39 +01:00
|
|
|
SViewPort CRenderer::GetViewport()
|
|
|
|
{
|
|
|
|
return m_Viewport;
|
|
|
|
}
|
|
|
|
|
2012-03-19 22:10:14 +01:00
|
|
|
void CRenderer::BindTexture(int unit, GLuint tex)
|
2004-06-11 00:24:03 +02:00
|
|
|
{
|
2021-12-21 23:03:31 +01:00
|
|
|
glActiveTextureARB(GL_TEXTURE0+unit);
|
2004-06-11 00:24:03 +02:00
|
|
|
|
2012-03-19 22:10:14 +01:00
|
|
|
glBindTexture(GL_TEXTURE_2D, tex);
|
2004-05-30 02:46:58 +02:00
|
|
|
}
|
|
|
|
|
2011-03-26 21:17:21 +01:00
|
|
|
void CRenderer::MakeShadersDirty()
|
|
|
|
{
|
|
|
|
m->ShadersDirty = true;
|
2022-01-04 14:29:01 +01:00
|
|
|
m->sceneRenderer.MakeShadersDirty();
|
2011-03-26 21:17:21 +01:00
|
|
|
}
|
|
|
|
|
2010-09-10 23:02:10 +02:00
|
|
|
CTextureManager& CRenderer::GetTextureManager()
|
|
|
|
{
|
|
|
|
return m->textureManager;
|
|
|
|
}
|
2011-03-26 21:17:21 +01:00
|
|
|
|
|
|
|
CShaderManager& CRenderer::GetShaderManager()
|
|
|
|
{
|
|
|
|
return m->shaderManager;
|
|
|
|
}
|
2011-04-03 21:15:15 +02:00
|
|
|
|
2012-08-06 21:10:47 +02:00
|
|
|
CTimeManager& CRenderer::GetTimeManager()
|
|
|
|
{
|
|
|
|
return m->timeManager;
|
|
|
|
}
|
|
|
|
|
2022-01-04 14:29:01 +01:00
|
|
|
CPostprocManager& CRenderer::GetPostprocManager()
|
2012-04-03 20:44:46 +02:00
|
|
|
{
|
2022-01-04 14:29:01 +01:00
|
|
|
return m->postprocManager;
|
2012-04-03 20:44:46 +02:00
|
|
|
}
|
2012-10-15 12:34:23 +02:00
|
|
|
|
2022-01-04 14:29:01 +01:00
|
|
|
CSceneRenderer& CRenderer::GetSceneRenderer()
|
2012-10-15 12:34:23 +02:00
|
|
|
{
|
2022-01-04 14:29:01 +01:00
|
|
|
return m->sceneRenderer;
|
2013-10-18 17:53:07 +02:00
|
|
|
}
|
|
|
|
|
2021-04-15 20:07:01 +02:00
|
|
|
CDebugRenderer& CRenderer::GetDebugRenderer()
|
|
|
|
{
|
|
|
|
return m->debugRenderer;
|
|
|
|
}
|
|
|
|
|
2013-10-18 17:53:07 +02:00
|
|
|
CFontManager& CRenderer::GetFontManager()
|
|
|
|
{
|
|
|
|
return m->fontManager;
|
|
|
|
}
|
2022-01-04 19:13:45 +01:00
|
|
|
|
|
|
|
void CRenderer::PreloadResourcesBeforeNextFrame()
|
|
|
|
{
|
|
|
|
m_ShouldPreloadResourcesBeforeNextFrame = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRenderer::MakeScreenShotOnNextFrame(ScreenShotType screenShotType)
|
|
|
|
{
|
|
|
|
m_ScreenShotType = screenShotType;
|
|
|
|
}
|
2022-01-05 15:49:54 +01:00
|
|
|
|
|
|
|
Renderer::Backend::GL::CDeviceCommandContext* CRenderer::GetDeviceCommandContext()
|
|
|
|
{
|
|
|
|
return m->deviceCommandContext.get();
|
|
|
|
}
|