227 lines
7.7 KiB
C++
227 lines
7.7 KiB
C++
/* ================================================================
|
|
Core
|
|
----------------
|
|
Core is somewhat like a service locator, but with larger engine capabilities - in essence, it is a lot of glue that would normally exist in a global scope. An instance of Core, "core," is provided in the global scope and is the instance that is referenced from other contexts.
|
|
================================================================ */
|
|
#include "Core.hpp"
|
|
#include "Log.hpp"
|
|
#include "RenderScene.hpp"
|
|
#include "RenderCamera.hpp"
|
|
#include "RenderSet.hpp"
|
|
#include "RenderObject.hpp"
|
|
|
|
Core core;
|
|
|
|
Core::Core() {
|
|
v_window = NULL;
|
|
v_context = 0;
|
|
v_fbo = 0;
|
|
}
|
|
Core::~Core() {
|
|
|
|
}
|
|
int Core::initSystem() {
|
|
if (SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_HAPTIC) != 0) {
|
|
LOG(LOG_ERROR) << FUNC_NAME << " " << SDL_GetError();
|
|
return 1;
|
|
}
|
|
#if defined(HAVE_OPENGLES)
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
|
#endif
|
|
// Get our maximum windowed display size and use it
|
|
SDL_DisplayMode display_mode;
|
|
SDL_GetDesktopDisplayMode(0, &display_mode);
|
|
v_width = display_mode.w;
|
|
v_height = display_mode.h;
|
|
v_flags = SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE;
|
|
// create our window
|
|
v_window = SDL_CreateWindow("Roll them Bones", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, v_width, v_height, v_flags);
|
|
if (v_window == NULL) {
|
|
LOG(LOG_ERROR) << "SDL_CreateWindow: " << SDL_GetError();
|
|
return 1;
|
|
}
|
|
// Ensure our v_width/v_height match the window dimensions
|
|
SDL_GetWindowSize(v_window, &v_width, &v_height);
|
|
// Get our OpenGL context
|
|
v_context = SDL_GL_CreateContext(v_window);
|
|
if (v_context == NULL) {
|
|
std::cerr << SDL_GetError();
|
|
LOG(LOG_ERROR) << "SDL_GL_CreateContext: " << SDL_GetError();
|
|
return 1;
|
|
}
|
|
// If using glew, initialize it (windows only thus far)
|
|
#ifdef USE_GLEW
|
|
glewExperimental = GL_TRUE;
|
|
if (glewInit() != GLEW_OK) {
|
|
LOG(LOG_ERROR) << "Could not initialize GLEW";
|
|
return 1;
|
|
}
|
|
#endif
|
|
// bind content to window
|
|
SDL_GL_MakeCurrent(v_window, v_context);
|
|
// Get our window's FBO id for iOS
|
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &v_fbo);
|
|
// enable depth testing
|
|
glEnable(GL_DEPTH_TEST);
|
|
//
|
|
glDepthFunc(GL_LESS);
|
|
// enable back-face culling
|
|
//glEnable(GL_CULL_FACE);
|
|
LOG(LOG_INFO) << "OpenGL Renderer: " << glGetString(GL_RENDERER) << "\nOpenGL Version: " << glGetString(GL_VERSION) << "\nGLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION);
|
|
// FIXME: temporary location for adding cameras/etc. for testing
|
|
// Create our basic RenderScene
|
|
scene = new RenderScene();
|
|
// TEMP: our framebuffer rendering program
|
|
Program *program = new Program();
|
|
// FIXME: check for GLSL version and automagically load the appropriate shader file
|
|
#ifdef HAVE_OPENGLES
|
|
if (program->addShader("data/shaders/fb_fs.100.glsl", GL_FRAGMENT_SHADER) != 0) {
|
|
LOG(LOG_ERROR) << "Failed to add Shader!";
|
|
return 1;
|
|
}
|
|
if (program->addShader("data/shaders/fb_vs.100.glsl", GL_VERTEX_SHADER) != 0) {
|
|
LOG(LOG_ERROR) << "Failed to add Shader!";
|
|
return 1;
|
|
}
|
|
if (program->doCompile() != 0) {
|
|
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
|
return 1;
|
|
}
|
|
// TEMP: our model rendering program
|
|
Program *program_model = new Program();
|
|
if (program_model->addShader("data/shaders/default_fs.100.glsl", GL_FRAGMENT_SHADER) != 0) {
|
|
LOG(LOG_ERROR) << "Failed to add Shader!";
|
|
return 1;
|
|
}
|
|
if (program_model->addShader("data/shaders/default_vs.100.glsl", GL_VERTEX_SHADER) != 0) {
|
|
LOG(LOG_ERROR) << "Failed to add Shdaer!";
|
|
return 1;
|
|
}
|
|
if (program_model->doCompile() != 0) {
|
|
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
|
return 1;
|
|
}
|
|
#else
|
|
if (program->addShader("data/shaders/fb_fs.glsl", GL_FRAGMENT_SHADER) != 0) {
|
|
LOG(LOG_ERROR) << "Failed to add Shader!";
|
|
return 1;
|
|
}
|
|
if (program->addShader("data/shaders/fb_vs.glsl", GL_VERTEX_SHADER) != 0) {
|
|
LOG(LOG_ERROR) << "Failed to add Shader!";
|
|
return 1;
|
|
}
|
|
if (program->doCompile() != 0) {
|
|
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
|
return 1;
|
|
}
|
|
// TEMP: our model rendering program
|
|
Program *program_model = new Program();
|
|
if (program_model->addShader("data/shaders/default_fs.glsl", GL_FRAGMENT_SHADER) != 0) {
|
|
LOG(LOG_ERROR) << "Failed to add Shader!";
|
|
return 1;
|
|
}
|
|
if (program_model->addShader("data/shaders/default_vs.glsl", GL_VERTEX_SHADER) != 0) {
|
|
LOG(LOG_ERROR) << "Failed to add Shdaer!";
|
|
return 1;
|
|
}
|
|
if (program_model->doCompile() != 0) {
|
|
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
|
return 1;
|
|
}
|
|
#endif
|
|
RenderCamera *camera = new RenderCamera();
|
|
camera->setRenderView(new RenderView(v_width, v_height));
|
|
camera->updateProjection(v_width, v_height);
|
|
camera->setPitch(75.0f);
|
|
camera->setPosition(0, 35, -10);
|
|
camera->doRefresh();
|
|
|
|
scene->addCamera(camera);
|
|
|
|
program->attachTexture(0, camera->getRenderView()->getFBO());
|
|
|
|
(camera->getRenderView()->setProgram(program));
|
|
|
|
RenderObject *objerct = new RenderObject();
|
|
Mesh *mersh = new Mesh("data/models/chest.obj");
|
|
mersh->buildMesh();
|
|
objerct->setMesh(mersh);
|
|
RenderSet *sert = new RenderSet();
|
|
sert->setProgram(program_model);
|
|
sert->addObject(objerct);
|
|
scene->addSet(sert);
|
|
|
|
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
|
|
|
|
flags |= IS_RUNNING;
|
|
return 0;
|
|
}
|
|
int Core::closeSystem() {
|
|
SDL_Quit();
|
|
return 0;
|
|
}
|
|
/* doProcess
|
|
*/
|
|
void Core::doProcess() {
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event)) {
|
|
if (event.type == SDL_QUIT) {
|
|
flags &= ~IS_RUNNING;
|
|
} else if (event.type == SDL_WINDOWEVENT) {
|
|
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
|
v_width = event.window.data1;
|
|
v_height = event.window.data2;
|
|
RenderCamera *r_camera;
|
|
RenderView *r_view;
|
|
std::vector<RenderCamera*>::iterator camera_it, camera_end;
|
|
for (camera_it = scene->getCameras()->begin(), camera_end = scene->getCameras()->end(); camera_it != camera_end; ++camera_it) {
|
|
r_camera = *camera_it;
|
|
if ((r_view = r_camera->getRenderView()) == NULL) continue;
|
|
r_camera->updateProjection(v_width, v_height);
|
|
r_view->setView(v_width, v_height);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
doRender();
|
|
}
|
|
void Core::doRender() {
|
|
scene->doRender(); // Render our main scene using loaded cameras
|
|
// Now let's actually render the framebuffers
|
|
glBindFramebuffer(GL_FRAMEBUFFER, v_fbo);
|
|
glViewport(0, 0, v_width, v_height);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
RenderCamera *r_camera;
|
|
RenderView *r_view;
|
|
Program *r_program;
|
|
// Iterate over each camera's RenderView and send the FBO/mesh to the shader
|
|
std::vector<RenderCamera*>::iterator camera_it, camera_end;
|
|
for (camera_it = scene->getCameras()->begin(), camera_end = scene->getCameras()->end(); camera_it != camera_end; ++camera_it) {
|
|
r_camera = *camera_it;
|
|
if ((r_view = r_camera->getRenderView()) == NULL) continue;
|
|
if ((r_program = r_view->getProgram()) == NULL) continue;
|
|
// FIXME: iOS doesn't like enabling the view's program - black screen if enabled.
|
|
r_program->activate();
|
|
GLuint program_p = r_program->getProgram();
|
|
GLuint program_vp = glGetAttribLocation(program_p, "vp");
|
|
// enable vertex positions and UV map
|
|
glEnableVertexAttribArray(program_vp);
|
|
// Get our mesh
|
|
Mesh *mesh = r_view->getMesh();
|
|
glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo);
|
|
glEnableVertexAttribArray(program_vp);
|
|
glVertexAttribPointer(program_vp, 3, GL_FLOAT, GL_FALSE, 0, NULL);
|
|
// and draw
|
|
glDrawArrays(GL_TRIANGLES, 0, mesh->vertices.size());
|
|
// close 'em
|
|
glDisableVertexAttribArray(program_vp);
|
|
}
|
|
// And update!
|
|
SDL_GL_SwapWindow(v_window);
|
|
}
|
|
SDL_Window* Core::getWindow() {
|
|
return v_window;
|
|
}
|