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).

master
kts 2015-02-12 05:48:10 -08:00
parent 28d93f69d3
commit 9ab5b42752
17 changed files with 460 additions and 30 deletions

View File

@ -78,6 +78,7 @@ xcopy /d /y "..\..\..\..\Dev\SDL2-2.0.3\lib\x86\SDL2.dll" "$(OutDir)"</Command>
<ClCompile Include="..\..\src\Log.cpp" /> <ClCompile Include="..\..\src\Log.cpp" />
<ClCompile Include="..\..\src\main.cpp" /> <ClCompile Include="..\..\src\main.cpp" />
<ClCompile Include="..\..\src\Mat4.cpp" /> <ClCompile Include="..\..\src\Mat4.cpp" />
<ClCompile Include="..\..\src\Mesh.cpp" />
<ClCompile Include="..\..\src\RenderCamera.cpp" /> <ClCompile Include="..\..\src\RenderCamera.cpp" />
<ClCompile Include="..\..\src\RenderObject.cpp" /> <ClCompile Include="..\..\src\RenderObject.cpp" />
<ClCompile Include="..\..\src\RenderScene.cpp" /> <ClCompile Include="..\..\src\RenderScene.cpp" />
@ -99,6 +100,7 @@ xcopy /d /y "..\..\..\..\Dev\SDL2-2.0.3\lib\x86\SDL2.dll" "$(OutDir)"</Command>
<ClInclude Include="..\..\src\common.hpp" /> <ClInclude Include="..\..\src\common.hpp" />
<ClInclude Include="..\..\src\Log.hpp" /> <ClInclude Include="..\..\src\Log.hpp" />
<ClInclude Include="..\..\src\Mat4.hpp" /> <ClInclude Include="..\..\src\Mat4.hpp" />
<ClInclude Include="..\..\src\Mesh.hpp" />
<ClInclude Include="..\..\src\RenderCamera.hpp" /> <ClInclude Include="..\..\src\RenderCamera.hpp" />
<ClInclude Include="..\..\src\RenderObject.hpp" /> <ClInclude Include="..\..\src\RenderObject.hpp" />
<ClInclude Include="..\..\src\RenderScene.hpp" /> <ClInclude Include="..\..\src\RenderScene.hpp" />

View File

@ -48,6 +48,9 @@
<ClCompile Include="..\..\src\Log.cpp"> <ClCompile Include="..\..\src\Log.cpp">
<Filter>Classes</Filter> <Filter>Classes</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\Mesh.cpp">
<Filter>Classes</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\..\..\Dev\SDL2-2.0.3\lib\x86\SDL2.dll"> <None Include="..\..\..\..\Dev\SDL2-2.0.3\lib\x86\SDL2.dll">
@ -85,5 +88,8 @@
<ClInclude Include="..\..\src\Log.hpp"> <ClInclude Include="..\..\src\Log.hpp">
<Filter>Classes</Filter> <Filter>Classes</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\Mesh.hpp">
<Filter>Classes</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -5,6 +5,8 @@ This file defines the class for Log.
================================================================ */ ================================================================ */
#include "Log.hpp" #include "Log.hpp"
void (*logHook)(const char*, const char*) = NULL;
Log::Log() {} Log::Log() {}
std::ostringstream& Log::Get(LogLevel level) { std::ostringstream& Log::Get(LogLevel level) {
@ -19,17 +21,19 @@ std::ostringstream& Log::Get(LogLevel level) {
ltm = localtime(&current_time); ltm = localtime(&current_time);
#endif #endif
os << 1900+ltm->tm_year << "/" << 1+ltm->tm_mon << "/" << ltm->tm_mday << " " << ltm->tm_hour << ":" << ltm->tm_min << ':' << ltm->tm_sec; 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; return os;
} }
Log::~Log() { Log::~Log() {
os << std::endl; os << std::endl;
fprintf(stderr, "%s\n", os.str().c_str());
fflush(stderr);
char *title = "Undefined"; char *title = "Undefined";
switch(l) { switch(l) {
case LOG_INFO:
title = "Info";
break;
case LOG_ERROR: case LOG_ERROR:
title = "Error"; title = "Error";
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, os.str().c_str(), NULL);
break; break;
case LOG_WARNING: case LOG_WARNING:
title = "Warning"; title = "Warning";
@ -38,5 +42,9 @@ Log::~Log() {
title = "Debug"; title = "Debug";
break; 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);
} }

View File

@ -19,7 +19,9 @@ This header file describes the Log class
#define FUNC_NAME __PRETTY_FUNCTION__ #define FUNC_NAME __PRETTY_FUNCTION__
#endif #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 { class Log {
public: public:

232
src/Mesh.cpp 100644
View File

@ -0,0 +1,232 @@
#include "Mesh.hpp"
#include <stdio.h> // fscanf
#include <string.h> // strcmp
#include <stdlib.h> // 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 <Vec3> temp_vertices;
std::vector <Vec2> temp_uvs;
std::vector <Vec3> temp_normals;
std::vector <unsigned int> vertex_indices;
std::vector <unsigned int> uv_indices;
std::vector <unsigned int> 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;
}

38
src/Mesh.hpp 100644
View File

@ -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 <vector>
#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 <Vec3> vertices;
std::vector <Vec2> uvs;
std::vector <Vec3> 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

View File

@ -17,3 +17,7 @@ int RenderCamera::setRenderView(RenderView *rv) {
render_view = rv; render_view = rv;
return 0; return 0;
} }
/* ======== Getter functions ======== */
RenderView* RenderCamera::getRenderView() {
return render_view;
}

View File

@ -17,6 +17,7 @@ class RenderCamera {
RenderCamera(); RenderCamera();
~RenderCamera(); ~RenderCamera();
int setRenderView(RenderView *view); int setRenderView(RenderView *view);
RenderView* getRenderView();
private: private:
Vec3 x, y, z; // TODO: replace with quaternion Vec3 x, y, z; // TODO: replace with quaternion
int render_mode; // 0 = perspective, 1 = orthogonal int render_mode; // 0 = perspective, 1 = orthogonal

View File

@ -6,6 +6,7 @@ This header file defines the RenderObject class.
#include "RenderObject.hpp" #include "RenderObject.hpp"
/* ======== Constructors and Destructors ======== */ /* ======== Constructors and Destructors ======== */
RenderObject::RenderObject() { RenderObject::RenderObject() {
mesh = NULL;
} }
RenderObject::~RenderObject() { RenderObject::~RenderObject() {
} }

View File

@ -10,13 +10,15 @@ a Mesh, a texture, a position, and an orientation.
#ifndef RENDEROBJECT_HPP #ifndef RENDEROBJECT_HPP
#define RENDEROBJECT_HPP #define RENDEROBJECT_HPP
#include "common.hpp" #include "common.hpp"
#include "Mesh.hpp"
#include "Mat4.hpp" #include "Mat4.hpp"
class RenderObject { class RenderObject {
friend class RenderSet;
public: public:
RenderObject(); RenderObject();
~RenderObject(); ~RenderObject();
private: private:
// Mesh *mesh; Mesh *mesh;
// GLuint texture; // GLuint texture;
Mat4 translation; Mat4 translation;
Mat4 rotation; Mat4 rotation;

View File

@ -4,6 +4,7 @@ RenderScene
This header file defines the RenderScene class. This header file defines the RenderScene class.
================================================================ */ ================================================================ */
#include "RenderScene.hpp" #include "RenderScene.hpp"
#include "RenderObject.hpp"
#include "Log.hpp" #include "Log.hpp"
#include <stdexcept> // for std::out_of_range #include <stdexcept> // for std::out_of_range
#include <iostream> // for std::cerr #include <iostream> // for std::cerr
@ -16,6 +17,30 @@ RenderScene::RenderScene() {
RenderScene::~RenderScene() { RenderScene::~RenderScene() {
} }
int RenderScene::renderTo(RenderView *target_view) {
RenderCamera *camera;
RenderView *view;
RenderSet *set;
RenderObject *object;
std::vector<RenderCamera*>::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<RenderSet*>::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<RenderObject*>::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 // This function adds the ptr to Camera and returns its "id" which is simply its index+1
int RenderScene::addCamera(RenderCamera* camera) { int RenderScene::addCamera(RenderCamera* camera) {
try { try {

View File

@ -17,12 +17,13 @@ class RenderScene {
public: public:
RenderScene(); RenderScene();
~RenderScene(); ~RenderScene();
int renderTo(RenderView *view);
int addCamera(RenderCamera* camera); int addCamera(RenderCamera* camera);
int remCamera(RenderCamera* camera); int remCamera(RenderCamera* camera);
int remCamera(int id); int remCamera(int id);
RenderCamera* getCamera(int id); RenderCamera* getCamera(int id);
private: private:
std::vector<RenderCamera*> cameras; // Our scene's cameras std::vector<RenderCamera*> cameras; // Our scene's cameras
std::vector<RenderSet*> render_sets; // Our scene's render sets std::vector<RenderSet*> sets; // Our scene's render sets
}; };
#endif #endif

View File

@ -14,12 +14,14 @@ rendering layers of the program.
#include "RenderObject.hpp" #include "RenderObject.hpp"
#include <vector> #include <vector>
class RenderSet { class RenderSet {
friend class RenderScene;
public: public:
RenderSet(); RenderSet();
~RenderSet(); ~RenderSet();
private: private:
int mode; // bitflag, 0 = normal, 1 = hide int mode; // bitflag, 0 = normal, 1 = hide
std::vector<RenderObject*> objects; // Our vector of objects to render
GLuint program; // Our rendering program GLuint program; // Our rendering program
protected:
std::vector<RenderObject*> objects; // Our vector of objects to render
}; };
#endif #endif

View File

@ -4,22 +4,96 @@ RenderView
This file defines our RenderView object. This file defines our RenderView object.
================================================================ */ ================================================================ */
#include "RenderView.hpp" #include "RenderView.hpp"
#include "Log.hpp"
/* ======== Constructors and Destructors ======== */ /* ======== Constructors and Destructors ======== */
RenderView::RenderView(unsigned int width, unsigned int height) { RenderView::RenderView(int width, int height) {
program = fbo = fbo_depth = fbo_tex = 0; program = fbo = fbo_depth = fbo_tex = 0;
w = h = 0; w = width;
h = height;
x = y = 0; x = y = 0;
flags = 0;
mesh = NULL;
createView(width, height); createView(width, height);
} }
RenderView::~RenderView() { RenderView::~RenderView() {
destroyView(); destroyView();
if (mesh != NULL) delete mesh;
} }
/* ======== Setters ======== */ /* ======== 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 // 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; return 0;
} }
int RenderView::destroyView() { 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; 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;
}

View File

@ -10,19 +10,25 @@ purposes, it is a wrapper around a FBO.
#ifndef RENDERVIEW_HPP #ifndef RENDERVIEW_HPP
#define RENDERVIEW_HPP #define RENDERVIEW_HPP
#include "common.hpp" #include "common.hpp"
#include "Mesh.hpp"
#define RENDERVIEW_ACTIVE (1 << 1)
class RenderView { class RenderView {
friend class RenderCamera; friend class RenderScene;
public: public:
RenderView(unsigned int width, unsigned int height); RenderView(int width, int height);
~RenderView(); ~RenderView();
protected:
GLuint fbo; // The fbo that RenderScene will draw to
private: private:
int createView(int width, int height);
int destroyView();
int setView(int width, int height);
GLuint program; // Compiled shader program to render with 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_depth; // The fbo depth buffer
GLuint fbo_tex; // The texture of the fbo 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 x, y; // x and y offsets of rendering to screen
int createView(unsigned int width, unsigned int height); Mesh *mesh; // rendering Mesh, created as quad in CreateView
int destroyView(); unsigned int flags; // byte flag
}; };
#endif #endif

View File

@ -5,13 +5,16 @@ This header provides common includes to SDL2 and OpenGL/OpenGLES
#include <TargetConditionals.h> #include <TargetConditionals.h>
#endif #endif
#include "SDL.h" #include "SDL.h"
#if defined(_WIN32)
#if defined(__IPHONEOS__) || defined(__ANDROID__) #define USE_GLEW
#define HAVE_OPENGLES #elif defined(__IPHONEOS__) || defined(__ANDROID__)
#define HAVE_OPENGLES
#endif #endif
#ifdef HAVE_OPENGLES #if defined(HAVE_OPENGLES)
#include "SDL_opengles.h" #include "SDL_opengles.h"
#elif defined(USE_GLEW)
#include <GL/glew.h>
#else #else
#include "SDL_opengl.h" #include "SDL_opengl.h"
#endif #endif

View File

@ -2,11 +2,13 @@
#include "RenderScene.hpp" #include "RenderScene.hpp"
#include "RenderView.hpp" #include "RenderView.hpp"
#include "RenderCamera.hpp" #include "RenderCamera.hpp"
#include "Log.hpp"
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// TEMP location of video vars // TEMP location of video vars
SDL_Window *v_window = NULL; SDL_Window *v_window = NULL;
SDL_GLContext v_context = 0; SDL_GLContext v_context = 0;
GLint v_fbo;
SDL_Event event; SDL_Event event;
int v_width = 640; int v_width = 640;
int v_height = 480; int v_height = 480;
@ -15,27 +17,42 @@ int main(int argc, char *argv[]) {
// initialize SDL // initialize SDL
if (SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_HAPTIC) != 0) { 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; return 1;
} }
// create our window // create our window
v_window = SDL_CreateWindow("Roll them Bones", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, v_width, v_height, v_flags); v_window = SDL_CreateWindow("Roll them Bones", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, v_width, v_height, v_flags);
if (v_window == NULL) { 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; return 1;
} }
// get our OpenGL context // get our OpenGL context
v_context = SDL_GL_CreateContext(v_window); v_context = SDL_GL_CreateContext(v_window);
if (v_context == NULL) { 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; 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); glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
// //
RenderView v_view(v_width, v_height);
RenderScene *scene = new RenderScene(); RenderScene *scene = new RenderScene();
int camera_id = scene->addCamera(new RenderCamera()); int camera_id = scene->addCamera(new RenderCamera());
RenderCamera *camera = scene->getCamera(camera_id); 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 // begin our main loop
g_running = 1; g_running = 1;
@ -45,10 +62,16 @@ int main(int argc, char *argv[]) {
g_running = 0; 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); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_GL_SwapWindow(v_window); SDL_GL_SwapWindow(v_window);
SDL_Delay(1); SDL_Delay(1);
} }
SDL_Quit(); SDL_Quit();
return 0; return 0;
} }