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\main.cpp" />
|
||||
<ClCompile Include="..\..\src\Mat4.cpp" />
|
||||
<ClCompile Include="..\..\src\Mesh.cpp" />
|
||||
<ClCompile Include="..\..\src\RenderCamera.cpp" />
|
||||
<ClCompile Include="..\..\src\RenderObject.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\Log.hpp" />
|
||||
<ClInclude Include="..\..\src\Mat4.hpp" />
|
||||
<ClInclude Include="..\..\src\Mesh.hpp" />
|
||||
<ClInclude Include="..\..\src\RenderCamera.hpp" />
|
||||
<ClInclude Include="..\..\src\RenderObject.hpp" />
|
||||
<ClInclude Include="..\..\src\RenderScene.hpp" />
|
||||
|
|
|
@ -48,6 +48,9 @@
|
|||
<ClCompile Include="..\..\src\Log.cpp">
|
||||
<Filter>Classes</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Mesh.cpp">
|
||||
<Filter>Classes</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\..\Dev\SDL2-2.0.3\lib\x86\SDL2.dll">
|
||||
|
@ -85,5 +88,8 @@
|
|||
<ClInclude Include="..\..\src\Log.hpp">
|
||||
<Filter>Classes</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Mesh.hpp">
|
||||
<Filter>Classes</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
16
src/Log.cpp
16
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);
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
return 0;
|
||||
}
|
||||
/* ======== Getter functions ======== */
|
||||
RenderView* RenderCamera::getRenderView() {
|
||||
return render_view;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -6,6 +6,7 @@ This header file defines the RenderObject class.
|
|||
#include "RenderObject.hpp"
|
||||
/* ======== Constructors and Destructors ======== */
|
||||
RenderObject::RenderObject() {
|
||||
mesh = NULL;
|
||||
}
|
||||
RenderObject::~RenderObject() {
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -4,6 +4,7 @@ RenderScene
|
|||
This header file defines the RenderScene class.
|
||||
================================================================ */
|
||||
#include "RenderScene.hpp"
|
||||
#include "RenderObject.hpp"
|
||||
#include "Log.hpp"
|
||||
#include <stdexcept> // for std::out_of_range
|
||||
#include <iostream> // 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<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
|
||||
int RenderScene::addCamera(RenderCamera* camera) {
|
||||
try {
|
||||
|
|
|
@ -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<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
|
||||
|
|
|
@ -14,12 +14,14 @@ rendering layers of the program.
|
|||
#include "RenderObject.hpp"
|
||||
#include <vector>
|
||||
class RenderSet {
|
||||
friend class RenderScene;
|
||||
public:
|
||||
RenderSet();
|
||||
~RenderSet();
|
||||
private:
|
||||
int mode; // bitflag, 0 = normal, 1 = hide
|
||||
std::vector<RenderObject*> objects; // Our vector of objects to render
|
||||
GLuint program; // Our rendering program
|
||||
protected:
|
||||
std::vector<RenderObject*> objects; // Our vector of objects to render
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -5,13 +5,16 @@ This header provides common includes to SDL2 and OpenGL/OpenGLES
|
|||
#include <TargetConditionals.h>
|
||||
#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 <GL/glew.h>
|
||||
#else
|
||||
#include "SDL_opengl.h"
|
||||
#include "SDL_opengl.h"
|
||||
#endif
|
33
src/main.cpp
33
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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue