RtB/src/Core.cpp

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;
}