266 lines
6.7 KiB
C++
266 lines
6.7 KiB
C++
#include "core.h"
|
|
#include "log.h"
|
|
#include "render.h"
|
|
#include "renderdevice.h"
|
|
#include "texturesmanager.h"
|
|
#include "shadersystem.h"
|
|
#include "modelsystem.h"
|
|
#include "debugrender.h"
|
|
#include "ifilesystem.h"
|
|
|
|
#include <pugixml.hpp>
|
|
|
|
static GLuint g_VAO = 0;
|
|
|
|
// TEMP
|
|
glm::vec3 g_viewOrigin;
|
|
glm::vec3 g_viewOrient;
|
|
|
|
#ifdef GL_DEBUG_OUTPUT
|
|
#define GL_DEBUG_OUTPUT 0x92E0
|
|
#endif // GL_DEBUG_OUTPUT
|
|
|
|
#ifndef GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
|
|
#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
|
|
#endif // !GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
|
|
|
|
#ifndef GL_DEBUG_TYPE_ERROR_ARB
|
|
#define GL_DEBUG_TYPE_ERROR_ARB 0x824C
|
|
#endif // !GL_DEBUG_TYPE_ERROR_ARB
|
|
|
|
#ifndef GL_ARB_debug_output
|
|
#define GL_ARB_debug_output 1
|
|
typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled);
|
|
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
|
|
typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf);
|
|
PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB;
|
|
typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC)(GLDEBUGPROCARB callback, const void* userParam);
|
|
PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
|
|
typedef GLuint(APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC)(GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog);
|
|
PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB;
|
|
#endif
|
|
|
|
void APIENTRY GL_DebugOutput(GLenum source,
|
|
GLenum type,
|
|
unsigned int id,
|
|
GLenum severity,
|
|
GLsizei length,
|
|
const char* message,
|
|
const void* userParam)
|
|
{
|
|
// Nvidia spam too much about filenameBuffer mapping
|
|
if (type == 0x8251)
|
|
return;
|
|
|
|
Msg("OpenGL: %stype = 0x%x, severity = 0x%x, message = %s\n",
|
|
(type == GL_DEBUG_TYPE_ERROR_ARB ? "** GL ERROR ** " : ""),
|
|
type, severity, message);
|
|
|
|
if (type == GL_DEBUG_TYPE_ERROR_ARB)
|
|
{
|
|
bool debug = true;
|
|
}
|
|
}
|
|
|
|
Render* g_pRender = nullptr;
|
|
|
|
Render::Render() :
|
|
m_pWindow(nullptr),
|
|
m_pGLContext(nullptr),
|
|
m_pStretchedPicVBuf(nullptr),
|
|
m_sceneModel(nullptr),
|
|
m_bUsingVAO(false)
|
|
{
|
|
m_ViewMatrix = glm::identity<glm::mat4>();
|
|
m_ProjectionMatrix = glm::identity<glm::mat4>();
|
|
}
|
|
|
|
Render::~Render()
|
|
{
|
|
}
|
|
|
|
void Render::Init(SDL_Window* pWindow)
|
|
{
|
|
m_pWindow = pWindow;
|
|
SDL_assert(m_pWindow);
|
|
|
|
// Create OpenGL context
|
|
m_pGLContext = SDL_GL_CreateContext(m_pWindow);
|
|
SDL_GL_MakeCurrent(m_pWindow, m_pGLContext);
|
|
|
|
gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress);
|
|
|
|
if (GLVersion.major == 0 || GLVersion.minor == 0)
|
|
{
|
|
Core::Error("Failed to load OpenGL");
|
|
}
|
|
|
|
// Core profile probably, should use VAO
|
|
if (GLVersion.major >= 3 && GLVersion.minor >= 1)
|
|
m_bUsingVAO = true;
|
|
|
|
Msg("%s", (const char*)glGetString(GL_VENDOR));
|
|
Msg("%s", (const char*)glGetString(GL_RENDERER));
|
|
Msg("OpenGL ver. %s", (const char*)glGetString(GL_VERSION));
|
|
Msg("Context created with OpenGL version %d.%d", GLVersion.major, GLVersion.minor);
|
|
|
|
// Reset OpenGL error stack
|
|
glGetError();
|
|
|
|
// Load extension
|
|
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)SDL_GL_GetProcAddress("glDebugMessageCallbackARB");
|
|
|
|
// Enable debug output
|
|
if (glDebugMessageCallbackARB)
|
|
{
|
|
Msg("...found GL_ARB_debug_output");
|
|
|
|
//glEnable(GL_DEBUG_OUTPUT);
|
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
|
glDebugMessageCallbackARB(GL_DebugOutput, NULL);
|
|
}
|
|
|
|
|
|
// Create render device
|
|
g_pRenderDevice = new RenderDevice();
|
|
|
|
// Create texture manager
|
|
g_pTexturesManager = new TexturesManager();
|
|
g_pTexturesManager->Init();
|
|
|
|
// Create shader system
|
|
g_pShaderSystem = new ShaderSystem();
|
|
g_pShaderSystem->Init();
|
|
|
|
// Create model system
|
|
g_pModelSystem = new ModelSystem();
|
|
|
|
// Create debug render
|
|
g_pDebugRender = new DebugRender();
|
|
g_pDebugRender->Initialize();
|
|
|
|
// Create stretched picture filenameBuffer
|
|
m_pStretchedPicVBuf = g_pRenderDevice->CreateVertexBuffer(nullptr, MAX_STRETCH_VX, true);
|
|
|
|
// Core profile require Vertex Array Object to render
|
|
if (m_bUsingVAO)
|
|
{
|
|
// Create global vertex array
|
|
glGenVertexArrays(1, &g_VAO);
|
|
glBindVertexArray(g_VAO);
|
|
}
|
|
}
|
|
|
|
void Render::Shutdown()
|
|
{
|
|
if (m_bUsingVAO)
|
|
{
|
|
glBindVertexArray(0);
|
|
glDeleteVertexArrays(1, &g_VAO);
|
|
}
|
|
|
|
delete m_pStretchedPicVBuf;
|
|
m_pStretchedPicVBuf = nullptr;
|
|
|
|
g_pDebugRender->Shutdown();
|
|
delete g_pDebugRender;
|
|
g_pDebugRender = nullptr;
|
|
|
|
g_pModelSystem->Shutdown();
|
|
delete g_pModelSystem;
|
|
g_pModelSystem = nullptr;
|
|
|
|
g_pShaderSystem->Shutdown();
|
|
delete g_pShaderSystem;
|
|
g_pShaderSystem = nullptr;
|
|
|
|
g_pTexturesManager->Shutdown();
|
|
delete g_pTexturesManager;
|
|
g_pTexturesManager = nullptr;
|
|
|
|
delete g_pRenderDevice;
|
|
g_pRenderDevice = nullptr;
|
|
|
|
// Destroy OpenGL context
|
|
SDL_GL_MakeCurrent(nullptr, nullptr);
|
|
SDL_GL_DestroyContext(m_pGLContext);
|
|
m_pGLContext = nullptr;
|
|
}
|
|
|
|
void Render::RenderScene()
|
|
{
|
|
if (m_sceneModel) {
|
|
static glm::mat4 s_identity = glm::mat4(1.0f);
|
|
m_sceneModel->Draw(s_identity);
|
|
}
|
|
|
|
g_pDebugRender->RenderFrame();
|
|
}
|
|
|
|
void Render::Present(bool vsync)
|
|
{
|
|
SDL_GL_SwapWindow(m_pWindow);
|
|
}
|
|
|
|
void Render::ResetStates()
|
|
{
|
|
g_pRenderDevice->SetDepthTest(true);
|
|
g_pRenderDevice->SetDepthWrite(true);
|
|
g_pRenderDevice->SetStencilTest(false);
|
|
g_pRenderDevice->SetScissorTest(false);
|
|
g_pRenderDevice->SetCullFace(false);
|
|
g_pRenderDevice->SetBlending(false);
|
|
}
|
|
|
|
void Render::SetViewMatrix(const glm::mat4& matView)
|
|
{
|
|
m_ViewMatrix = matView;
|
|
}
|
|
|
|
void Render::SetProjectionMatrix(const glm::mat4& matProjection)
|
|
{
|
|
m_ProjectionMatrix = matProjection;
|
|
}
|
|
|
|
void Render::LoadSceneXML(const char* filename)
|
|
{
|
|
char filenameBuffer[kMaxPathLength];
|
|
snprintf(filenameBuffer, kMaxPathLength, "data/levels/%s/%s.xml", filename, filename);
|
|
|
|
FileHandle_t file = GetFileSystem()->OpenFile(filenameBuffer, "rb");
|
|
SDL_assert_always(file != kInvalidFileHandleValue);
|
|
|
|
size_t length = GetFileSystem()->GetFileLength(file);
|
|
|
|
char* filedata = new char[length + 1];
|
|
GetFileSystem()->ReadFile(file, filedata, length);
|
|
filedata[length] = '\0';
|
|
|
|
GetFileSystem()->CloseFile(file);
|
|
|
|
pugi::xml_document doc;
|
|
pugi::xml_parse_result result = doc.load_buffer(filedata, length);
|
|
delete[] filedata;
|
|
if (!result) {
|
|
Core::Error("Render::LoadSceneXML: Error while reading level description file '%s'\nError: %s:%i",
|
|
filenameBuffer, result.description(), result.offset);
|
|
}
|
|
|
|
pugi::xml_node root = doc.document_element();
|
|
const char* scenefilename = root.child("SceneFile").attribute("filename").value();
|
|
|
|
sprintf(filenameBuffer, "data/levels/%s/%s", filename, scenefilename);
|
|
|
|
if (!GetFileSystem()->IsExist(filenameBuffer)) {
|
|
Core::Error("SceneManager::LoadScene: scene file '%s' doesnt exist", scenefilename);
|
|
}
|
|
|
|
m_sceneFilename = filenameBuffer;
|
|
|
|
m_sceneModel = g_pModelSystem->LoadModel(m_sceneFilename.c_str());
|
|
}
|
|
|
|
//IRender* GetRender()
|
|
//{
|
|
// return g_pRender;
|
|
//}
|