Added Program class - it is responsible for loading and compiling GLSL shaders into a GLSL program. Much to be changed in regards to its functionality, especially Variable/Texture-related access. Rendering to FBO and displaying via a framebuffer shader works.

master
kts 2015-02-20 19:48:24 -08:00
parent 8b11fd78f3
commit 082828465c
14 changed files with 466 additions and 34 deletions

View File

@ -14,6 +14,9 @@
2056AE3E1A8A421500833760 /* Vec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2056AE3A1A8A421500833760 /* Vec.cpp */; };
205D36CE1A6749FB00C05BD8 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 205D36CD1A6749FB00C05BD8 /* main.cpp */; };
205D370C1A674B1D00C05BD8 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 205D370B1A674B1D00C05BD8 /* OpenGL.framework */; };
206662951A9305FF00631FC0 /* fb_fs.glsl in Copy Shaders */ = {isa = PBXBuildFile; fileRef = 209930A31A92CAB10089E661 /* fb_fs.glsl */; };
206662961A9305FF00631FC0 /* fb_vs.glsl in Copy Shaders */ = {isa = PBXBuildFile; fileRef = 209930A41A92CAB10089E661 /* fb_vs.glsl */; };
209930831A92ADB00089E661 /* Program.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 209930811A92ADB00089E661 /* Program.cpp */; };
20A7A8D51A89E11200EDC1A0 /* RenderScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 20A7A8D11A89E11200EDC1A0 /* RenderScene.cpp */; };
20A7A8D61A89E11200EDC1A0 /* RenderSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 20A7A8D31A89E11200EDC1A0 /* RenderSet.cpp */; };
20A8CE541A899B72004D2504 /* RenderCamera.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 20A8CE501A899B72004D2504 /* RenderCamera.cpp */; };
@ -23,6 +26,31 @@
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
204FF23E1A93F28B0006E1F0 /* Copy Models */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = data/models;
dstSubfolderSpec = 7;
files = (
);
name = "Copy Models";
runOnlyForDeploymentPostprocessing = 0;
};
209930BA1A92CB1C0089E661 /* Copy Shaders */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = data/shaders;
dstSubfolderSpec = 7;
files = (
206662951A9305FF00631FC0 /* fb_fs.glsl in Copy Shaders */,
206662961A9305FF00631FC0 /* fb_vs.glsl in Copy Shaders */,
);
name = "Copy Shaders";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
20020C6F1A8A01EE00F985D8 /* common.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = common.hpp; path = ../../src/common.hpp; sourceTree = SOURCE_ROOT; };
@ -36,6 +64,10 @@
2056AE3B1A8A421500833760 /* Vec.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Vec.hpp; path = ../../src/Vec.hpp; sourceTree = SOURCE_ROOT; };
205D36CD1A6749FB00C05BD8 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../../src/main.cpp; sourceTree = SOURCE_ROOT; };
205D370B1A674B1D00C05BD8 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
209930811A92ADB00089E661 /* Program.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Program.cpp; path = ../../src/Program.cpp; sourceTree = SOURCE_ROOT; };
209930821A92ADB00089E661 /* Program.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Program.hpp; path = ../../src/Program.hpp; sourceTree = SOURCE_ROOT; };
209930A31A92CAB10089E661 /* fb_fs.glsl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = fb_fs.glsl; sourceTree = "<group>"; };
209930A41A92CAB10089E661 /* fb_vs.glsl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = fb_vs.glsl; sourceTree = "<group>"; };
20A7A8D11A89E11200EDC1A0 /* RenderScene.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RenderScene.cpp; path = ../../src/RenderScene.cpp; sourceTree = SOURCE_ROOT; };
20A7A8D21A89E11200EDC1A0 /* RenderScene.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = RenderScene.hpp; path = ../../src/RenderScene.hpp; sourceTree = SOURCE_ROOT; };
20A7A8D31A89E11200EDC1A0 /* RenderSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RenderSet.cpp; path = ../../src/RenderSet.cpp; sourceTree = SOURCE_ROOT; };
@ -69,6 +101,8 @@
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
209930811A92ADB00089E661 /* Program.cpp */,
209930821A92ADB00089E661 /* Program.hpp */,
20E3F2901A8CE8470071FD41 /* Log.cpp */,
20E3F2911A8CE8470071FD41 /* Log.hpp */,
20E3F2921A8CE8470071FD41 /* Mesh.cpp */,
@ -88,8 +122,12 @@
20A8CE521A899B72004D2504 /* RenderView.cpp */,
20A8CE531A899B72004D2504 /* RenderView.hpp */,
);
indentWidth = 2;
name = Classes;
sourceTree = "<group>";
tabWidth = 2;
usesTabs = 0;
wrapsLines = 1;
};
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
@ -122,12 +160,35 @@
children = (
205D36CD1A6749FB00C05BD8 /* main.cpp */,
);
indentWidth = 2;
name = Sources;
sourceTree = "<group>";
tabWidth = 2;
usesTabs = 0;
wrapsLines = 1;
};
2099309F1A92CAB10089E661 /* data */ = {
isa = PBXGroup;
children = (
209930A01A92CAB10089E661 /* shaders */,
);
name = data;
path = ../../data;
sourceTree = SOURCE_ROOT;
};
209930A01A92CAB10089E661 /* shaders */ = {
isa = PBXGroup;
children = (
209930A31A92CAB10089E661 /* fb_fs.glsl */,
209930A41A92CAB10089E661 /* fb_vs.glsl */,
);
path = shaders;
sourceTree = "<group>";
};
29B97314FDCFA39411CA2CEA /* INDIE */ = {
isa = PBXGroup;
children = (
2099309F1A92CAB10089E661 /* data */,
205D36C31A6749DF00C05BD8 /* Sources */,
080E96DDFE201D6D7F000001 /* Classes */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
@ -143,8 +204,11 @@
children = (
20020C6F1A8A01EE00F985D8 /* common.hpp */,
);
indentWidth = 2;
name = "Other Sources";
sourceTree = "<group>";
tabWidth = 2;
usesTabs = 0;
};
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
@ -172,6 +236,8 @@
8D1107290486CEB800E47090 /* Resources */,
8D11072C0486CEB800E47090 /* Sources */,
8D11072E0486CEB800E47090 /* Frameworks */,
209930BA1A92CB1C0089E661 /* Copy Shaders */,
204FF23E1A93F28B0006E1F0 /* Copy Models */,
);
buildRules = (
);
@ -235,6 +301,7 @@
2056AE3E1A8A421500833760 /* Vec.cpp in Sources */,
20E3F2941A8CE8470071FD41 /* Log.cpp in Sources */,
20E3F2951A8CE8470071FD41 /* Mesh.cpp in Sources */,
209930831A92ADB00089E661 /* Program.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -0,0 +1,13 @@
#version 120
// in
varying vec2 UV;
uniform sampler2D tex1;
//
void main() {
gl_FragColor = vec4(texture2D(tex1, UV).xyz, 1.0);
//gl_FragColor = vec4(UV.xy, 1.0, 1.0);
//gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}

View File

@ -0,0 +1,11 @@
#version 120
// in
attribute vec3 vp;
// out
varying vec2 UV;
void main() {
gl_Position = vec4(vp, 1.0);
UV = (vp.xy + vec2(1.0, 1.0)) / 2.0;
///UV = vp.xy;
}

View File

@ -4,11 +4,14 @@
#include <stdlib.h> // atof
Mesh::Mesh() {
vbo = vao = tex = 0;
uvbo = 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) {
uvbo = vbo = vao = tex = 0;
flags = 0;
mode = GL_STATIC_DRAW;
loadArrays(in_vertices, v_count, in_uvs, uv_count, in_normals, n_count);
}
@ -211,15 +214,15 @@ int Mesh::loadArrays(Vec3 *in_vertices, int v_count, Vec2 *in_uvs, int uv_count,
int Mesh::buildMesh() {
if (!(flags & MESH_LOADED)) return 1;
if (flags & MESH_BUILT) destroyMesh();
// generate our vertex array object
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// 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);
// unbind vao to disallow external mucking
glBindVertexArray(0);
// generate our uvs buffer object
glGenBuffers(1, &uvbo);
glBindBuffer(GL_ARRAY_BUFFER, uvbo);
glBufferData(GL_ARRAY_BUFFER, uvs.size()*sizeof(Vec2), &uvs[0], mode);
flags |= MESH_BUILT;
return 0;
}
@ -228,4 +231,4 @@ int Mesh::destroyMesh() {
//glDeleteVertexArrays(1, &vao);
flags &= ~MESH_BUILT;
return 0;
}
}

View File

@ -22,17 +22,18 @@ class Mesh {
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;
GLuint vao; // our mesh vertex attribute object
GLuint vbo; // our mesh vertex buffer object
GLuint uvbo; // our mesh uv buffer object
private:
unsigned int flags; // Flags to signify our status
// 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
#endif

158
src/Program.cpp 100644
View File

@ -0,0 +1,158 @@
/* ================================================================
Program
----------------
This file defines our Program class. This class is responsible for
loading, creating, and compiling OpenGL programs.
================================================================ */
#include "Program.hpp"
#include "Log.hpp"
#include <fstream>
#include <stdexcept> // oor
/* ======== Constructors and Destructors ======== */
Program::Program() {
program = 0;
}
Program::~Program() {
doClean();
}
/* ======== Compilation and Linking ======== */
// add given shader to Program. During doCompile(), it is compiled and attached to the program
int Program::addShader(const char *file, GLenum type) {
// Load in our shader file
std::ifstream in(file);
if (!in) {
LOG(LOG_ERROR) << FUNC_NAME << ": Could not open \"" << file << "\" for reading";
return 1;
}
std::string contents((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
// Create our shader
GLuint shader = glCreateShader(type);
if (shader == 0) {
LOG(LOG_ERROR) << FUNC_NAME << ": Could not create shader for " << file;
return 2;
}
// Load GLSL program into OpenGL
const char *c_str = contents.c_str();
glShaderSource(shader, 1, &c_str, NULL);
// Push the shader and its type onto the appropriate vectors
shader_prog.push_back(shader);
shader_type.push_back(type);
return 0;
}
int Program::doCompile() {
int params = -1; // param return for error checking
char log[2048]; // log for OpenGL info logs
int len = 0; // length of logs
// Let's first create our program
program = glCreateProgram();
// Now we compile our shaders
int i;
for (i = 0; i < shader_prog.size(); i++) {
GLuint shader = shader_prog.at(i);
glCompileShader(shader);
// Let's check for errors
glGetShaderiv(shader, GL_COMPILE_STATUS, &params);
if (params == GL_FALSE) {
glGetShaderInfoLog(shader, 2048, &len, log);
LOG(LOG_ERROR) << FUNC_NAME << ": shader \'" << shader << "\' failed to compile!\n" << log;
return 1;
}
glAttachShader(program, shader);
LOG(LOG_INFO) << FUNC_NAME << ": shader \'" << shader << "\' built and attached to " << program;
}
// Let's link the program
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &params);
if (params != GL_TRUE) {
glGetProgramInfoLog(program, 2048, &len, log);
LOG(LOG_ERROR) << FUNC_NAME << ": failed to link program " << program << "\n" << log;
return 1;
}
LOG(LOG_INFO) << FUNC_NAME << ": program " << program << " successfully built";
return 0;
}
GLuint Program::getProgram() {
return program;
}
/* ======== (De)Activation ======== */
//
int Program::activate() {
glUseProgram(program);
// TODO: foreach texture, activate and bind
/*glActiveTexture(r_texture++);
glBindTexture(GL_TEXTURE_2D, r_view->getFBO());
// FIXME: not sure how else this should be done!
char texture_str[7];
snprintf(texture_str, 7, "tex%d", r_texture);
glUniform1i(glGetUniformLocation(program->getProgram(), texture_str), r_texture-1);*/
int i;
for (i = 0; i < shader_textures.size(); i++) {
glActiveTexture(GL_TEXTURE0 + shader_textures[i].index);
glBindTexture(GL_TEXTURE_2D, shader_textures[i].texture);
glUniform1i(shader_textures[i].location, shader_textures[i].index);
}
return 0;
}
int Program::deactivate() {
// TODO: deactivate textures
int i;
for (i = 0; i < shader_textures.size(); i++) {
// ?? FIXME
}
return 0;
}
/* ======== Cleaning ======== */
int Program::doClean() {
// TODO: glDetachShader
// TODO: glDeleteProgram
return 0;
}
/* ======== Variable interfaces ======== */
// Textures can be "inserted" into a Program via the following function. The texture index position corresponds to an OpenGL texture position as well as the GLSL uniform that matches "tex"+"1-99" (e.g., "tex1").
int Program::attachTexture(GLuint index, GLuint texture) {
if (texture == 0) return 1;
char texture_str[7];
snprintf(texture_str, 7, "tex%d", index);
Texture tex;
tex.index = index;
tex.texture = texture;
tex.location = glGetUniformLocation(program, texture_str);
// Insert it onto the textures record for later usage
shader_textures.insert(shader_textures.begin()+index, tex);
return 0;
}
int Program::setTexture(GLuint index, GLuint texture) {
try {
shader_textures.at(index).texture = texture;
} catch (const std::out_of_range& oor) {
LOG(LOG_WARNING) << FUNC_NAME << ": " << oor.what();
return 1;
}
return 0;
}
GLuint Program::getUniform(const char *name) {
return 0;
}
// VARIABLE
Program::Variable::Variable(VariableType type_) {
data_type = type_;
type = UNDEF;
location = 0;
data = NULL;
length = 0;
switch(data_type) {
case TEXTURE:
length = sizeof(GLuint);
data = (char*)malloc(length);
(*data) = (GLuint)0;
break;
case INT:
break;
}
}
Program::Variable::~Variable() {
if (data != NULL) free(data);
}

59
src/Program.hpp 100644
View File

@ -0,0 +1,59 @@
/* ================================================================
Program
----------------
This file describes our Program class. This class is responsible for
loading, creating, and compiling OpenGL programs.
================================================================ */
#ifndef PROGRAM_HPP
#define PROGRAM_HPP
#include "common.hpp"
#include <vector>
class Program {
//
public:
class Variable {
friend class Program;
public:
enum VariableType {
UNDEF, INT, UINT, FLOAT, DOUBLE, TEXTURE
};
Variable(VariableType type);
~Variable();
protected:
int type; // 0 = uniform, 1 = attribute
GLint location;
int data_type;
char *data;
size_t length;
};
class Texture {
friend class Program;
public:
Texture() { location = -1; index = 0; texture = 0;};
protected:
GLint location;
GLuint index;
GLuint texture;
};
public:
Program();
~Program();
int addShader(const char *file, GLenum type);
int attachTexture(GLuint index, GLuint texture);
int setTexture(GLuint index, GLuint texture);
int doCompile();
int doClean();
GLuint getUniform(const char *name);
GLuint getProgram();
int activate();
int deactivate();
protected:
GLuint program; // Compiled shader program
private:
std::vector<GLenum> shader_type; // Type of shader program, tied to v
std::vector<GLuint> shader_prog; // Compiled shader program, tied to ^
std::vector<GLuint> shader_uniform; // Shader uniform locations
std::vector<Texture> shader_textures;// Textures that this shader uses
std::vector<Variable> shader_variables;
};
#endif

View File

@ -17,7 +17,11 @@ RenderScene::RenderScene() {
RenderScene::~RenderScene() {
}
int RenderScene::renderTo(RenderView *target_view) {
/* renderTo
This function attempts to render the given scene to the target_view using the contained RenderCamera(s).
It iterates over all RenderSets and their RenderObjects and attempts to render to the RenderCamera's attached RenderViews.
*/
int RenderScene::renderTo(RenderView *target_view, Program *render_program) {
RenderCamera *camera;
RenderView *view;
RenderSet *set;
@ -38,9 +42,48 @@ int RenderScene::renderTo(RenderView *target_view) {
}
}
}
// Use this provided program for rendering. Should refer to a framebuffer shader
glUseProgram(render_program->getProgram());
// Bind to the provided target view's fbo
glBindFramebuffer(GL_FRAMEBUFFER, view->fbo);
// Render each of our camera's framebuffers with the appropriate changes
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);
}
return 0;
}
int RenderScene::doRender() {
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);
glClearColor(0.75f, 0.25f, 0.25f, 0.5f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
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;
if (set->program == NULL) continue;
glUseProgram(set->program->getProgram());
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;
// TODO: if object is not in camera's view, continue (probably reverse projection on each corner)
// TODO: enable and attach texture
// TODO: enable vp, uv, normals, and send to shader!
// TODO: maybe other things? Should this be managed by Program somehow?
}
}
}
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 {
@ -78,3 +121,6 @@ RenderCamera* RenderScene::getCamera(int id) {
}
return NULL;
}
std::vector<RenderCamera*> *RenderScene::getCameras() {
return &cameras;
}

View File

@ -12,16 +12,19 @@ each of which correspond to a different scene perspective.
#include "common.hpp"
#include "RenderCamera.hpp"
#include "RenderSet.hpp"
#include "Program.hpp"
#include <vector>
class RenderScene {
public:
RenderScene();
~RenderScene();
int renderTo(RenderView *view);
int doRender();
int renderTo(RenderView *target_view, Program *render_program);
int addCamera(RenderCamera* camera);
int remCamera(RenderCamera* camera);
int remCamera(int id);
RenderCamera* getCamera(int id);
std::vector<RenderCamera*> *getCameras();
private:
std::vector<RenderCamera*> cameras; // Our scene's cameras
std::vector<RenderSet*> sets; // Our scene's render sets

View File

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

View File

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

View File

@ -7,7 +7,7 @@ This file defines our RenderView object.
#include "Log.hpp"
/* ======== Constructors and Destructors ======== */
RenderView::RenderView(int width, int height) {
program = fbo = fbo_depth = fbo_tex = 0;
fbo = fbo_depth = fbo_tex = 0;
w = width;
h = height;
x = y = 0;
@ -19,6 +19,13 @@ RenderView::~RenderView() {
destroyView();
if (mesh != NULL) delete mesh;
}
/* ======== Getters ======== */
GLuint RenderView::getFBO() {
return fbo;
}
Mesh *RenderView::getMesh() {
return mesh;
}
/* ======== Setters ======== */
int RenderView::createView(int width, int height) {
// TODO: call destroyView() and create new FBO at width and height
@ -73,19 +80,16 @@ int RenderView::createView(int width, int height) {
};
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() {
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);
delete mesh;
flags &= ~RENDERVIEW_ACTIVE;
// TODO: delete fbo_vao, fbo_vbo
return 0;
}
int RenderView::setView(int width, int height) {
@ -102,4 +106,4 @@ int RenderView::setView(int width, int height) {
w = width;
h = height;
return 0;
}
}

View File

@ -4,8 +4,7 @@ RenderView
This header file describes our RenderView object.
A RenderView is the target of a RenderCamera and consists of a framebuffer
object and shader program to render said framebuffer. For all intents and
purposes, it is a wrapper around a FBO.
object. For all intents and purposes, it is a wrapper around a FBO.
================================================================ */
#ifndef RENDERVIEW_HPP
#define RENDERVIEW_HPP
@ -17,13 +16,14 @@ class RenderView {
public:
RenderView(int width, int height);
~RenderView();
GLuint getFBO();
Mesh *getMesh();
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_depth; // The fbo depth buffer
GLuint fbo_tex; // The texture of the fbo
int w, h; // width and height of this view (also of fbo)
@ -31,4 +31,4 @@ class RenderView {
Mesh *mesh; // rendering Mesh, created as quad in CreateView
unsigned int flags; // byte flag
};
#endif
#endif

View File

@ -1,10 +1,23 @@
#include "common.hpp"
#include "Program.hpp"
#include "RenderScene.hpp"
#include "RenderView.hpp"
#include "RenderCamera.hpp"
#include "Log.hpp"
#ifdef __APPLE__
#include "CoreFoundation/CoreFoundation.h"
#endif
int main(int argc, char *argv[]) {
#ifdef __APPLE__
char path[PATH_MAX];
CFURLRef res = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
CFURLGetFileSystemRepresentation(res, TRUE, (UInt8 *)path, PATH_MAX);
CFRelease(res);
chdir(path);
#endif
// TEMP location of video vars
SDL_Window *v_window = NULL;
SDL_GLContext v_context = 0;
@ -44,16 +57,36 @@ int main(int argc, char *argv[]) {
SDL_GL_MakeCurrent(v_window, v_context);
// Get our window's FBO id for iOS
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &v_fbo);
// enable depth testing
glEnable(GL_DEPTH_TEST);
//
glDepthFunc(GL_LESS);
// enable back-face culling
//glEnable(GL_CULL_FACE);
LOG(LOG_INFO) << "OpenGL Renderer: " << glGetString(GL_RENDERER) << "\nOpenGL Version: " << glGetString(GL_VERSION);
glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
//
RenderView v_view(v_width, v_height);
// Create our basic RenderScene
RenderScene *scene = new RenderScene();
Program *program = new Program();
if (program->addShader("data/shaders/fb_fs.glsl", GL_FRAGMENT_SHADER) != 0) {
LOG(LOG_ERROR) << "Failed to add Shader!";
return 1;
}
if (program->addShader("data/shaders/fb_vs.glsl", GL_VERTEX_SHADER) != 0) {
LOG(LOG_ERROR) << "Failed to add Shader!";
return 1;
}
if (program->doCompile() != 0) {
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
return 1;
}
int camera_id = scene->addCamera(new RenderCamera());
RenderCamera *camera = scene->getCamera(camera_id);
RenderView *view = new RenderView(v_width, v_height);
camera->setRenderView(view);
camera->setRenderView(new RenderView(v_width, v_height));
program->attachTexture(0, camera->getRenderView()->getFBO());
// begin our main loop
g_running = 1;
@ -63,16 +96,48 @@ int main(int argc, char *argv[]) {
g_running = 0;
}
}
scene->renderTo(&v_view);
scene->doRender(); // Render our main scene using loaded cameras
glBindFramebuffer(GL_FRAMEBUFFER, v_fbo);
//glBindFramebuffer(GL_FRAMEBUFFER, v_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, v_width, v_height);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Alright, let's render our scene to the screen. We bind textures equal to the # of RenderCamera's Renderviews available.
RenderCamera *r_camera;
RenderView *r_view;
std::vector<RenderCamera*>::iterator camera_it, camera_end;
program->activate();
for (camera_it = scene->getCameras()->begin(), camera_end = scene->getCameras()->end(); camera_it != camera_end; ++camera_it) {
r_camera = *camera_it;
if ((r_view = camera->getRenderView()) == NULL) continue;
//
GLuint program_p = program->getProgram();
GLuint program_vp = glGetAttribLocation(program_p, "vp");
// enable vertex positions and UV map
glEnableVertexAttribArray(program_vp);
// Get our mesh
Mesh *mesh = r_view->getMesh();
glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo);
glEnableVertexAttribArray(program_vp);
glVertexAttribPointer(program_vp, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// and draw
glDrawArrays(GL_TRIANGLES, 0, mesh->vertices.size());
// close 'em
glDisableVertexAttribArray(program_vp);
/*glActiveTexture(r_texture++);
glBindTexture(GL_TEXTURE_2D, r_view->getFBO());
// FIXME: not sure how else this should be done!
char texture_str[7];
snprintf(texture_str, 7, "tex%d", r_texture);
glUniform1i(glGetUniformLocation(program->getProgram(), texture_str), r_texture-1);*/
}
program->deactivate();
SDL_GL_SwapWindow(v_window);
SDL_Delay(1);
}
SDL_Quit();
return 0;
}
}