From adcf6cd1b565cd6fba5349c40ce2af2079903a73 Mon Sep 17 00:00:00 2001 From: kts Date: Mon, 23 Feb 2015 02:49:52 -0800 Subject: [PATCH] Added test chest model and basic model rendering shader. Mesh now builds normals buffer along with uv and vp. Added Quaternion class, currently used for RenderObject's rotation matrix generation - needs to be added to RenderCamera. RenderScene now accomplishes what its name implies - the rendering of a scene. Some logic needs to be moved into Program from RenderScene's doRender function. --- build/vs/vs.vcxproj | 6 +- build/vs/vs.vcxproj.filters | 12 ++ data/models/chest.obj | 280 +++++++++++++++++++++++++++++++++++ data/shaders/default_fs.glsl | 11 ++ data/shaders/default_vs.glsl | 16 ++ src/Mesh.cpp | 16 +- src/Mesh.hpp | 2 + src/Quat.cpp | 133 +++++++++++++++++ src/Quat.hpp | 33 +++++ src/RenderCamera.hpp | 6 +- src/RenderObject.cpp | 30 ++++ src/RenderObject.hpp | 8 +- src/RenderScene.cpp | 91 +++++++++++- src/RenderScene.hpp | 5 + src/RenderSet.cpp | 14 ++ src/RenderSet.hpp | 2 + src/main.cpp | 32 +++- 17 files changed, 681 insertions(+), 16 deletions(-) create mode 100644 data/models/chest.obj create mode 100644 data/shaders/default_fs.glsl create mode 100644 data/shaders/default_vs.glsl create mode 100644 src/Quat.cpp create mode 100644 src/Quat.hpp diff --git a/build/vs/vs.vcxproj b/build/vs/vs.vcxproj index 89d9865..8b56c5c 100644 --- a/build/vs/vs.vcxproj +++ b/build/vs/vs.vcxproj @@ -53,7 +53,7 @@ true SDL2.lib;SDL2main.lib;opengl32.lib;glew32.lib;%(AdditionalDependencies) - Windows + Console xcopy /d /y "..\..\..\..\Dev\glew-1.11.0\bin\Release\Win32\glew32.dll" "$(OutDir)" @@ -81,6 +81,7 @@ xcopy /s /e /d /y "..\..\data" "$(OutDir)data\" + @@ -97,6 +98,8 @@ xcopy /s /e /d /y "..\..\data" "$(OutDir)data\" true + + @@ -106,6 +109,7 @@ xcopy /s /e /d /y "..\..\data" "$(OutDir)data\" + diff --git a/build/vs/vs.vcxproj.filters b/build/vs/vs.vcxproj.filters index 034d35d..f1a5393 100644 --- a/build/vs/vs.vcxproj.filters +++ b/build/vs/vs.vcxproj.filters @@ -60,6 +60,9 @@ Classes + + Classes + @@ -74,6 +77,12 @@ Build Copy\data\shaders + + Build Copy\data\shaders + + + Build Copy\data\shaders + @@ -109,5 +118,8 @@ Classes + + Classes + \ No newline at end of file diff --git a/data/models/chest.obj b/data/models/chest.obj new file mode 100644 index 0000000..6232b1d --- /dev/null +++ b/data/models/chest.obj @@ -0,0 +1,280 @@ +# Blender v2.69 (sub 0) OBJ File: 'chest.blend' +# www.blender.org +o Cube_Cube.001 +v -1.000000 -1.000000 1.500000 +v -1.000000 -1.000000 -1.500000 +v 1.000000 -1.000000 -1.500000 +v 1.000000 -1.000000 1.500000 +v -1.000000 0.500000 1.500000 +v -1.000000 0.500000 -1.500000 +v 1.000000 0.500000 -1.500000 +v 1.000000 0.500000 1.500000 +v -0.890000 0.500000 1.500000 +v -0.890000 -1.000000 1.500000 +v -0.890000 -1.000000 -1.500000 +v -0.890000 0.500000 -1.500000 +v -1.000000 0.500000 -1.385000 +v -1.000000 -1.000000 -1.385000 +v 0.890000 -1.000000 -1.385000 +v 0.890000 0.500000 -1.385000 +v 0.890000 -1.000000 1.385000 +v 0.890000 0.500000 1.385000 +v -1.000000 -1.000000 1.385000 +v -1.000000 0.500000 1.385000 +v -1.000000 -0.992500 1.500000 +v 1.000000 -0.992500 1.500000 +v 1.000000 -0.992500 -1.500000 +v -1.000000 -0.992500 -1.500000 +v -0.189709 1.663380 -1.500000 +v -0.189709 1.663380 1.500000 +v 0.005754 1.678334 -1.500000 +v 0.005754 1.678334 1.500000 +v 0.200379 1.654868 -1.500000 +v 0.200379 1.654868 1.500000 +v 0.386686 1.593884 -1.500000 +v 0.386686 1.593884 1.500000 +v 0.557516 1.497724 -1.500000 +v 0.557516 1.497724 1.500000 +v 0.706304 1.370085 -1.500000 +v 0.706304 1.370085 1.500000 +v 0.827331 1.215872 -1.500000 +v 0.827331 1.215872 1.500000 +v 0.915947 1.041010 -1.500000 +v 0.915947 1.041010 1.500000 +v 0.968747 0.852220 -1.500000 +v 0.968747 0.852220 1.500000 +v -1.015822 0.700388 -1.500000 +v -1.015822 0.700388 1.500000 +v -0.992356 0.895013 -1.500000 +v -0.992356 0.895013 1.500000 +v -0.931371 1.081320 -1.500000 +v -0.931371 1.081320 1.500000 +v -0.835212 1.252149 -1.500000 +v -0.835212 1.252150 1.500000 +v -0.707572 1.400937 -1.500000 +v -0.707572 1.400937 1.500000 +v -0.553359 1.521964 -1.500000 +v -0.553359 1.521964 1.500000 +v -0.378497 1.610580 -1.500000 +v -0.378497 1.610580 1.500000 +v -1.000868 0.504925 1.500000 +v -1.000868 0.504925 -1.500000 +v -0.187898 1.653109 -1.485563 +v 0.005527 1.667907 -1.485563 +v 0.005527 1.667907 1.485562 +v -0.187898 1.653109 1.485562 +v 0.198122 1.644686 -1.485563 +v 0.198122 1.644686 1.485562 +v 0.382486 1.584337 -1.485563 +v 0.382486 1.584337 1.485562 +v 0.551534 1.489181 -1.485563 +v 0.551534 1.489181 1.485562 +v 0.698770 1.362873 -1.485563 +v 0.698770 1.362873 1.485563 +v 0.818535 1.210268 -1.485563 +v 0.818535 1.210268 1.485563 +v 0.906227 1.037230 -1.485563 +v 0.906227 1.037230 1.485563 +v 0.959117 0.849527 -1.485000 +v 0.959117 0.849527 1.485000 +v -0.990898 0.505688 -1.485000 +v -1.005396 0.700160 -1.485563 +v -1.005396 0.700161 1.485563 +v -0.990898 0.505688 1.485000 +v -0.982174 0.892755 -1.485563 +v -0.982174 0.892756 1.485563 +v -0.921825 1.077119 -1.485563 +v -0.921825 1.077120 1.485563 +v -0.826669 1.246167 -1.485563 +v -0.826669 1.246168 1.485562 +v -0.700360 1.393403 -1.485563 +v -0.700360 1.393403 1.485562 +v -0.547755 1.513168 -1.485563 +v -0.547755 1.513168 1.485562 +v -0.374717 1.600860 -1.485563 +v -0.374717 1.600860 1.485562 +s 1 +f 5 6 1 +f 6 7 2 +f 7 8 3 +f 8 5 4 +f 1 2 4 +f 9 10 12 +f 6 5 12 +f 2 6 11 +f 1 2 10 +f 5 1 9 +f 13 14 16 +f 16 15 18 +f 18 17 20 +f 5 8 20 +f 1 5 19 +f 4 1 19 +f 8 7 18 +f 3 4 15 +f 7 6 13 +f 2 3 14 +f 6 2 13 +f 21 22 24 +f 2 1 24 +f 3 2 23 +f 4 3 22 +f 1 4 21 +f 25 26 27 +f 27 28 29 +f 29 30 31 +f 31 32 33 +f 33 34 35 +f 35 36 37 +f 37 38 39 +f 39 40 41 +f 58 57 43 +f 43 44 45 +f 45 46 47 +f 47 48 49 +f 49 50 51 +f 51 52 53 +f 55 56 25 +f 53 54 55 +f 28 26 30 +f 25 27 29 +f 59 60 62 +f 60 63 61 +f 63 65 64 +f 65 67 66 +f 67 69 68 +f 69 71 70 +f 71 73 72 +f 73 75 74 +f 77 78 80 +f 78 81 79 +f 81 83 82 +f 83 85 84 +f 85 87 86 +f 87 89 88 +f 91 59 92 +f 89 91 90 +f 80 74 76 +f 73 77 75 +f 58 41 77 +f 42 57 76 +f 57 58 80 +f 41 42 75 +f 6 2 1 +f 7 3 2 +f 8 4 3 +f 5 1 4 +f 2 3 4 +f 10 11 12 +f 5 9 12 +f 6 12 11 +f 2 11 10 +f 1 10 9 +f 14 15 16 +f 15 17 18 +f 17 19 20 +f 8 18 20 +f 5 20 19 +f 17 4 19 +f 7 16 18 +f 4 17 15 +f 16 7 13 +f 3 15 14 +f 2 14 13 +f 22 23 24 +f 1 21 24 +f 2 24 23 +f 3 23 22 +f 4 22 21 +f 26 28 27 +f 28 30 29 +f 30 32 31 +f 32 34 33 +f 34 36 35 +f 36 38 37 +f 38 40 39 +f 40 42 41 +f 57 44 43 +f 44 46 45 +f 46 48 47 +f 48 50 49 +f 50 52 51 +f 52 54 53 +f 56 26 25 +f 54 56 55 +f 50 54 52 +f 56 54 50 +f 57 46 44 +f 42 46 57 +f 32 36 34 +f 32 38 36 +f 30 38 32 +f 30 26 38 +f 26 56 38 +f 56 50 38 +f 38 50 40 +f 50 48 40 +f 48 46 40 +f 46 42 40 +f 55 25 53 +f 25 29 53 +f 29 31 53 +f 53 49 51 +f 53 31 49 +f 31 33 49 +f 33 35 49 +f 45 58 43 +f 45 41 58 +f 35 37 49 +f 37 39 49 +f 39 41 49 +f 41 45 47 +f 49 41 47 +f 60 61 62 +f 63 64 61 +f 65 66 64 +f 67 68 66 +f 69 70 68 +f 71 72 70 +f 73 74 72 +f 75 76 74 +f 78 79 80 +f 81 82 79 +f 83 84 82 +f 85 86 84 +f 87 88 86 +f 89 90 88 +f 59 62 92 +f 91 92 90 +f 79 74 80 +f 72 68 70 +f 72 66 68 +f 64 66 72 +f 79 72 74 +f 82 72 79 +f 92 88 90 +f 92 86 88 +f 92 84 86 +f 64 72 82 +f 61 64 62 +f 64 82 62 +f 82 84 92 +f 62 82 92 +f 73 78 77 +f 63 67 65 +f 63 69 67 +f 85 89 87 +f 91 89 85 +f 81 85 83 +f 91 85 81 +f 71 78 73 +f 63 71 69 +f 63 78 71 +f 60 59 63 +f 63 59 78 +f 59 91 78 +f 91 81 78 +f 41 75 77 +f 57 80 76 +f 58 77 80 +f 42 76 75 diff --git a/data/shaders/default_fs.glsl b/data/shaders/default_fs.glsl new file mode 100644 index 0000000..7782979 --- /dev/null +++ b/data/shaders/default_fs.glsl @@ -0,0 +1,11 @@ +#version 120 + +// uniform data +uniform sampler2D texture_sampler; +// in +varying vec2 frag_uv; + +void main() { + //gl_FragColor = texture2D(texture_sampler, frag_uv); + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); +} diff --git a/data/shaders/default_vs.glsl b/data/shaders/default_vs.glsl new file mode 100644 index 0000000..35d6648 --- /dev/null +++ b/data/shaders/default_vs.glsl @@ -0,0 +1,16 @@ +#version 120 +// shared data +// our projection and translation matrices +uniform mat4 proj_matrix, mv_matrix; +// attributes +attribute vec3 vp; +attribute vec2 uv; +attribute vec3 normal; +// out +varying vec2 frag_uv; + +void main() { + vec4 eye = mv_matrix * vec4(vp, 1.0); + gl_Position = proj_matrix * eye; + frag_uv = uv; +} \ No newline at end of file diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 8e2f12f..4e6b4f6 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -1,15 +1,22 @@ #include "Mesh.hpp" +#include "Log.hpp" #include // fscanf #include // strcmp #include // atof Mesh::Mesh() { - uvbo = vbo = vao = tex = 0; + nbo = uvbo = vbo = vao = tex = 0; flags = 0; mode = GL_STATIC_DRAW; } +Mesh::Mesh(const char *filename) { + nbo = uvbo = vbo = vao = tex = 0; + flags = 0; + mode = GL_STATIC_DRAW; + loadObj(filename); +} 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; + nbo = uvbo = vbo = vao = tex = 0; flags = 0; mode = GL_STATIC_DRAW; loadArrays(in_vertices, v_count, in_uvs, uv_count, in_normals, n_count); @@ -35,6 +42,7 @@ int Mesh::loadObj(const char *filename) { #endif if (file == NULL) { // TODO: error report + LOG(LOG_ERROR) << "Could not open model: " << filename; return 1; } char word[32]; @@ -222,6 +230,10 @@ int Mesh::buildMesh() { glGenBuffers(1, &uvbo); glBindBuffer(GL_ARRAY_BUFFER, uvbo); glBufferData(GL_ARRAY_BUFFER, uvs.size()*sizeof(Vec2), &uvs[0], mode); + // generate our normals buffer object + glGenBuffers(1, &nbo); + glBindBuffer(GL_ARRAY_BUFFER, nbo); + glBufferData(GL_ARRAY_BUFFER, normals.size()*sizeof(Vec3), &normals[0], mode); flags |= MESH_BUILT; return 0; diff --git a/src/Mesh.hpp b/src/Mesh.hpp index 69e55b5..1cbea71 100644 --- a/src/Mesh.hpp +++ b/src/Mesh.hpp @@ -15,6 +15,7 @@ A Mesh is as the name indicates, a 3D mesh. class Mesh { public: Mesh(); + Mesh(const char *filename); Mesh(Vec3 *in_vertices, int v_count, Vec2 *in_uvs, int uv_count, Vec3 *in_normals, int n_count); ~Mesh(); // @@ -29,6 +30,7 @@ class Mesh { GLuint vao; // our mesh vertex attribute object GLuint vbo; // our mesh vertex buffer object GLuint uvbo; // our mesh uv buffer object + GLuint nbo; // our mesh normal buffer object private: unsigned int flags; // Flags to signify our status // reference to GPU objects diff --git a/src/Quat.cpp b/src/Quat.cpp new file mode 100644 index 0000000..7316747 --- /dev/null +++ b/src/Quat.cpp @@ -0,0 +1,133 @@ +/* ================================================================ +Quat +```````````````` +This file defines the Quaternion class +================================================================ */ +#include "Quat.hpp" +#include +#define PIOVER180 0.01745329252 +Quat::Quat() { + x = y = z = w = 0.0f; +}; +Quat::Quat(float x_, float y_, float z_, float w_) { + x = x_; + y = y_; + z = z_; + w = w_; +} +// Tait-bryan angles to Quat constructor +Quat::Quat(float pitch, float yaw, float roll) { + float cp = (float)cos(pitch * PIOVER180 / 2.0f); + float cy = (float)cos(-yaw * PIOVER180 / 2.0f); + float cr = (float)cos(-roll * PIOVER180 / 2.0f); + float cycr = cy * cr; + float sp = (float)sin(pitch * PIOVER180 / 2.0f); + float sy = (float)sin(-yaw * PIOVER180 / 2.0f); + float sr = (float)sin(-roll * PIOVER180 / 2.0f); + float srsy = sr * sy; + + x = cycr * sp + srsy * cp; + y = cr * sy * cp - sr * cy * sp; + z = sr * cy * cp + cr * sy * sp; + w = cycr * cp - srsy * sp; + normalize(); +} +Quat::Quat(const Vec3 &v, float angle) { + angle *= 0.5f; + Vec3 vn(v); + vn.normalize(); + + float sin_angle = sin(angle); + + x = vn.x * sin_angle; + y = vn.y * sin_angle; + z = vn.z * sin_angle; + w = cos(angle); +} +Quat Quat::operator*(const Quat &quat_) const { + Quat new_Quat; + new_Quat.x = w*quat_.x + x*quat_.w + y*quat_.z - z*quat_.y; + new_Quat.y = w*quat_.y + y*quat_.w + z*quat_.x - x*quat_.z; + new_Quat.z = w*quat_.z + z*quat_.w + x*quat_.y - y*quat_.x; + new_Quat.w = w*quat_.w - x*quat_.x - y*quat_.y - z*quat_.z; + + return new_Quat; +} +Quat::~Quat() {} +// rotate Vec3 by Quat +Vec3 Quat::operator*(const Vec3 &vec) const { + Vec3 newvec(vec); + newvec.normalize(); + + Quat vec_quat, res_quat; + vec_quat.x = newvec.x; + vec_quat.y = newvec.y; + vec_quat.z = newvec.z; + vec_quat.w = 0.0f; + + res_quat = vec_quat * getConjugate(); + res_quat = *this * res_quat; + return (Vec3(res_quat.x, res_quat.y, res_quat.z)); +} +void Quat::operator*=(const Quat &quat_) { + w = w*quat_.w - x*quat_.x - y*quat_.y - z*quat_.z; + x = w*quat_.x + x*quat_.w + y*quat_.z - z*quat_.y; + y = w*quat_.y - x*quat_.z + y*quat_.w + z*quat_.x; + z = w*quat_.z + x*quat_.y - y*quat_.x + z*quat_.w; +} + +void Quat::normalize() { + float magnitude = sqrt(w*w + x*x + y*y + z*z); + x /= magnitude; + y /= magnitude; + z /= magnitude; + w /= magnitude; +} + +Quat Quat::getConjugate() const { + return Quat(-x, -y, -z, w); +} +float Quat::getPitch() { + return asin(2.0f * (w * x - z * y)); +} +float Quat::getYaw() { + return atan2(2.0f * (w * y + x * z), 1.0f - 2.0f * (x * x + y * y)); +} +float Quat::getRoll() { + return atan2(2.0f * (w * z + y * x), 1.0f - 2.0f * (x * x + z * z)); +} +Mat4 Quat::toMat4() const { + float x2 = x * x; + float y2 = y * y; + float z2 = z * z; + float xy = x * y; + float xz = x * z; + float yz = y * z; + float wx = w * x; + float wy = w * y; + float wz = w * z; + + return Mat4( + Vec4(1.0f - 2.0f * (y2 + z2), 2.0f * (xy - wz), 2.0f * (xz + wy), 0.0f), + Vec4(2.0f * (xy + wz), 1.0f - 2.0f * (x2 + z2), 2.0f * (yz - wx), 0.0f), + Vec4(2.0f * (xz - wy), 2.0f * (yz + wx), 1.0f - 2.0f * (x2 + y2), 0.0f), + Vec4(0.0f, 0.0f, 0.0f, 1.0f) + ); +} +float *Quat::toMatrix(float matrix[]) const { + float x2 = x * x; + float y2 = y * y; + float z2 = z * z; + float xy = x * y; + float xz = x * z; + float yz = y * z; + float wx = w * x; + float wy = w * y; + float wz = w * z; + + matrix[0] = 1.0f - 2.0f * (y2 + z2); matrix[1] = 2.0f * (xy - wz); matrix[2] = 2.0f * (xz + wy); matrix[3] = 0.0f; + matrix[4] = 2.0f * (xy + wz); matrix[5] = 1.0f - 2.0f * (x2 + z2); matrix[6] = 2.0f * (yz - wx); matrix[7] = 0.0f; + matrix[8] = 2.0f * (xz - wy); matrix[9] = 2.0f * (yz + wx); matrix[10] = 1.0f - 2.0f * (x2 + y2); matrix[11] = 0.0f; + matrix[12] = 0.0f; matrix[13] = 0.0f; matrix[14] = 0.0f; matrix[15] = 1.0f; + return matrix; +} diff --git a/src/Quat.hpp b/src/Quat.hpp new file mode 100644 index 0000000..8406049 --- /dev/null +++ b/src/Quat.hpp @@ -0,0 +1,33 @@ +/* ================================================================ +Quat +```````````````` +This header file describes the Quaternion class +================================================================ */ +#ifndef QUAT_HPP +#define QUAT_HPP +#include "Vec.hpp" +#include "Mat4.hpp" +class Quat { + public: + Quat(); + Quat(float x_, float y_, float z_, float w_); // manual constructor + Quat(float pitch, float yaw, float roll); // euler angle constructor + Quat(const Vec3 &v, float angle); // axis-angle constructor + ~Quat(); + // + float x, y, z, w; + // + Quat operator*(const Quat &quat_) const; + Vec3 operator*(const Vec3 &vec) const; + + void operator*=(const Quat &quat_); + + void normalize(); + Quat getConjugate() const; + float getPitch(); + float getYaw(); + float getRoll(); + Mat4 toMat4() const; + float *toMatrix(float matrix[]) const; +}; +#endif \ No newline at end of file diff --git a/src/RenderCamera.hpp b/src/RenderCamera.hpp index 9ced4fa..a609cb8 100644 --- a/src/RenderCamera.hpp +++ b/src/RenderCamera.hpp @@ -13,11 +13,15 @@ RenderScene and outputs all data to the friend class, RenderView. #include "RenderView.hpp" #include "Vec.hpp" #include "Mat4.hpp" -#define DIRTY (1 << 1) + class RenderCamera { + friend class RenderScene; public: RenderCamera(); ~RenderCamera(); + enum Flags { + DIRTY = (1 << 1) + }; int setRenderView(RenderView *view); RenderView* getRenderView(); void updateProjection(int width, int height); diff --git a/src/RenderObject.cpp b/src/RenderObject.cpp index 8779266..8740a3c 100644 --- a/src/RenderObject.cpp +++ b/src/RenderObject.cpp @@ -4,9 +4,39 @@ RenderSet This header file defines the RenderObject class. ================================================================ */ #include "RenderObject.hpp" +#include "Vec.hpp" +#include "Quat.hpp" /* ======== Constructors and Destructors ======== */ RenderObject::RenderObject() { mesh = NULL; + translation = Mat4( + Vec4(1.0, 0.0, 0.0, 0.0), + Vec4(0.0, 1.0, 0.0, 0.0), + Vec4(0.0, 0.0, 1.0, 0.0), + Vec4(0.0, 0.0, 0.0, 1.0) + ); + rotation = scale = translation; + calcMatrix(); } RenderObject::~RenderObject() { +} +void RenderObject::setMesh(Mesh *new_mesh) { + mesh = new_mesh; +} +void RenderObject::setTranslation(float x, float y, float z) { + translation[3][0] = x; + translation[3][1] = y; + translation[3][2] = z; +} +void RenderObject::setRotation(float pitch, float yaw, float roll) { + Quat quat(pitch, yaw, roll); + rotation = quat.toMat4(); +} +void RenderObject::setScale(float x, float y, float z) { + scale[0][0] = x; + scale[1][1] = y; + scale[2][2] = z; +} +void RenderObject::calcMatrix() { + model = translation * rotation * scale; } \ No newline at end of file diff --git a/src/RenderObject.hpp b/src/RenderObject.hpp index 8937035..f355231 100644 --- a/src/RenderObject.hpp +++ b/src/RenderObject.hpp @@ -14,15 +14,21 @@ a Mesh, a texture, a position, and an orientation. #include "Mat4.hpp" class RenderObject { friend class RenderSet; + friend class RenderScene; public: RenderObject(); ~RenderObject(); + void calcMatrix(); + void setTranslation(float x, float y, float z); + void setRotation(float pitch, float roll, float yaw); + void setScale(float x, float y, float z); + void setMesh(Mesh *new_mesh); private: Mesh *mesh; // GLuint texture; Mat4 translation; Mat4 rotation; Mat4 scale; - Mat4 modelview; + Mat4 model; }; #endif \ No newline at end of file diff --git a/src/RenderScene.cpp b/src/RenderScene.cpp index 876369d..a3fa130 100644 --- a/src/RenderScene.cpp +++ b/src/RenderScene.cpp @@ -59,32 +59,64 @@ int RenderScene::doRender() { RenderView *view; RenderSet *set; RenderObject *object; + // Begin iteration over the scene's cameras std::vector::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; + if ((view = camera->getRenderView()) == NULL) continue; // bail if camera has no rendering target glBindFramebuffer(GL_FRAMEBUFFER, view->fbo); - glClearColor(0.75f, 0.25f, 0.25f, 0.5f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - + // Iterate over the scene's render sets std::vector::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()); + if (set->program == NULL) continue; // bail if set has no rendering program to use + GLuint glsl_program = set->program->getProgram(); + //LOG(LOG_INFO) << "set program is: " << glsl_program; + glUseProgram(glsl_program); + // FIXME: We are temporarily getting the locations here - this needs to be moved elsewhere (Program?) + GLuint shader_projection = glGetUniformLocation(glsl_program, "proj_matrix"); + GLuint shader_modelview = glGetUniformLocation(glsl_program, "mv_matrix"); + GLuint shader_vp = glGetAttribLocation(glsl_program, "vp"); + GLuint shader_uv = glGetAttribLocation(glsl_program, "uv"); + GLuint shader_normal = glGetAttribLocation(glsl_program, "normal"); + // Send the camera's perspective + float pm[16]; + glUniformMatrix4fv(shader_projection, 1, GL_FALSE, camera->p_matrix.toFloats(pm)); + // enable attribs + glEnableVertexAttribArray(shader_vp); + glEnableVertexAttribArray(shader_uv); + glEnableVertexAttribArray(shader_normal); + // Iterate over the set's render objects std::vector::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; + Mat4 mv_matrix; // modelview matrix + float mv[16]; // converted modelview to send to OpenGL + Mesh *mesh; + if ((mesh = object->mesh) == NULL) continue; // No mesh to render with, bail // TODO: if object is not in camera's view, continue (probably reverse projection on each screen corner) - // TODO: get modelview matrix (renderobject matrix * camera matrix) and send to shader + // send computed modelview to shader + mv_matrix = camera->mv_matrix * object->model; + glUniformMatrix4fv(shader_modelview, 1, GL_FALSE, mv_matrix.toFloats(mv)); // TODO: enable and attach texture - // TODO: enable vp, uv, normals, and send to shader! + // bind vp + glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); + glVertexAttribPointer(shader_vp, 3, GL_FLOAT, GL_FALSE, 0, NULL); + // bind uvs/texture coords + glBindBuffer(GL_ARRAY_BUFFER, mesh->uvbo); + glVertexAttribPointer(shader_uv, 2, GL_FLOAT, GL_FALSE, 0, 0); + // bind normals + glBindBuffer(GL_ARRAY_BUFFER, mesh->nbo); + glVertexAttribPointer(shader_normal, 3, GL_FLOAT, GL_FALSE, 0, NULL); + glDrawArrays(GL_TRIANGLES, 0, mesh->vertices.size()); // TODO: maybe other things? Should this be managed by Program somehow? } } } return 0; } +/* ======== Camera Functionality ======== */ // This function adds the ptr to Camera and returns its "id" which is simply its index+1 int RenderScene::addCamera(RenderCamera* camera) { try { @@ -95,6 +127,7 @@ int RenderScene::addCamera(RenderCamera* camera) { // return size regardless of success, likely The Wrong Thing return cameras.size(); } +// Remove camera by ID int RenderScene::remCamera(int id) { RenderCamera *camera = getCamera(id); if (camera) { @@ -104,6 +137,7 @@ int RenderScene::remCamera(int id) { LOG(LOG_WARNING) << FUNC_NAME << ": Could not remove RenderCamera " << id; return 1; } +// Remove camera by pointer int RenderScene::remCamera(RenderCamera *camera) { std::vector::iterator it; if ((it = std::find(cameras.begin(), cameras.end(), camera)) != cameras.end()) { @@ -113,7 +147,7 @@ int RenderScene::remCamera(RenderCamera *camera) { LOG(LOG_WARNING) << FUNC_NAME << ": Could not remove RenderCamera"; return 1; } - +// Get camera by ID RenderCamera* RenderScene::getCamera(int id) { try { return cameras.at(id-1); @@ -122,6 +156,47 @@ RenderCamera* RenderScene::getCamera(int id) { } return NULL; } +// Get cameras vector std::vector *RenderScene::getCameras() { return &cameras; } +/* ======== RenderSet Functionality ======== */ +int RenderScene::addSet(RenderSet* set) { + try { + sets.push_back(set); + } catch(...) { + LOG(LOG_ERROR) << FUNC_NAME << ": Could not add RenderSet"; + } + // return size regardless of success, likely The Wrong Thing + return sets.size(); +} +int RenderScene::remSet(int id) { + RenderSet *set = getSet(id); + if (set) { + sets.erase(sets.begin()+(id-1)); + return 0; + } + LOG(LOG_WARNING) << FUNC_NAME << ": Could not remove RenderSet " << id; + return 1; +} +int RenderScene::remSet(RenderSet *set) { + std::vector::iterator it; + if ((it = std::find(sets.begin(), sets.end(), set)) != sets.end()) { + sets.erase(it); + return 0; + } + LOG(LOG_WARNING) << FUNC_NAME << ": Could not remove RenderSet"; + return 1; +} + +RenderSet* RenderScene::getSet(int id) { + try { + return sets.at(id-1); + } catch (const std::out_of_range& oor) { + LOG(LOG_ERROR) << FUNC_NAME << ": RenderSet index out of range: " << oor.what(); + } + return NULL; +} +std::vector *RenderScene::getSets() { + return &sets; +} \ No newline at end of file diff --git a/src/RenderScene.hpp b/src/RenderScene.hpp index 50ff34b..35b4fbe 100644 --- a/src/RenderScene.hpp +++ b/src/RenderScene.hpp @@ -25,6 +25,11 @@ class RenderScene { int remCamera(int id); RenderCamera* getCamera(int id); std::vector *getCameras(); + int addSet(RenderSet *set); + int remSet(RenderSet *set); + int remSet(int id); + RenderSet* getSet(int id); + std::vector *getSets(); private: std::vector cameras; // Our scene's cameras std::vector sets; // Our scene's render sets diff --git a/src/RenderSet.cpp b/src/RenderSet.cpp index 4895c8f..99e9ee6 100644 --- a/src/RenderSet.cpp +++ b/src/RenderSet.cpp @@ -4,9 +4,23 @@ RenderSet This header file defines the RenderSet class. ================================================================ */ #include "RenderSet.hpp" +#include "Log.hpp" /* ======== Constructors and Destructors ======== */ RenderSet::RenderSet() { program = NULL; } RenderSet::~RenderSet() { +} +int RenderSet::addObject(RenderObject *object) { + try { + objects.push_back(object); + } catch(...) { + LOG(LOG_ERROR) << FUNC_NAME << ": Could not add RenderObject"; + return 1; + } + return 0; +} +int RenderSet::setProgram(Program *prog) { + program = prog; + return 0; } \ No newline at end of file diff --git a/src/RenderSet.hpp b/src/RenderSet.hpp index bd25918..06b203e 100644 --- a/src/RenderSet.hpp +++ b/src/RenderSet.hpp @@ -19,6 +19,8 @@ class RenderSet { public: RenderSet(); ~RenderSet(); + int addObject(RenderObject *object); + int setProgram(Program *prog); private: int mode; // bitflag, 0 = normal, 1 = hide Program *program; // Our rendering program diff --git a/src/main.cpp b/src/main.cpp index 792a2d1..51a423c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,7 +9,6 @@ #include "CoreFoundation/CoreFoundation.h" #endif - int main(int argc, char *argv[]) { #ifdef __APPLE__ char path[PATH_MAX]; @@ -67,7 +66,7 @@ int main(int argc, char *argv[]) { // // Create our basic RenderScene RenderScene *scene = new RenderScene(); - + // TEMP: our framebuffer rendering program Program *program = new Program(); if (program->addShader("data/shaders/fb_fs.glsl", GL_FRAGMENT_SHADER) != 0) { LOG(LOG_ERROR) << "Failed to add Shader!"; @@ -81,14 +80,42 @@ int main(int argc, char *argv[]) { LOG(LOG_ERROR) << "Failed to compile GLSL Program!"; return 1; } + // TEMP: our model rendering program + Program *program_model = new Program(); + if (program_model->addShader("data/shaders/default_fs.glsl", GL_FRAGMENT_SHADER) != 0) { + LOG(LOG_ERROR) << "Failed to add Shader!"; + return 1; + } + if (program_model->addShader("data/shaders/default_vs.glsl", GL_VERTEX_SHADER) != 0) { + LOG(LOG_ERROR) << "Failed to add Shdaer!"; + return 1; + } + if (program_model->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); camera->setRenderView(new RenderView(v_width, v_height)); + camera->updateProjection(v_width, v_height); + camera->setPitch(70.0f); + camera->setPosition(0, 35, -10); + camera->doRefresh(); program->attachTexture(0, camera->getRenderView()->getFBO()); + RenderObject *objerct = new RenderObject(); + Mesh *mersh = new Mesh("data/models/chest.obj"); + mersh->buildMesh(); + objerct->setMesh(mersh); + RenderSet *sert = new RenderSet(); + sert->setProgram(program_model); + sert->addObject(objerct); + scene->addSet(sert); + // begin our main loop + glClearColor(1.0f, 1.0f, 1.0f, 0.0f); g_running = 1; while (g_running) { while (SDL_PollEvent(&event)) { @@ -101,7 +128,6 @@ int main(int argc, char *argv[]) { //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;