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).
parent
28d93f69d3
commit
9ab5b42752
|
@ -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" />
|
||||||
|
|
|
@ -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>
|
16
src/Log.cpp
16
src/Log.cpp
|
@ -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(¤t_time);
|
ltm = localtime(¤t_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);
|
||||||
}
|
}
|
|
@ -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:
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
33
src/main.cpp
33
src/main.cpp
|
@ -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;
|
||||||
}
|
}
|
Loading…
Reference in New Issue