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.
parent
8b11fd78f3
commit
082828465c
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
17
src/Mesh.cpp
17
src/Mesh.cpp
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
11
src/Mesh.hpp
11
src/Mesh.hpp
|
@ -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
|
||||
|
|
|
@ -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, ¶ms);
|
||||
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, ¶ms);
|
||||
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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -6,6 +6,7 @@ This header file defines the RenderSet class.
|
|||
#include "RenderSet.hpp"
|
||||
/* ======== Constructors and Destructors ======== */
|
||||
RenderSet::RenderSet() {
|
||||
program = NULL;
|
||||
}
|
||||
RenderSet::~RenderSet() {
|
||||
}
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
83
src/main.cpp
83
src/main.cpp
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue