From 9ab5b42752942c0d19705920a6f56ee43ce3e535 Mon Sep 17 00:00:00 2001 From: kts Date: Thu, 12 Feb 2015 05:48:10 -0800 Subject: [PATCH] Added common checks for GLEW on Windows, need to fix and add other systems. Added LOG_INFO to logging, ERROR logs show SDL message box, and pointing logHook to a function taking 2 const char* params will call said function on log. Added Mesh type that can load an OBJ mesh and build OpenGL vbo/vao. Can also build from passed vertices, uv, and normal arrays. RenderCamera updated. RenderObject updated with Mesh member. RenderScene updated with basic rendering system set (renderTo(RenderView*)). RenderView now creates framebuffers and should be working. RenderView also relies on a Mesh that should generally be a quad, but is not necessarily (it uses a Mesh). --- build/vs/vs.vcxproj | 2 + build/vs/vs.vcxproj.filters | 6 + src/Log.cpp | 16 ++- src/Log.hpp | 4 +- src/Mesh.cpp | 232 ++++++++++++++++++++++++++++++++++++ src/Mesh.hpp | 38 ++++++ src/RenderCamera.cpp | 4 + src/RenderCamera.hpp | 1 + src/RenderObject.cpp | 1 + src/RenderObject.hpp | 4 +- src/RenderScene.cpp | 25 ++++ src/RenderScene.hpp | 3 +- src/RenderSet.hpp | 4 +- src/RenderView.cpp | 82 ++++++++++++- src/RenderView.hpp | 20 ++-- src/common.hpp | 15 ++- src/main.cpp | 33 ++++- 17 files changed, 460 insertions(+), 30 deletions(-) create mode 100644 src/Mesh.cpp create mode 100644 src/Mesh.hpp diff --git a/build/vs/vs.vcxproj b/build/vs/vs.vcxproj index 4a36874..3f34956 100644 --- a/build/vs/vs.vcxproj +++ b/build/vs/vs.vcxproj @@ -78,6 +78,7 @@ xcopy /d /y "..\..\..\..\Dev\SDL2-2.0.3\lib\x86\SDL2.dll" "$(OutDir)" + @@ -99,6 +100,7 @@ xcopy /d /y "..\..\..\..\Dev\SDL2-2.0.3\lib\x86\SDL2.dll" "$(OutDir)" + diff --git a/build/vs/vs.vcxproj.filters b/build/vs/vs.vcxproj.filters index d474496..056fc30 100644 --- a/build/vs/vs.vcxproj.filters +++ b/build/vs/vs.vcxproj.filters @@ -48,6 +48,9 @@ Classes + + Classes + @@ -85,5 +88,8 @@ Classes + + Classes + \ No newline at end of file diff --git a/src/Log.cpp b/src/Log.cpp index 21cfbfe..2f5da66 100644 --- a/src/Log.cpp +++ b/src/Log.cpp @@ -5,6 +5,8 @@ This file defines the class for Log. ================================================================ */ #include "Log.hpp" +void (*logHook)(const char*, const char*) = NULL; + Log::Log() {} std::ostringstream& Log::Get(LogLevel level) { @@ -19,17 +21,19 @@ std::ostringstream& Log::Get(LogLevel level) { ltm = localtime(¤t_time); #endif os << 1900+ltm->tm_year << "/" << 1+ltm->tm_mon << "/" << ltm->tm_mday << " " << ltm->tm_hour << ":" << ltm->tm_min << ':' << ltm->tm_sec; - os << "\n"; + os << std::endl; return os; } Log::~Log() { os << std::endl; - fprintf(stderr, "%s\n", os.str().c_str()); - fflush(stderr); char *title = "Undefined"; switch(l) { + case LOG_INFO: + title = "Info"; + break; case LOG_ERROR: title = "Error"; + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, os.str().c_str(), NULL); break; case LOG_WARNING: title = "Warning"; @@ -38,5 +42,9 @@ Log::~Log() { title = "Debug"; break; } - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, os.str().c_str(), NULL); + if (logHook != NULL) { + logHook(title, os.str().c_str()); + } + fprintf(stderr, "%s: %s\n", title, os.str().c_str()); + fflush(stderr); } \ No newline at end of file diff --git a/src/Log.hpp b/src/Log.hpp index 95029a9..49a81a4 100644 --- a/src/Log.hpp +++ b/src/Log.hpp @@ -19,7 +19,9 @@ This header file describes the Log class #define FUNC_NAME __PRETTY_FUNCTION__ #endif -enum LogLevel { LOG_ERROR, LOG_WARNING, LOG_DEBUG }; +extern void (*logHook)(const char*, const char*); + +enum LogLevel { LOG_INFO, LOG_ERROR, LOG_WARNING, LOG_DEBUG }; class Log { public: diff --git a/src/Mesh.cpp b/src/Mesh.cpp new file mode 100644 index 0000000..b1ee991 --- /dev/null +++ b/src/Mesh.cpp @@ -0,0 +1,232 @@ +#include "Mesh.hpp" +#include // fscanf +#include // strcmp +#include // atof + +Mesh::Mesh() { + vbo = vao = tex = 0; + flags = 0; + mode = GL_STATIC_DRAW; +} +Mesh::Mesh(Vec3 *in_vertices, int v_count, Vec2 *in_uvs, int uv_count, Vec3 *in_normals, int n_count) { + loadArrays(in_vertices, v_count, in_uvs, uv_count, in_normals, n_count); +} + +Mesh::~Mesh() { + if (flags & MESH_BUILT) destroyMesh(); +} + +int Mesh::loadObj(const char *filename) { + std::vector temp_vertices; + std::vector temp_uvs; + std::vector temp_normals; + std::vector vertex_indices; + std::vector uv_indices; + std::vector normal_indices; + int ret; +#ifdef _WIN32 + FILE *file; + fopen_s(&file, filename, "r"); +#else + FILE *file = fopen(filename, "r"); +#endif + if (file == NULL) { + // TODO: error report + return 1; + } + char word[32]; +#ifdef _WIN32 + while ((ret = fscanf_s(file, "%s ", word)) != EOF) { +#else + while ((ret = fscanf(file, "%s ", word)) != EOF) { +#endif + if (strcmp(word, "v") == 0) { // vertices + // "x y z w" as floats, with "w" being optional + Vec3 vec; // our vertex + char word[32]; + char ch; + int pos = 0, w_i = 0; + while ((ch = fgetc(file)) != EOF) { + if (ch == ' ' || ch == '\n') { + if (pos == 0) { // x + word[w_i] = '\0'; + vec.x = (float)atof(word); + } else if (pos == 1) { // y + word[w_i] = '\0'; + vec.y = (float)atof(word); + } else if (pos == 2) { // z + word[w_i] = '\0'; + vec.z = (float)atof(word); + /*} else if (pos == 3) { // w + word[w_i] = '\0'; + vec.w = atof(word);*/ + } + pos++; + w_i = 0; + } + if (ch == '\n') break; + word[w_i++] = ch; + } + temp_vertices.push_back(vec); + } else if (strcmp(word, "vt") == 0) { // texture coordinates + // "u v [w]" as floats, with "w" being optional + Vec2 vec; // our texture coord + char word[32]; + char ch; + int pos = 0, w_i = 0; + while ((ch = fgetc(file)) != EOF) { + if (ch == ' ' || ch == '\n') { + if (pos == 0) { // x + word[w_i] = '\0'; + vec.x = (float)atof(word); + } else if (pos == 1) { // y + word[w_i] = '\0'; + vec.y = (float)atof(word); + /*} else if (pos == 3) { // w + word[w_i] = '\0'; + vec.w = atof(word);*/ + } + pos++; + w_i = 0; + } + if (ch == '\n') break; + word[w_i++] = ch; + } + temp_uvs.push_back(vec); + } else if (strcmp(word, "vn") == 0) { // normals + // "x y z" as floats + Vec3 vec; // our normal + char word[32]; + char ch; + int pos = 0, w_i = 0; + while ((ch = fgetc(file)) != EOF) { + if (ch == ' ' || ch == '\n') { + if (pos == 0) { // x + word[w_i] = '\0'; + vec.x = (float)atof(word); + } else if (pos == 1) { // y + word[w_i] = '\0'; + vec.y = (float)atof(word); + } else if (pos == 2) { // z + word[w_i] = '\0'; + vec.z = (float)atof(word); + /*} else if (pos == 3) { // w + word[w_i] = '\0'; + vec.w = atof(word);*/ + } + pos++; + w_i = 0; + } + if (ch == '\n') break; + word[w_i++] = ch; + } + temp_normals.push_back(vec); + /*} else if (strcmp(word, "vp") == 0) { // parameter space vertices + // "u v w", with 'v' and 'w' being optional*/ + } else if (strcmp(word, "f") == 0) { // face definitions + // "v1 v2 v3" for plain vertex indices + // "v1/vt1 v2/vt2 v3/vt3" for vertex/texture-coordinate indices + // "v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3" for vertex/texture-coordinate/normal indices + // "v1//vn1 v2//vn2 v3//vn3" for vertex/normal indices + char word[32]; + char ch; + int w_i = 0, mode = 0; + // read in our faces into our index vectors + while ((ch = fgetc(file)) != EOF) { + if (ch == ' ' || ch == '\n') { + word[w_i] = '\0'; + if (mode == 0) { // was in vertex, now in texture-coords + vertex_indices.push_back(atoi(word)); + } else if (mode == 1) { // was in texture-coords, now in normal + uv_indices.push_back(atoi(word)); + } else if (mode == 2) { // was in normal, write it out + normal_indices.push_back(atoi(word)); + } + w_i = 0; + mode = 0; // reset our mode + } else if (ch == '/') { + word[w_i] = '\0'; + if (mode == 0) { // was in vertex, now in texture-coords + vertex_indices.push_back(atoi(word)); + } else if (mode == 1) { // was in texture-coords, now in normal + if (w_i > 0) uv_indices.push_back(atoi(word)); + } + mode++; + w_i = 0; + } else { + word[w_i++] = ch; + } + if (ch == '\n') break; + } + //} else if (strcmp(word, "#") == 0) { // comment + //} else if (strcmp(word, "o") == 0) { // object name + //} else if (strcmp(word, "g") == 0) { // group name + //} else if (Strmcpmp(word, "s") == 0) { // smooth + // "s 1" or "s off" + } else { // ergo, newline noms + char ch; + while ((ch = fgetc(file)) != EOF) { + if (ch == '\n') break; + } + } + } + fclose(file); + // we're done, let's convert our face-derived indices to our actual mesh + int i; + int indices = vertex_indices.size(); + // TODO: vertex index access should be checked for validity (>= 0 < temp_vertices.size()) + for (i = 0; i < indices; i++) { + Vec3 vertex = temp_vertices[vertex_indices[i]-1]; + vertices.push_back(vertex); + } + indices = uv_indices.size(); + for (i = 0; i < indices; i++) { + printf("%d/%d\n", i, indices); + printf("%d\n", uv_indices[i]); + Vec2 uv = temp_uvs[uv_indices[i]-1]; + uvs.push_back(uv); + } + indices = normal_indices.size(); + for (i = 0; i < indices; i++) { + Vec3 normal = temp_normals[normal_indices[i]-1]; + normals.push_back(normal); + } + flags |= MESH_LOADED; + return 0; +} +int Mesh::loadArrays(Vec3 *in_vertices, int v_count, Vec2 *in_uvs, int uv_count, Vec3 *in_normals, int n_count) { + if (v_count > 0) { + vertices.assign(in_vertices, in_vertices + v_count); + flags |= MESH_LOADED; + } + if (uv_count > 0) { + uvs.assign(in_uvs, in_uvs + uv_count); + } + if (n_count > 0) { + normals.assign(in_normals, in_normals + n_count); + } + return 0; +} + +int Mesh::buildMesh() { + if (!(flags & MESH_LOADED)) return 1; + if (flags & MESH_BUILT) destroyMesh(); + // generate our vertex buffer object from our given points + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vec3), &vertices[0], mode); + // generate our vertex attribute object + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); + flags |= MESH_BUILT; + return 0; +} +int Mesh::destroyMesh() { + glDeleteBuffers(1, &vbo); + glDeleteVertexArrays(1, &vao); + flags &= ~MESH_BUILT; + return 0; +} \ No newline at end of file diff --git a/src/Mesh.hpp b/src/Mesh.hpp new file mode 100644 index 0000000..bb2e065 --- /dev/null +++ b/src/Mesh.hpp @@ -0,0 +1,38 @@ +/* ================================================================ +Mesh +---------------- +This header file describes the Mesh class. + +A Mesh is as the name indicates, a 3D mesh. +================================================================ */ +#ifndef MESH_HPP +#define MESH_HPP +#include "common.hpp" +#include "Vec.hpp" +#include +#define MESH_LOADED (1 << 1) +#define MESH_BUILT (1 << 2) +class Mesh { + public: + Mesh(); + Mesh(Vec3 *in_vertices, int v_count, Vec2 *in_uvs, int uv_count, Vec3 *in_normals, int n_count); + ~Mesh(); + // + int loadObj(const char *filename); + int loadArrays(Vec3 *in_vertices, int v_count, Vec2 *in_uvs, int uv_count, Vec3 *in_normals, int n_count); + int buildMesh(); + int destroyMesh(); + private: + unsigned int flags; // Flags to signify our status + // the base sources of our mesh + std::vector vertices; + std::vector uvs; + std::vector normals; + // reference to GPU objects + GLuint tex; // our texture to use + GLuint vao; // our mesh vertex attribute object + GLuint mode; // Our BufferData mode, either (default)GL_STATIC_DRAW or GL_DYNAMIC_DRAW + protected: + GLuint vbo; // our mesh vertex buffer object +}; +#endif \ No newline at end of file diff --git a/src/RenderCamera.cpp b/src/RenderCamera.cpp index 6413f52..657e746 100644 --- a/src/RenderCamera.cpp +++ b/src/RenderCamera.cpp @@ -17,3 +17,7 @@ int RenderCamera::setRenderView(RenderView *rv) { render_view = rv; return 0; } +/* ======== Getter functions ======== */ +RenderView* RenderCamera::getRenderView() { + return render_view; +} \ No newline at end of file diff --git a/src/RenderCamera.hpp b/src/RenderCamera.hpp index 126ffe5..3887782 100644 --- a/src/RenderCamera.hpp +++ b/src/RenderCamera.hpp @@ -17,6 +17,7 @@ class RenderCamera { RenderCamera(); ~RenderCamera(); int setRenderView(RenderView *view); + RenderView* getRenderView(); private: Vec3 x, y, z; // TODO: replace with quaternion int render_mode; // 0 = perspective, 1 = orthogonal diff --git a/src/RenderObject.cpp b/src/RenderObject.cpp index de0244e..8779266 100644 --- a/src/RenderObject.cpp +++ b/src/RenderObject.cpp @@ -6,6 +6,7 @@ This header file defines the RenderObject class. #include "RenderObject.hpp" /* ======== Constructors and Destructors ======== */ RenderObject::RenderObject() { + mesh = NULL; } RenderObject::~RenderObject() { } \ No newline at end of file diff --git a/src/RenderObject.hpp b/src/RenderObject.hpp index a635b5a..8937035 100644 --- a/src/RenderObject.hpp +++ b/src/RenderObject.hpp @@ -10,13 +10,15 @@ a Mesh, a texture, a position, and an orientation. #ifndef RENDEROBJECT_HPP #define RENDEROBJECT_HPP #include "common.hpp" +#include "Mesh.hpp" #include "Mat4.hpp" class RenderObject { + friend class RenderSet; public: RenderObject(); ~RenderObject(); private: - // Mesh *mesh; + Mesh *mesh; // GLuint texture; Mat4 translation; Mat4 rotation; diff --git a/src/RenderScene.cpp b/src/RenderScene.cpp index b1532d5..cf261b8 100644 --- a/src/RenderScene.cpp +++ b/src/RenderScene.cpp @@ -4,6 +4,7 @@ RenderScene This header file defines the RenderScene class. ================================================================ */ #include "RenderScene.hpp" +#include "RenderObject.hpp" #include "Log.hpp" #include // for std::out_of_range #include // for std::cerr @@ -16,6 +17,30 @@ RenderScene::RenderScene() { RenderScene::~RenderScene() { } +int RenderScene::renderTo(RenderView *target_view) { + RenderCamera *camera; + RenderView *view; + RenderSet *set; + RenderObject *object; + std::vector::iterator camera_it, camera_end; + for (camera_it = cameras.begin(), camera_end = cameras.end(); camera_it != camera_end; ++camera_it) { + camera = *camera_it; + if ((view = camera->getRenderView()) == NULL) continue; + glBindFramebuffer(GL_FRAMEBUFFER, view->fbo); + + std::vector::iterator set_it, set_end; + for (set_it = sets.begin(), set_end = sets.end(); set_it != set_end; ++set_it) { + set = *set_it; + std::vector::iterator obj_it, obj_end; + for (obj_it = set->objects.begin(), obj_end = set->objects.end(); obj_it != obj_end; ++obj_it) { + object = *obj_it; + + } + } + } + return 0; +} + // This function adds the ptr to Camera and returns its "id" which is simply its index+1 int RenderScene::addCamera(RenderCamera* camera) { try { diff --git a/src/RenderScene.hpp b/src/RenderScene.hpp index bb5063b..2fc143f 100644 --- a/src/RenderScene.hpp +++ b/src/RenderScene.hpp @@ -17,12 +17,13 @@ class RenderScene { public: RenderScene(); ~RenderScene(); + int renderTo(RenderView *view); int addCamera(RenderCamera* camera); int remCamera(RenderCamera* camera); int remCamera(int id); RenderCamera* getCamera(int id); private: std::vector cameras; // Our scene's cameras - std::vector render_sets; // Our scene's render sets + std::vector sets; // Our scene's render sets }; #endif diff --git a/src/RenderSet.hpp b/src/RenderSet.hpp index 8b4a314..9881a0a 100644 --- a/src/RenderSet.hpp +++ b/src/RenderSet.hpp @@ -14,12 +14,14 @@ rendering layers of the program. #include "RenderObject.hpp" #include class RenderSet { + friend class RenderScene; public: RenderSet(); ~RenderSet(); private: int mode; // bitflag, 0 = normal, 1 = hide - std::vector objects; // Our vector of objects to render GLuint program; // Our rendering program + protected: + std::vector objects; // Our vector of objects to render }; #endif diff --git a/src/RenderView.cpp b/src/RenderView.cpp index c06db37..2d6296a 100644 --- a/src/RenderView.cpp +++ b/src/RenderView.cpp @@ -4,22 +4,96 @@ RenderView This file defines our RenderView object. ================================================================ */ #include "RenderView.hpp" +#include "Log.hpp" /* ======== Constructors and Destructors ======== */ -RenderView::RenderView(unsigned int width, unsigned int height) { +RenderView::RenderView(int width, int height) { program = fbo = fbo_depth = fbo_tex = 0; - w = h = 0; + w = width; + h = height; x = y = 0; + flags = 0; + mesh = NULL; createView(width, height); } RenderView::~RenderView() { destroyView(); + if (mesh != NULL) delete mesh; } /* ======== Setters ======== */ -int RenderView::createView(unsigned int width, unsigned int height) { +int RenderView::createView(int width, int height) { // TODO: call destroyView() and create new FBO at width and height + // ================ create depth buffer + glGenRenderbuffers(1, &fbo_depth); + glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth); + // unbind the render buffer + glBindRenderbuffer(GL_RENDERBUFFER, 0); + // ================ create texture + glGenTextures(1, &fbo_tex); + glBindTexture(GL_TEXTURE_2D, fbo_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + // add some filters (... move this) + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + // unbind texture + glBindTexture(GL_TEXTURE_2D, 0); + // ================ create framebuffers + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + // attach texture to framebuffer + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex, 0); + // attach depth render buffer + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + LOG(LOG_ERROR) << FUNC_NAME << "Failed to create Framebuffer!"; + glBindFramebuffer(GL_FRAMEBUFFER, 0); + return 1; + } + flags |= RENDERVIEW_ACTIVE; + // unbind our frame buffer + glBindFramebuffer(GL_FRAMEBUFFER, 0); + // ================ create quad mesh + // Load our default quad mesh + Vec3 quad[6] = { + Vec3(-1.0f, -1.0f, 0.0f), + Vec3(1.0f, -1.0f, 0.0f), + Vec3(-1.0f, 1.0f, 0.0f), + Vec3(-1.0f, 1.0f, 0.0f), + Vec3(1.0f, -1.0f, 0.0f), + Vec3(1.0f, 1.0f, 0.0f) + }; + mesh = new Mesh(quad, 6, NULL, 0, NULL, 0); + mesh->buildMesh(); + // TODO: Create and Compile Framebuffer shader (maybe?) + w = width; h = height; return 0; } int RenderView::destroyView() { - // TODO: destroy FBO + if ((flags & RENDERVIEW_ACTIVE) == 0) return 1; + //glDeleteProgram(v_fb_program[i]); + //glDeleteTextures(1, &v_fb_program_texture[i]); + glDeleteFramebuffers(1, &fbo); + glDeleteTextures(1, &fbo_tex); + glDeleteRenderbuffers(1, &fbo_depth); + flags &= ~RENDERVIEW_ACTIVE; + // TODO: delete fbo_vao, fbo_vbo return 0; } +int RenderView::setView(int width, int height) { + if ((flags & RENDERVIEW_ACTIVE) == 0) return 1; + // resize depth buffer + glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + // resize texture + glBindTexture(GL_TEXTURE_2D, fbo_tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); + glBindTexture(GL_TEXTURE_2D, 0); + w = width; + h = height; + return 0; +} \ No newline at end of file diff --git a/src/RenderView.hpp b/src/RenderView.hpp index 040cd7b..892c0fd 100644 --- a/src/RenderView.hpp +++ b/src/RenderView.hpp @@ -10,19 +10,25 @@ purposes, it is a wrapper around a FBO. #ifndef RENDERVIEW_HPP #define RENDERVIEW_HPP #include "common.hpp" +#include "Mesh.hpp" +#define RENDERVIEW_ACTIVE (1 << 1) class RenderView { - friend class RenderCamera; + friend class RenderScene; public: - RenderView(unsigned int width, unsigned int height); + RenderView(int width, int height); ~RenderView(); + protected: + GLuint fbo; // The fbo that RenderScene will draw to private: + int createView(int width, int height); + int destroyView(); + int setView(int width, int height); GLuint program; // Compiled shader program to render with - GLuint fbo; // The fbo that RenderCamera will draw to GLuint fbo_depth; // The fbo depth buffer GLuint fbo_tex; // The texture of the fbo - unsigned int w, h; // width and height of this view (also of fbo) + int w, h; // width and height of this view (also of fbo) int x, y; // x and y offsets of rendering to screen - int createView(unsigned int width, unsigned int height); - int destroyView(); + Mesh *mesh; // rendering Mesh, created as quad in CreateView + unsigned int flags; // byte flag }; -#endif +#endif \ No newline at end of file diff --git a/src/common.hpp b/src/common.hpp index 1940380..9322b6d 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -5,13 +5,16 @@ This header provides common includes to SDL2 and OpenGL/OpenGLES #include #endif #include "SDL.h" - -#if defined(__IPHONEOS__) || defined(__ANDROID__) -#define HAVE_OPENGLES +#if defined(_WIN32) + #define USE_GLEW +#elif defined(__IPHONEOS__) || defined(__ANDROID__) + #define HAVE_OPENGLES #endif -#ifdef HAVE_OPENGLES -#include "SDL_opengles.h" +#if defined(HAVE_OPENGLES) + #include "SDL_opengles.h" +#elif defined(USE_GLEW) + #include #else -#include "SDL_opengl.h" + #include "SDL_opengl.h" #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 5e71c80..11313b3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,11 +2,13 @@ #include "RenderScene.hpp" #include "RenderView.hpp" #include "RenderCamera.hpp" +#include "Log.hpp" int main(int argc, char *argv[]) { // TEMP location of video vars SDL_Window *v_window = NULL; SDL_GLContext v_context = 0; + GLint v_fbo; SDL_Event event; int v_width = 640; int v_height = 480; @@ -15,27 +17,42 @@ int main(int argc, char *argv[]) { // initialize SDL if (SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_HAPTIC) != 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init: %s\n", SDL_GetError()); + LOG(LOG_ERROR) << "SDL_Init: " << SDL_GetError(); return 1; } // 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) { - SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "SDL_CreateWindow: %s\n", SDL_GetError()); + LOG(LOG_ERROR) << "SDL_CreateWindow: " << SDL_GetError(); return 1; } // get our OpenGL context v_context = SDL_GL_CreateContext(v_window); if (v_context == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "SDL_GL_CreateContext: %s\n", SDL_GetError()); + LOG(LOG_ERROR) << "SDL_GL_CreateContext: " << SDL_GetError(); return 1; } +#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); + // + LOG(LOG_INFO) << "OpenGL Renderer: " << glGetString(GL_RENDERER) << "\nOpenGL Version: " << glGetString(GL_VERSION); glClearColor(0.5f, 0.5f, 0.5f, 0.5f); // + RenderView v_view(v_width, v_height); RenderScene *scene = new RenderScene(); int camera_id = scene->addCamera(new RenderCamera()); RenderCamera *camera = scene->getCamera(camera_id); - camera->setRenderView(new RenderView(v_width, v_height)); + RenderView *view = new RenderView(v_width, v_height); + camera->setRenderView(view); // begin our main loop g_running = 1; @@ -45,10 +62,16 @@ int main(int argc, char *argv[]) { g_running = 0; } } + scene->renderTo(&v_view); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, v_width, v_height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + SDL_GL_SwapWindow(v_window); SDL_Delay(1); } SDL_Quit(); return 0; -} +} \ No newline at end of file