110 lines
3.3 KiB
C++
110 lines
3.3 KiB
C++
#include "Renderer.h"
|
|
|
|
#include "GL/glew.h"
|
|
#include "GL\wglew.h"
|
|
#include "glm/glm.hpp"
|
|
|
|
#include "Application.h"
|
|
#include "Utility.h"
|
|
|
|
namespace nf {
|
|
Renderer::Renderer(Application* app) {
|
|
m_app = app;
|
|
m_hdc = GetDC(m_app->getWindow());
|
|
PIXELFORMATDESCRIPTOR pfd = {
|
|
sizeof(PIXELFORMATDESCRIPTOR),
|
|
1,
|
|
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //Flags
|
|
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
|
|
32, // Colordepth of the framebuffer.
|
|
0, 0, 0, 0, 0, 0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, 0, 0, 0,
|
|
24, // Number of bits for the depthbuffer
|
|
8, // Number of bits for the stencilbuffer
|
|
0, // Number of Aux buffers in the framebuffer.
|
|
PFD_MAIN_PLANE,
|
|
0,
|
|
0, 0, 0
|
|
};
|
|
int pf = ChoosePixelFormat(m_hdc, &pfd);
|
|
SetPixelFormat(m_hdc, pf, &pfd);
|
|
m_hglrc = wglCreateContext(m_hdc);
|
|
wglMakeCurrent(m_hdc, m_hglrc);
|
|
glewExperimental = GL_TRUE;
|
|
if (glewInit() != GLEW_OK)
|
|
Error("Could not initialize GLEW!");
|
|
const int attrib[] = {
|
|
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
|
|
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
|
|
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
|
0, 0
|
|
};
|
|
wglDeleteContext(m_hglrc);
|
|
m_hglrc = wglCreateContextAttribsARB(m_hdc, NULL, attrib);
|
|
wglMakeCurrent(m_hdc, m_hglrc);
|
|
wglSwapIntervalEXT(0);
|
|
Log("OpenGL version: " + std::string((char*)glGetString(GL_VERSION)));
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_LESS);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_CULL_FACE);
|
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
baseAP.load("base.nfpack");
|
|
const char* defaultVertex = baseAP["defaultVertex.shader"]->data;
|
|
const char* defaultFragment = baseAP["defaultFragment.shader"]->data;
|
|
m_defaultShader = new Shader(defaultVertex, defaultFragment);
|
|
|
|
BaseAssets::cube = (AModel*)baseAP["cube.obj"];
|
|
BaseAssets::plane = (AModel*)baseAP["plane.obj"];
|
|
BaseAssets::sphere = (AModel*)baseAP["sphere.obj"];
|
|
BaseAssets::cone = (AModel*)baseAP["cone.obj"];
|
|
BaseAssets::cylinder = (AModel*)baseAP["cylinder.obj"];
|
|
BaseAssets::torus = (AModel*)baseAP["torus.obj"];
|
|
}
|
|
|
|
void Renderer::render(Entity& in) {
|
|
if (&in == nullptr)
|
|
Error("Tried to render Entity before being created!");
|
|
m_lGame.push_back(&in);
|
|
//TODO: Sort transparent objects by distance; Farthest first
|
|
}
|
|
|
|
void Renderer::doFrame(Camera* camera) {
|
|
glViewport(0, 0, m_app->getConfig().width, m_app->getConfig().height);
|
|
glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)m_app->getConfig().width / (float)m_app->getConfig().height, 0.1f, 100000.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
for (Entity* draw : m_lGame) {
|
|
Entity& curr = *draw;
|
|
curr.bind(m_defaultShader);
|
|
m_defaultShader->setUniform("proj", proj);
|
|
camera->bind(m_defaultShader);
|
|
//TODO: Clean this up a bit
|
|
glDrawElements(GL_TRIANGLES, curr.getModel()->getIndexCount(), GL_UNSIGNED_INT, nullptr);
|
|
}
|
|
m_lGame.clear();
|
|
|
|
for (Drawable* draw : m_lUI) {
|
|
Drawable& curr = *draw;
|
|
|
|
}
|
|
m_lUI.clear();
|
|
|
|
SwapBuffers(m_hdc);
|
|
|
|
GLenum err = glGetError();
|
|
if (err != GL_NO_ERROR)
|
|
Error("OpenGL error " + std::to_string(err));
|
|
}
|
|
|
|
Renderer::~Renderer() {
|
|
ReleaseDC(m_app->getWindow(), m_hdc);
|
|
wglMakeCurrent(NULL, NULL);
|
|
wglDeleteContext(m_hglrc);
|
|
}
|
|
} |