From 8c987af31390e33f7a5f49ecceb9e84cebde2f18 Mon Sep 17 00:00:00 2001 From: Anselme Date: Tue, 15 Aug 2017 17:18:34 +0200 Subject: [PATCH] updated the deferred pipeline to use PBR, and added skybox to its workflow --- CMakeLists.txt.user.6bc6d81 | 248 +++++++++++++++++++++++++++ shaders/gbuffer.frag.glsl | 78 +++++---- shaders/gbuffer.vert.glsl | 3 - shaders/gui.frag.glsl | 8 +- shaders/lighting.frag.glsl | 148 +++++++++++----- shaders/posteffects.frag.glsl | 7 + src/deferredpipeline.cpp | 53 +++--- src/deferredpipeline.h | 8 +- src/forwardmodule.cpp | 2 +- src/light.cpp | 18 +- src/light.h | 10 +- src/mesh.cpp | 5 +- src/mesh.h | 15 +- src/model.cpp | 93 ---------- src/model.h | 78 --------- src/parametricmesh.cpp | 2 +- src/pbrmaterial.cpp | 75 ++++++++ src/pbrmaterial.h | 52 ++++++ src/phongmaterial.cpp | 142 --------------- src/phongmaterial.h | 66 ------- src/{skyboxmodule.cpp => skybox.cpp} | 51 +++--- src/skybox.h | 35 ++++ src/skyboxmodule.h | 38 ---- 23 files changed, 665 insertions(+), 570 deletions(-) create mode 100644 CMakeLists.txt.user.6bc6d81 delete mode 100644 src/model.cpp delete mode 100644 src/model.h create mode 100644 src/pbrmaterial.cpp create mode 100644 src/pbrmaterial.h delete mode 100644 src/phongmaterial.cpp delete mode 100644 src/phongmaterial.h rename src/{skyboxmodule.cpp => skybox.cpp} (69%) create mode 100644 src/skybox.h delete mode 100644 src/skyboxmodule.h diff --git a/CMakeLists.txt.user.6bc6d81 b/CMakeLists.txt.user.6bc6d81 new file mode 100644 index 0000000..6248c57 --- /dev/null +++ b/CMakeLists.txt.user.6bc6d81 @@ -0,0 +1,248 @@ + + + + + + EnvironmentId + {6bc6d814-5082-4cc7-a3fd-c0503e9952d9} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.8.0 MinGW 32bit + Desktop Qt 5.8.0 MinGW 32bit + qt.58.win32_mingw53_kit + 1 + 0 + 0 + + + CMAKE_BUILD_TYPE:STRING=Debug + CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + CMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} + QT_QMAKE_EXECUTABLE:STRING=C:/Qt/5.7/mingw53_32/bin/qmake.exe + + C:/Users/Anselme/git/SparrowRenderer/build-Debug + + + + + all + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Build + + ProjectExplorer.BuildSteps.Build + + + + + + clean + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Debug + CMakeProjectManager.CMakeBuildConfiguration + + + + CMAKE_BUILD_TYPE:STRING=Release + CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx} + CMAKE_C_COMPILER:STRING=%{Compiler:Executable:C} + QT_QMAKE_EXECUTABLE:STRING=C:/Qt/5.7/mingw53_32/bin/qmake.exe + + C:/Users/Anselme/git/SparrowRenderer/build-Release + + + + + all + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Build + + ProjectExplorer.BuildSteps.Build + + + + + + clean + + true + Make + + CMakeProjectManager.MakeStep + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Release + CMakeProjectManager.CMakeBuildConfiguration + + 2 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy locally + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + SparrowResource + + + C:/Users/Anselme/git/SparrowRenderer/build-Release + 2 + + SparrowResource + + CMakeProjectManager.CMakeRunConfiguration.SparrowResource + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/shaders/gbuffer.frag.glsl b/shaders/gbuffer.frag.glsl index 9545128..7574831 100644 --- a/shaders/gbuffer.frag.glsl +++ b/shaders/gbuffer.frag.glsl @@ -1,34 +1,38 @@ // - Position in view space layout (location = 0) out vec4 outPosition; -// - Color + objectId buffer -layout (location = 1) out vec4 outColor; +// - Albedo + Roughness +layout (location = 1) out vec4 outAlbedo; // - Normal buffer layout (location = 2) out vec3 outNormal; -// - Specular color + Specular exponent buffer -layout (location = 3) out vec4 outSpecular; - -uniform float materialNs; - -// variables used for picking -uniform int object_identifier; -#ifdef INSTANCED -flat in int instanceId; -#endif +// - Emission + Metallic +layout (location = 3) out vec4 outEmission; #ifdef ALPHA_MASK uniform sampler2D alphaMask; #endif -#ifdef DIFFUSE_TEXTURE -uniform sampler2D diffuseTexture; +#ifdef ALBEDO_TEXTURE +uniform sampler2D albedoTexture; #else -uniform vec3 materialKd; +uniform vec3 albedo; #endif -#ifdef SPECULAR_TEXTURE -uniform sampler2D specularTexture; +#ifdef EMISSION_TEXTURE +uniform sampler2D emissionTexture; #else -uniform vec3 materialKs; +uniform vec3 emission; +#endif + +#ifdef ROUGHNESS_TEXTURE +uniform sampler2D roughnessTexture; +#else +uniform float roughness; +#endif + +#ifdef METALLIC_TEXTURE +uniform sampler2D metallicTexture; +#else +uniform float metallic; #endif in vec4 posInView; @@ -50,9 +54,11 @@ in vec2 varTexCoord; void main() { #ifdef WIREFRAME - outColor.rgb = varColor; - outNormal = vec3(0., 0., 1.); - outSpecular = vec4(0., 0., 0., 1.); + outAlbedo.rgb = vec3(0., 0., 0.); // black + outAlbedo.a = 1.; // full roughness + outEmission.rgb = varColor; + outEmission.a = 0.; // not metallic + outNormal = vec3(0., 0., 1.); // oriented towards the eye #else #ifdef ALPHA_MASK @@ -74,27 +80,31 @@ void main() outNormal = normalize(varNormal); #endif -#ifdef DIFFUSE_TEXTURE - outColor.rgb = texture(diffuseTexture, varTexCoord).rgb; +#ifdef ALBEDO_TEXTURE + outAlbedo.rgb = texture(albedoTexture, varTexCoord).rgb; #else - outColor.rgb = materialKd; + outAlbedo.rgb = albedo; #endif -#ifdef SPECULAR_TEXTURE - outSpecular.rgb = texture(specularTexture, varTexCoord).rgb; +#ifdef ROUGHNESS_TEXTURE + outAlbedo.a = texture(roughnessTexture, varTexCoord).r; #else - outSpecular.rgb = materialKs; + outAlbedo.a = roughness; #endif - outSpecular.w = float(materialNs)/255; +#ifdef EMISSION_TEXTURE + outEmission.rgb = texture(emissionTexture, varTexCoord).rgb; +#else + outEmission.rgb = emission; +#endif + +#ifdef METALLIC_TEXTURE + outEmission.a = texture(metallicTexture, varTexCoord).r; +#else + outEmission.a = metallic; +#endif #endif // WIREFRAME -#ifdef INSTANCED - outColor.a = float(object_identifier+instanceId)/255; -#else - outColor.a = float(object_identifier)/255; -#endif - outPosition = posInView; } diff --git a/shaders/gbuffer.vert.glsl b/shaders/gbuffer.vert.glsl index 82dc487..88bd105 100644 --- a/shaders/gbuffer.vert.glsl +++ b/shaders/gbuffer.vert.glsl @@ -26,8 +26,6 @@ layout(location = 4)in vec3 inBinormal; #ifdef INSTANCED layout(location = 5)in vec3 inInstanceOffset; - -flat out int instanceId; #endif void main(void) { @@ -48,7 +46,6 @@ void main(void) { // computing positions #ifdef INSTANCED - instanceId = gl_InstanceID; vec4 pos = vec4(inPosition + inInstanceOffset, 1.0); #else vec4 pos = vec4(inPosition, 1.0); diff --git a/shaders/gui.frag.glsl b/shaders/gui.frag.glsl index 6421896..2421dd8 100644 --- a/shaders/gui.frag.glsl +++ b/shaders/gui.frag.glsl @@ -5,9 +5,9 @@ in vec2 texCoord; #endif #ifdef DIFFUSE_TEXTURE -uniform sampler2D diffuseTexture; +uniform sampler2D albedoTexture; #else -uniform vec3 materialKd; +uniform vec3 albedo; #endif #ifdef ALPHA_MASK @@ -25,9 +25,9 @@ layout(location = 0)out vec4 outColor; void main(void) { #ifdef DIFFUSE_TEXTURE - vec3 color = texture(diffuseTexture, texCoord).rgb; + vec3 color = texture(albedoTexture, texCoord).rgb; #else - vec3 color = materialKd; + vec3 color = albedo; #endif #ifdef ALPHA_MASK diff --git a/shaders/lighting.frag.glsl b/shaders/lighting.frag.glsl index 6cf27d3..54dfe17 100644 --- a/shaders/lighting.frag.glsl +++ b/shaders/lighting.frag.glsl @@ -2,18 +2,24 @@ // - Position in view space uniform sampler2DRect positionBuffer; -// - Color + objectId buffer -uniform sampler2DRect colorBuffer; +// - Albedo + Roughness +uniform sampler2DRect albedoBuffer; // - Normal buffer uniform sampler2DRect normalBuffer; -// - Specular color + Specular exponent buffer -uniform sampler2DRect specularBuffer; +// - Emission + Metallic +uniform sampler2DRect emissionBuffer; // - depth buffer uniform sampler2DRect depthBuffer; // LIGHT ATTRIBUTES - +#ifdef AMBIENT_LIGHT +uniform samplerCube ambientMap; +uniform samplerCube reflectMap; +uniform sampler2D brdfLUT; +uniform mat3 inverseViewMatrix; +#else uniform vec3 lightColor; +#endif #ifdef SHADOWMAP #ifdef POINT_LIGHT @@ -47,61 +53,109 @@ uniform mat4 inverseProjectionMatrix; layout(location = 0)out vec4 outColor; +// CONSTANTS + +const float PI = 3.14159265359; +const float MAX_REFLECTION_LOD = 4.0; + // FUNCTIONS -const float CELL_SHADING = 0.3333; +#ifdef AMBIENT_LIGHT +vec3 GGX( + in vec3 albedoColor, + in float metallic, + in float roughness, + in vec3 N, + in vec3 V) +{ + float NdotV = max(dot(N, V), 0.0); + vec3 R = reflect(-V, N); + vec3 albedo = pow(albedoColor, vec3(2.2)); + vec3 F0 = mix(vec3(0.04), albedo, metallic); -vec3 phongLighting(in vec3 kd, in vec3 ks, in float ns, in vec3 color, in vec3 normal, in vec3 lightDir, in vec3 halfVec, in vec3 viewDir){ - float diffuseComponent = max(dot(normal, lightDir), 0); - float specularComponent = max(dot(halfVec, normal), 0); - return color*diffuseComponent*(kd+ks*pow(specularComponent, ns)); + // ambient lighting (we now use IBL as the ambient term) (fresnelSchlickRoughness function) + vec3 F = F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - NdotV, 5.0); + + vec3 kD = 1.0 - F; + kD *= 1.0 - metallic; + + vec3 irradiance = texture(ambientMap, inverseViewMatrix * N).rgb; + vec3 diffuse = irradiance * albedo; + + // sample both the pre-filter map and the BRDF lut and combine them together as per the Split-Sum approximation to get the IBL specular part. + + vec3 prefilteredColor = textureLod(reflectMap, inverseViewMatrix * R, roughness * MAX_REFLECTION_LOD).rgb; + vec2 brdf2 = texture(brdfLUT, vec2(NdotV, roughness)).rg; + vec3 specular = prefilteredColor * (F * brdf2.x + brdf2.y); + + // combining light + return kD * diffuse + specular; +} +#else +float DistributionGGX(vec3 N, vec3 H, float roughness) +{ + float a = roughness*roughness; + float a2 = a*a; + float NdotH = max(dot(N, H), 0.0); + float denom = (NdotH * NdotH * (a2 - 1.0) + 1.0); + denom = PI * denom * denom; + return a2 / denom; } -vec3 CookTorranceSpecularHighlight(in vec3 ks, in float ns, in vec3 normal, in vec3 lightDir, in vec3 halfVec, in vec3 viewDir){ - float HN = dot(halfVec, normal); - float VN = dot(viewDir, normal); - float VH = dot(viewDir, halfVec); - float LN = dot(lightDir, normal); - - HN = max(HN, 0); - VN = max(VN, 0); - LN = max(LN, 0); - - // GGX normal distribution : - float roughness = 2/(ns+2); - float denom = mix(1, roughness, HN*HN); - float D = roughness/(3.1416*denom*denom); - //D = pow(HN, ns); - - // Fresnel term with Schlick's approximation - vec3 F = mix(ks, vec3(1), pow(1 - VH, 5)); - - VH = max(VH, 0); - - // Geometric attenuation - float G = min(1, min(2*HN*VN/VH, 2*HN*LN/VH)); - - return D * F * G; +float GeometrySchlickGGX(float cosAlpha, float roughness) +{ + float r = (roughness + 1.0); + float k = (r*r) / 8.0; + return cosAlpha / (cosAlpha * (1.0 - k) + k); } -vec3 testLighting(in vec3 kd, in vec3 ks, in float ns, in vec3 color, in vec3 normal, in vec3 lightDir, in vec3 halfVec, in vec3 viewDir){ - float diffuseComponent = max(dot(normal, lightDir), 0); - return color*diffuseComponent*(kd+ks*CookTorranceSpecularHighlight(ks, ns, normal, lightDir, halfVec, viewDir)); +vec3 GGX( + in vec3 albedoColor, + in float metallic, + in float roughness, + in vec3 radiance, + in vec3 N, + in vec3 L, + in vec3 H, + in vec3 V) +{ + vec3 albedo = pow(albedoColor, vec3(2.2)); + vec3 F0 = mix(vec3(0.04), albedo, metallic); + float NdotL = max(dot(N, L), 0.0); + float NdotV = max(dot(N, V), 0.0); + + // Cook-Torrance BRDF + float NDF = DistributionGGX(N, H, roughness); + float G = GeometrySchlickGGX(NdotV, roughness) * GeometrySchlickGGX(NdotL, roughness); + vec3 F = F0 + (1.0 - F0) * pow(1.0 - max(dot(H, V), 0.0), 5.0); + + vec3 nominator = NDF * G * F; + float denominator = 4 * NdotV * NdotL + 0.001; // 0.001 to prevent divide by zero. + vec3 brdf = nominator / denominator; + + vec3 kD = 1.0 - F; + kD *= 1.0 - metallic; + + return (kD * albedo / PI + brdf) * radiance * NdotL; } +#endif // MAIN PROGRAM void main(void) { + // get fragment information from the G-Buffer ivec2 texCoord = ivec2(gl_FragCoord.xy); vec3 normal = texelFetch(normalBuffer, texCoord).xyz; - vec4 diffuseTexel = texelFetch(colorBuffer, texCoord); - vec3 diffuse = diffuseTexel.rgb; - vec4 specularTexel = texelFetch(specularBuffer, texCoord); - vec3 specular = specularTexel.rgb; - float shininess = specularTexel.w*255; + vec4 albedoTexel = texelFetch(albedoBuffer, texCoord); + vec3 albedo = albedoTexel.rgb; + float roughness = albedoTexel.a; + vec4 emissionTexel = texelFetch(emissionBuffer, texCoord); + vec3 emission = emissionTexel.rgb; + float metallic = emissionTexel.a; vec4 fragPos = texelFetch(positionBuffer, texCoord); float depth = texelFetch(depthBuffer, texCoord).r; + // compute shadow #ifdef SHADOWMAP #ifdef POINT_LIGHT float shadow = 1; @@ -128,12 +182,12 @@ void main(void) { dirLight = normalize(dirLight); #endif -#ifdef AMBIENT_LIGHT - outColor = vec4(diffuse*lightColor, 1); -#else vec3 viewDir = normalize(-fragPos.xyz); +#ifdef AMBIENT_LIGHT + outColor = vec4(emission + GGX(albedo, metallic, roughness, normal, viewDir), 1); +#else vec3 halfVec = normalize(viewDir + dirLight); - vec3 light = testLighting(diffuse, specular, shininess, lightColor, normal, dirLight, halfVec, viewDir); + vec3 light = GGX(albedo, metallic, roughness, lightColor, normal, dirLight, halfVec, viewDir); outColor = vec4(mix(vec3(0.0), light*shadow, att*att), 1); #endif } diff --git a/shaders/posteffects.frag.glsl b/shaders/posteffects.frag.glsl index b4d6561..f9e7c07 100644 --- a/shaders/posteffects.frag.glsl +++ b/shaders/posteffects.frag.glsl @@ -13,5 +13,12 @@ layout(location = 0)out vec4 outColor; void main(void) { ivec2 texCoord = ivec2(gl_FragCoord.xy); vec3 color = texelFetch(lightBuffer, texCoord).xyz; + + // HDR tonemapping + color = color / (color + vec3(1.0)); + + // gamma correct + color = pow(color, vec3(1.0/2.2)); + outColor = vec4(color, 1.0); } diff --git a/src/deferredpipeline.cpp b/src/deferredpipeline.cpp index def2e82..3d2b717 100644 --- a/src/deferredpipeline.cpp +++ b/src/deferredpipeline.cpp @@ -6,8 +6,9 @@ #include "shader.h" #include #include "shadersource.h" -#include "phongmaterial.h" +#include "pbrmaterial.h" #include "camera.h" +#include "skybox.h" #include "guimesh.h" #include #include @@ -24,10 +25,10 @@ GBuffer::GBuffer(int width, int height) : FrameBuffer() tex->setUnit(POSITION); addTexture(tex, GL_COLOR_ATTACHMENT0); - // - Color + objectId buffer + // - Albedo + Roughness tex = new Texture(GL_RGBA, GL_RGBA, width, height, GL_UNSIGNED_BYTE, GL_TEXTURE_RECTANGLE); tex->setFiltering(GL_NEAREST); - tex->setUnit(DIFFUSE); + tex->setUnit(ALBEDO); addTexture(tex, GL_COLOR_ATTACHMENT1); // - Normal buffer @@ -36,10 +37,10 @@ GBuffer::GBuffer(int width, int height) : FrameBuffer() tex->setUnit(NORMAL); addTexture(tex, GL_COLOR_ATTACHMENT2); - // - Specular color + Specular exponent buffer + // - Emission + Metallic tex = new Texture(GL_RGBA, GL_RGBA, width, height, GL_UNSIGNED_BYTE, GL_TEXTURE_RECTANGLE); tex->setFiltering(GL_NEAREST); - tex->setUnit(SPECULAR); + tex->setUnit(EMISSION); addTexture(tex, GL_COLOR_ATTACHMENT3); // - depth buffer @@ -74,12 +75,13 @@ LightingBuffer::LightingBuffer(int width, int height) : FrameBuffer() } DeferredPipeline::DeferredPipeline() : - m_camera(NULL), + m_camera(nullptr), + m_skybox(nullptr), m_width(512), m_height(512), - m_gBuffer(NULL), - m_lightingBuffer(NULL), - m_renderTarget(NULL) + m_gBuffer(nullptr), + m_lightingBuffer(nullptr), + m_renderTarget(nullptr) { Resource::ResourceMap shaderMap; Resource::getResourcePack_shaders(shaderMap); @@ -120,7 +122,6 @@ void DeferredPipeline::renderGL(Scene *scene) glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // loop on geometry - unsigned int id = 2; for(SceneIterator* geometryIt = scene->getGeometry(); geometryIt->isValid(); geometryIt->next()) { @@ -138,13 +139,7 @@ void DeferredPipeline::renderGL(Scene *scene) continue; } shader->bind(); - - shader->bindUnsignedInteger(shader->getLocation("object_identifier"), id); - if(node->mesh->instances_offsets.empty()) - ++id; - else - id += node->mesh->instances_offsets.size(); - + glm::mat4 modelViewMatrix = m_camera->getViewMatrix() * node->modelMatrix; glm::mat4 normalMatrix = glm::transpose(glm::inverse(modelViewMatrix)); shader->bindMat4(shader->getLocation("projectionMatrix"), m_camera->getProjectionMatrix()); @@ -156,6 +151,9 @@ void DeferredPipeline::renderGL(Scene *scene) // LIGHTING PASS m_lightingBuffer->bindFBO(); + + if(m_skybox != nullptr) + m_skybox->renderGL(m_camera); glDepthFunc(GL_LEQUAL); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); @@ -175,9 +173,9 @@ void DeferredPipeline::renderGL(Scene *scene) // bind GBuffer shader->bindInteger(shader->getLocation("positionBuffer"), GBuffer::POSITION); - shader->bindInteger(shader->getLocation("colorBuffer"), GBuffer::DIFFUSE); + shader->bindInteger(shader->getLocation("albedoBuffer"), GBuffer::ALBEDO); shader->bindInteger(shader->getLocation("normalBuffer"), GBuffer::NORMAL); - shader->bindInteger(shader->getLocation("specularBuffer"), GBuffer::SPECULAR); + shader->bindInteger(shader->getLocation("emissionBuffer"), GBuffer::EMISSION); shader->bindInteger(shader->getLocation("depthBuffer"), GBuffer::DEPTH); // bind light @@ -219,7 +217,19 @@ void DeferredPipeline::renderGL(Scene *scene) } // IMGUI PASS - gui.drawGL(); + m_guiMesh->drawGL(); +} + +void DeferredPipeline::setSkybox(Texture* texture) +{ + if(m_skybox != nullptr) + delete m_skybox; + m_skybox = nullptr; + if(texture != nullptr) + { + m_skybox = new Skybox(texture); + m_skybox->resizeGL(m_width, m_height); + } } void DeferredPipeline::resizeGL(int w, int h) @@ -228,6 +238,9 @@ void DeferredPipeline::resizeGL(int w, int h) m_width = w; m_height = h; + if(m_skybox != nullptr) + m_skybox->resizeGL(w, h); + // rebuilding FrameBuffers if(m_gBuffer != NULL) { diff --git a/src/deferredpipeline.h b/src/deferredpipeline.h index e2fb307..0c71948 100644 --- a/src/deferredpipeline.h +++ b/src/deferredpipeline.h @@ -8,12 +8,13 @@ class Shader; class Camera; +class Skybox; class GuiMesh; class GBuffer : public FrameBuffer { public: - enum Buffers { POSITION, DIFFUSE, NORMAL, SPECULAR, DEPTH, NB_BUFFERS }; + enum Buffers { POSITION, ALBEDO, NORMAL, EMISSION, DEPTH, NB_BUFFERS }; GBuffer(int width, int height); void bindTextures(); void unbindTextures(); @@ -28,7 +29,9 @@ public: class DeferredPipeline : public Pipeline { Camera *m_camera; - + + Skybox* m_skybox; + int m_width; int m_height; @@ -60,6 +63,7 @@ public: void setCamera(Camera *camera) { m_camera = camera; } void setSources(ShaderSource *gBufferSource, ShaderSource *lightingSource, ShaderSource *guiSource, Shader *postEffectsShader); void setRenderTarget(const FrameBuffer *fbo) { m_renderTarget = fbo; } + void setSkybox(Texture* texture); void refreshScene(Scene *scene); virtual void renderGL(Scene *scene); diff --git a/src/forwardmodule.cpp b/src/forwardmodule.cpp index c8b87a5..b86041b 100644 --- a/src/forwardmodule.cpp +++ b/src/forwardmodule.cpp @@ -3,7 +3,7 @@ #include "mesh.h" #include "shader.h" #include "light.h" -#include "phongmaterial.h" +#include "pbrmaterial.h" #include "texture.h" #include "camera.h" #include diff --git a/src/light.cpp b/src/light.cpp index d37c7c6..d869a5e 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -4,7 +4,7 @@ #include "scene.h" #include "shader.h" #include "shadersource.h" -#include "phongmaterial.h" +#include "pbrmaterial.h" #include "mesh.h" #include "camera.h" #include @@ -28,9 +28,23 @@ const glm::mat4 Light::biasMatrix( 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0); +Texture* AmbientLight::brdfLUT = nullptr; + void AmbientLight::bindAttributes(Shader *shader, Camera *camera) { - shader->bindVec3(shader->getLocation("lightColor"), m_color); + int slot = PBRMaterial::NB_PBR_SLOTS; + brdfLUT->bind(slot); + shader->bindInteger(shader->getLocation("brdfLUT"), slot); + + ++slot; + ambient->bind(slot); + shader->bindInteger(shader->getLocation("ambientMap"), slot); + + ++slot; + reflect->bind(slot); + shader->bindInteger(shader->getLocation("reflectMap"), slot); + + shader->bindMat3(shader->getLocation("inverseViewMatrix"), glm::inverse(glm::mat3(camera->getViewMatrix()))); } // DIRECTIONNAL LIGHT diff --git a/src/light.h b/src/light.h index 8d8c3b7..d914a6b 100644 --- a/src/light.h +++ b/src/light.h @@ -51,11 +51,19 @@ protected: class AmbientLight : public Light { + Texture* ambient; + Texture* reflect; + static Texture* brdfLUT; public: - AmbientLight(glm::vec3 lightColor = glm::vec3(0.1f)) { m_color = lightColor; } + AmbientLight(Texture* ambientTex = nullptr, Texture* reflectTex = nullptr) : ambient(ambientTex), reflect(reflectTex) {} virtual LightType getType() { return AMBIENT; } virtual void bindAttributes(Shader *shader, Camera *camera); virtual unsigned int getFlags() { return 1 << AMBIENT_FLAG; } + void setAmbient(Texture* texture) { ambient = texture; } + Texture* getAmbient() { return ambient; } + void setReflect(Texture* texture) { reflect = texture; } + Texture* getReflect() { return reflect; } + static void setBrdfLut(Texture* texture) { brdfLUT = texture; } }; class DirectionnalLight : public Light diff --git a/src/mesh.cpp b/src/mesh.cpp index cb37e75..38d7a44 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -25,9 +25,10 @@ const char* const Mesh::flagStr[Mesh::NB_FLAGS] = "ALPHA_MASK", "PHONG", - "DIFFUSE_TEXTURE", + "ALBEDO_TEXTURE", "EMISSION_TEXTURE", - "SPECULAR_TEXTURE", + "ROUGHNESS_TEXTURE", + "METALLIC_TEXTURE", "NORMAL_MAP", "BUMP_MAP" diff --git a/src/mesh.h b/src/mesh.h index e50df83..327c50f 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -41,15 +41,16 @@ public: MATERIAL_COLOR_TEXTURE, MATERIAL_ALPHA_MASK, - // 3D phong material - MATERIAL_PHONG, - MATERIAL_PHONG_DIFFUSE_TEXTURE, - MATERIAL_PHONG_EMISSION_TEXTURE, - MATERIAL_PHONG_SPECULAR_TEXTURE, - MATERIAL_PHONG_NORMAL_MAP, + // 3D PBR material + MATERIAL_PBR, + MATERIAL_PBR_ALBEDO_TEXTURE, + MATERIAL_PBR_EMISSION_TEXTURE, + MATERIAL_PBR_ROUGHNESS_TEXTURE, + MATERIAL_PBR_METALLIC_TEXTURE, + MATERIAL_PBR_NORMAL_MAP, // 3D Beckman-like materials - MATERIAL_BACKMANN_BUMP_MAP, + MATERIAL_BECKMANN_BUMP_MAP, NB_FLAGS }; diff --git a/src/model.cpp b/src/model.cpp deleted file mode 100644 index f9429ad..0000000 --- a/src/model.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "model.h" -#include "mesh.h" -#include "image.h" -#include "texture.h" -#include "phongmaterial.h" - -Model::Model() : m_texPack(NULL) {} - -Model::~Model() -{ - initDestroy(); - destroyGL(); - for(Mesh *m : m_meshes) - delete m; - setTexturePack(NULL); -} - -void Model::setTexturePack(TexturePack *texPack) -{ - if(m_texPack != NULL) - delete m_texPack; - m_texPack = texPack; -} - -void Model::initDestroy() -{ - initGL(); - for(Mesh* m : m_meshes) - m->clearData(); - if(m_texPack != NULL) - m_texPack->initDestroyImages(); -} - -void Model::initGL() -{ - for(Mesh* m : m_meshes) - m->initGL(); - if(m_texPack != NULL) - m_texPack->initGL(); -} - -void Model::destroyGL() -{ - for(Mesh* m : m_meshes) - m->destroyGL(); - if(m_texPack != NULL) - m_texPack->destroyGL(); -} - -bool Model::save(const std::string &filename, const std::string &texturesPath) -{ - // open file - std::FILE *file = std::fopen(filename.c_str(), "w"); - if(file == NULL) - return false; - - // write meshes and materials, there is no material sharing (1 mesh = 1 material) - bool ok = false; - int size = m_meshes.size(); - if(std::fwrite(&size, sizeof(int), 1, file)) - { - ok = true; - for(Mesh* m : m_meshes) - { - ok = ok && m->serialize(file); - PhongMaterial* mat = (PhongMaterial*)m->getMaterial(); - ok = ok && mat->serialize(file); - } - std::fclose(file); - } - - // saves the TexturePack - if(m_texPack != NULL) - ok = ok && m_texPack->save(texturesPath); - - // finishing - return ok; -} - -Model* Model::load(const std::string &filename, const std::string &texturesPath) -{ - // open file - std::FILE *file = std::fopen(filename.c_str(), "r"); - if(file == NULL) - return NULL; - - bool ok = false; - - - - // finishing - return NULL; -} diff --git a/src/model.h b/src/model.h deleted file mode 100644 index c51c4a8..0000000 --- a/src/model.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef MODEL_H -#define MODEL_H - -#include -#include - -class Mesh; -class Image; -class TexturePack; - -class Model -{ -protected: - TexturePack *m_texPack; - std::vector m_meshes; - -public: - Model(); - - ~Model(); - - void setTexturePack(TexturePack *texPack); - - /** - * @brief addMesh adds a mesh to the mesh list - */ - void addMesh(Mesh *mesh) { m_meshes.push_back(mesh); } - - /** - * @brief getMeshes returns the mesh array - */ - const std::vector& getMeshes() { return m_meshes; } - - /** - * @brief getImage returns the image which has the specified name, or NULL if there are no images of this name. - */ - //Image* getImage(const std::string &name); - - /** - * @brief getTexture returns the texture which has the specified name, or NULL if there are no images of this name. - */ - //Texture* getTexture(const std::string &name); - - /** - * @brief uploads meshes and images to GPU memory, - * then frees Mesh and Image memory in the RAM, - * so it stays allocated only in GPU memory. - */ - void initDestroy(); - - /** - * @brief initGL uploads image and mesh data to GPU memory - */ - void initGL(); - - /** - * @brief destroyGL frees the meshes and the textures from GPU memory - */ - void destroyGL(); - - /** - * @brief save saves the model on a file - * @param filename is the name of the resulting file - * @param texturesPath is the existing folder where the textures will be saved - * @return true if the save succeeded - */ - bool save(const std::string &filename, const std::string &texturesPath); - - /** - * @brief load loads the model from a file - * @param filename is the name of the target file - * @param texturesPath is the existing folder where the textures will be gathered - * @return the model if the loading succeeded, or NULL if it failed - */ - static Model* load(const std::string &filename, const std::string &texturesPath); -}; - -#endif // MODEL_H diff --git a/src/parametricmesh.cpp b/src/parametricmesh.cpp index 29479b0..6711804 100644 --- a/src/parametricmesh.cpp +++ b/src/parametricmesh.cpp @@ -1,6 +1,6 @@ #include "parametricmesh.h" #include "glm/ext.hpp" -#include "phongmaterial.h" +#include "pbrmaterial.h" #define M_PI 3.14159265358979323846 #define MAGIC_RATIO 0.37139f diff --git a/src/pbrmaterial.cpp b/src/pbrmaterial.cpp new file mode 100644 index 0000000..84b0e17 --- /dev/null +++ b/src/pbrmaterial.cpp @@ -0,0 +1,75 @@ +#include "pbrmaterial.h" +#include "texture.h" +#include "sparrowrenderer.h" + +#include "shader.h" +#include "mesh.h" +#include + +void PBRMaterial::bindAttributes(Shader* myShader) +{ + // TODO store the attributes location + myShader->bindFloat(myShader->getLocation("opacity"), opacity); + + if(textures[NORMALS_SLOT] != NULL) + { + textures[NORMALS_SLOT]->bind(NORMALS_SLOT); + myShader->bindInteger(myShader->getLocation("normalMap"), NORMALS_SLOT); + } + + if(textures[EMISSION_SLOT] != NULL) + { + textures[EMISSION_SLOT]->bind(EMISSION_SLOT); + myShader->bindInteger(myShader->getLocation("emissionTexture"), EMISSION_SLOT); + } + else + myShader->bindVec3(myShader->getLocation("emission"), emission); + + if(textures[ALBEDO_SLOT] != NULL) + { + textures[ALBEDO_SLOT]->bind(ALBEDO_SLOT); + myShader->bindInteger(myShader->getLocation("albedoTexture"), ALBEDO_SLOT); + } + else + myShader->bindVec3(myShader->getLocation("albedo"), albedo); + + if(textures[ROUGHNESS_SLOT] != NULL) + { + textures[ROUGHNESS_SLOT]->bind(ROUGHNESS_SLOT); + myShader->bindInteger(myShader->getLocation("roughnessTexture"), ROUGHNESS_SLOT); + } + else + myShader->bindFloat(myShader->getLocation("roughness"), roughness); + + if(textures[METALLIC_SLOT] != NULL) + { + textures[METALLIC_SLOT]->bind(METALLIC_SLOT); + myShader->bindInteger(myShader->getLocation("metallicTexture"), METALLIC_SLOT); + } + else + myShader->bindFloat(myShader->getLocation("metallic"), metallic); + + if(textures[ALPHA_SLOT] != NULL) + { + textures[ALPHA_SLOT]->bind(ALPHA_SLOT); + myShader->bindInteger(myShader->getLocation("alphaMask"), ALPHA_SLOT); + } +} + +unsigned int PBRMaterial::getFlags() +{ + unsigned int flags = 1 << Mesh::MATERIAL_PBR; + if(textures[NORMALS_SLOT] != NULL) + flags |= 1 << Mesh::MATERIAL_PBR_NORMAL_MAP; + if(textures[EMISSION_SLOT] != NULL) + flags |= 1 << Mesh::MATERIAL_PBR_EMISSION_TEXTURE; + if(textures[ALBEDO_SLOT] != NULL) + flags |= 1 << Mesh::MATERIAL_PBR_ALBEDO_TEXTURE; + if(textures[ROUGHNESS_SLOT] != NULL) + flags |= 1 << Mesh::MATERIAL_PBR_ROUGHNESS_TEXTURE; + if(textures[METALLIC_SLOT] != NULL) + flags |= 1 << Mesh::MATERIAL_PBR_METALLIC_TEXTURE; + if(textures[ALPHA_SLOT] != NULL) + flags |= 1 << Mesh::MATERIAL_ALPHA_MASK; + return flags; +} diff --git a/src/pbrmaterial.h b/src/pbrmaterial.h new file mode 100644 index 0000000..1f4b762 --- /dev/null +++ b/src/pbrmaterial.h @@ -0,0 +1,52 @@ +#ifndef PHONGMATERIAL_H +#define PHONGMATERIAL_H + +#include "material.h" +#include "glm/vec3.hpp" +#include + +class Texture; + +struct PBRMaterial : public Material +{ + enum TextureSlots + { + ALBEDO_SLOT, + EMISSION_SLOT, + NORMALS_SLOT, + ROUGHNESS_SLOT, + METALLIC_SLOT, + ALPHA_SLOT, + NB_PBR_SLOTS + }; + + glm::vec3 emission; + glm::vec3 albedo; + float roughness; + float metallic; + float opacity; + Texture* textures[NB_PBR_SLOTS]; + std::string textureNames[NB_PBR_SLOTS]; + + PBRMaterial() : + emission(0), + albedo(0.9f), + roughness(0.8f), + metallic(0.2), + opacity(1.f) + { + for(int i=0; i - -void PhongMaterial::bindAttributes(Shader* myShader) -{ - // TODO store the attributes location - myShader->bindFloat(myShader->getLocation("materialNs"), shininess); - myShader->bindFloat(myShader->getLocation("opacity"), m_opacity); - - if(textures[NORMALS_SLOT] != NULL) - { - textures[NORMALS_SLOT]->bind(NORMALS_SLOT); - myShader->bindInteger(myShader->getLocation("normalMap"), NORMALS_SLOT); - } - - if(textures[EMISSION_SLOT] != NULL) - { - textures[EMISSION_SLOT]->bind(EMISSION_SLOT); - myShader->bindInteger(myShader->getLocation("emissionTexture"), EMISSION_SLOT); - } - else - myShader->bindVec3(myShader->getLocation("materialEmission"), emission); - - if(textures[DIFFUSE_SLOT] != NULL) - { - textures[DIFFUSE_SLOT]->bind(DIFFUSE_SLOT); - myShader->bindInteger(myShader->getLocation("diffuseTexture"), DIFFUSE_SLOT); - } - else - myShader->bindVec3(myShader->getLocation("materialKd"), diffuse); - - if(textures[SPECULAR_SLOT] != NULL) - { - textures[SPECULAR_SLOT]->bind(SPECULAR_SLOT); - myShader->bindInteger(myShader->getLocation("specularTexture"), SPECULAR_SLOT); - } - else - myShader->bindVec3(myShader->getLocation("materialKs"), specular); - - if(textures[ALPHA_SLOT] != NULL) - { - textures[ALPHA_SLOT]->bind(ALPHA_SLOT); - myShader->bindInteger(myShader->getLocation("alphaMask"), ALPHA_SLOT); - } -} - -unsigned int PhongMaterial::getFlags() -{ - unsigned int flags = 1 << Mesh::MATERIAL_PHONG; - if(textures[NORMALS_SLOT] != NULL) - flags |= 1 << Mesh::MATERIAL_PHONG_NORMAL_MAP; - if(textures[EMISSION_SLOT] != NULL) - flags |= 1 << Mesh::MATERIAL_PHONG_EMISSION_TEXTURE; - if(textures[DIFFUSE_SLOT] != NULL) - flags |= 1 << Mesh::MATERIAL_PHONG_DIFFUSE_TEXTURE; - if(textures[SPECULAR_SLOT] != NULL) - flags |= 1 << Mesh::MATERIAL_PHONG_SPECULAR_TEXTURE; - if(textures[ALPHA_SLOT] != NULL) - flags |= 1 << Mesh::MATERIAL_ALPHA_MASK; - return flags; -} - -// serialisation methods : - -struct MaterialHeader -{ - glm::vec3 emission; - glm::vec3 diffuse; - glm::vec3 specular; - float shininess; - int textureLengths[PhongMaterial::NB_PHONG_SLOTS]; -}; - -bool PhongMaterial::serialize(PhongMaterial* mat, FILE *file) -{ - unsigned int flags = mat->getFlags(); - - if(!fwrite(&flags, sizeof(unsigned int), 1, file)) - return false; - - if(flags & (1 << Mesh::MATERIAL_PHONG)) - { - MaterialHeader header; - header.emission = mat->emission; - header.diffuse = mat->diffuse; - header.specular = mat->specular; - header.shininess = mat->shininess; - - for(int i=0; itextures[i] != NULL) - header.textureLengths[i] = mat->textureNames[i].length()+1; - else - header.textureLengths[i] = 0; - } - - if(!std::fwrite(&header, sizeof(MaterialHeader), 1, file)) - return false; - for(int i=0; i 0) - { - if(!std::fwrite(mat->textureNames[i].c_str(), header.textureLengths[i], 1, file)) - return false; - } - } - } - - return true; -} - -PhongMaterial* PhongMaterial::deserialize(FILE *file) -{ - int flags; - if(!std::fread(&flags, sizeof(int), 1, file)) - return NULL; - - MaterialHeader header; - if(!std::fread(&header, sizeof(MaterialHeader), 1, file)) - return NULL; - - PhongMaterial *mat = new PhongMaterial(); - - mat->diffuse = header.diffuse; - mat->emission = header.emission; - mat->specular = header.specular; - mat->shininess = header.shininess; - for(int i=0; itextureNames[i] = std::string(str); - } - - return mat; -} diff --git a/src/phongmaterial.h b/src/phongmaterial.h deleted file mode 100644 index 3dbd7e5..0000000 --- a/src/phongmaterial.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef PHONGMATERIAL_H -#define PHONGMATERIAL_H - -#include "material.h" -#include "glm/vec3.hpp" -#include - -class Texture; - -struct PhongMaterial : public Material -{ - enum TextureSlots - { - DIFFUSE_SLOT, - EMISSION_SLOT, - NORMALS_SLOT, - SPECULAR_SLOT, - ALPHA_SLOT, - NB_PHONG_SLOTS - }; - - glm::vec3 emission; - glm::vec3 diffuse; - glm::vec3 specular; - float shininess; - float m_opacity; - Texture* textures[NB_PHONG_SLOTS]; - std::string textureNames[NB_PHONG_SLOTS]; - - PhongMaterial() : - emission(0), - diffuse(0.5f), - specular(0.5f), - shininess(10), - m_opacity(1.f) - { - for(int i=0; i #include #include -#include "skyboxmodule.h" +#include "skybox.h" #include "shader.h" #include "texture.h" #include "camera.h" -#include "framebuffer.h" - -#include "sparrowrenderer.h" +#include "opengl.h" #define BUFFER_OFFSET(i) ((char *)NULL + (i)) -SkyboxModule::SkyboxModule(Texture* myCubeMap) +Skybox::Skybox(Texture* myCubeMap) { cubeMap = myCubeMap; @@ -20,39 +18,38 @@ SkyboxModule::SkyboxModule(Texture* myCubeMap) glGenBuffers(2, vbos); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbos[0]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(GLubyte), skyboxIndices, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, vbos[1]); + + glBindBuffer(GL_ARRAY_BUFFER, vbos[1]); glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), skyboxVertices, GL_STATIC_DRAW); - - renderTarget = FrameBuffer::screen; + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(0)); + glEnableVertexAttribArray(0); + shader = new Shader(vertSource, fragSource); mvpLocation = shader->getLocation("MVP"); + cubemapLocation = shader->getLocation("skybox"); glBindVertexArray(0); } -SkyboxModule::~SkyboxModule() +Skybox::~Skybox() { glDeleteVertexArrays(1, &vao); glDeleteBuffers(2, vbos); } -void SkyboxModule::renderGL(Camera* myCamera, Scene* scene) +void Skybox::renderGL(Camera* myCamera) { glViewport(0, 0, width, height); glm::mat4 viewMatrix = glm::mat4(glm::mat3(myCamera->getViewMatrix())); - glm::mat4 projectionMatrix = myCamera->getProjectionMatrix(); glDisable(GL_CULL_FACE); glDepthMask(GL_FALSE); - renderTarget->bindFBO(); + shader->bind(); - shader->bindMat4(mvpLocation, projectionMatrix * viewMatrix); + shader->bindMat4(mvpLocation, myCamera->getProjectionMatrix() * viewMatrix); + shader->bindInteger(cubemapLocation, 0); cubeMap->bind(0); glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, vbos[1]); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(0)); - glEnableVertexAttribArray(0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbos[0]); glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, NULL); glBindVertexArray(0); @@ -61,13 +58,7 @@ void SkyboxModule::renderGL(Camera* myCamera, Scene* scene) glDepthMask(GL_TRUE); } -void SkyboxModule::setRenderTarget(const FrameBuffer* target) -{ - if(target != NULL) - renderTarget = target; -} - -const GLfloat SkyboxModule::skyboxVertices[] = { +const GLfloat Skybox::skyboxVertices[] = { -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, @@ -78,7 +69,7 @@ const GLfloat SkyboxModule::skyboxVertices[] = { 1.0f, -1.0f, -1.0f }; -const GLubyte SkyboxModule::skyboxIndices[] = { +const GLubyte Skybox::skyboxIndices[] = { 0, 6, 2, 0, 4, 6, 1, 3, 5, @@ -93,8 +84,9 @@ const GLubyte SkyboxModule::skyboxIndices[] = { 6, 7, 3 }; -const std::string SkyboxModule::vertSource = - "layout(location = 0)in vec3 inPosition;\n\ +const std::string Skybox::vertSource = + "#version 330 core\n\ + layout(location = 0)in vec3 inPosition;\n\ out vec3 varTexCoord;\n\ uniform mat4 MVP;\n\ void main()\n\ @@ -103,8 +95,9 @@ const std::string SkyboxModule::vertSource = varTexCoord = inPosition;\n\ }\n"; -const std::string SkyboxModule::fragSource = - "in vec3 varTexCoord;\n\ +const std::string Skybox::fragSource = + "#version 330 core\n\ + in vec3 varTexCoord;\n\ out vec4 outColor;\n\ uniform samplerCube skybox;\n\ void main()\n\ diff --git a/src/skybox.h b/src/skybox.h new file mode 100644 index 0000000..95c0968 --- /dev/null +++ b/src/skybox.h @@ -0,0 +1,35 @@ +#ifndef SKYBOX_H +#define SKYBOX_H + +#include "opengl.h" +#include + +class Camera; +class Shader; +class Texture; + +class Skybox +{ + static const GLfloat skyboxVertices[]; + static const GLubyte skyboxIndices[]; + static const std::string vertSource; + static const std::string fragSource; + + int width; + int height; + + GLuint vao; + GLuint vbos[2]; + GLuint mvpLocation; + GLuint cubemapLocation; + Shader* shader; + Texture* cubeMap; + +public: + Skybox(Texture* myCubeMap); + ~Skybox(); + void renderGL(Camera* myCamera); + void resizeGL(int w, int h) {width = w; height = h;} +}; + +#endif // SKYBOX_H diff --git a/src/skyboxmodule.h b/src/skyboxmodule.h deleted file mode 100644 index ce1c5b1..0000000 --- a/src/skyboxmodule.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef SKYBOXMODULE_H -#define SKYBOXMODULE_H - -#include "opengl.h" -#include "module.h" -#include - -class Shader; -class Texture; -class FrameBuffer; - -class SkyboxModule : public Module -{ - static const GLfloat skyboxVertices[]; - static const GLubyte skyboxIndices[]; - static const std::string vertSource; - static const std::string fragSource; - - int width; - int height; - - GLuint vao; - GLuint vbos[2]; - GLuint mvpLocation; - Shader* shader; - Texture* cubeMap; - - const FrameBuffer* renderTarget; - -public: - SkyboxModule(Texture* myCubeMap); - ~SkyboxModule(); - virtual void renderGL(Camera* myCamera, Scene* scene = NULL); - virtual void resize(int w, int h) {width = w; height = h;} - void setRenderTarget(const FrameBuffer* target); -}; - -#endif // SKYBOXMODULE_H