diff --git a/libraries/model/src/model/Geometry.h b/libraries/model/src/model/Geometry.h index 0beaa20a83..fbd485e6a0 100755 --- a/libraries/model/src/model/Geometry.h +++ b/libraries/model/src/model/Geometry.h @@ -23,6 +23,7 @@ typedef gpu::BufferView::Index Index; typedef gpu::BufferView BufferView; typedef AABox Box; typedef std::vector< Box > Boxes; +typedef glm::vec3 Vec3; class Mesh { public: @@ -35,7 +36,7 @@ public: typedef gpu::Stream::Format VertexFormat; typedef std::map< Slot, BufferView > BufferViewMap; - typedef glm::vec3 Vec3; + typedef model::Vec3 Vec3; Mesh(); Mesh(const Mesh& mesh); diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index efd2f35968..57e0f68a9c 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -100,7 +100,6 @@ public: void setTextureView(MapChannel channel, const TextureView& texture); const TextureMap& getTextureMap() const { return _textureMap; } - const Schema* getSchema() const { return &_schemaBuffer.get(); } protected: Flags _flags; diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index 9e421c03c9..cd65fd1053 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -59,7 +59,7 @@ vec3 evalDirectionalColor(float shadowAttenuation, vec3 position, vec3 normal, v // Diffuse Lighting float diffuseDot = dot(normal, gl_LightSource[0].position.xyz); float facingLight = step(0.0, diffuseDot) * shadowAttenuation; - vec3 diffuseColor = diffuse * (/*gl_FrontLightModelProduct.sceneColor.rgb +*/ gl_FrontLightProduct[0].diffuse.rgb * (diffuseDot * facingLight)); + vec3 diffuseColor = diffuse * (gl_FrontLightProduct[0].diffuse.rgb * (diffuseDot * facingLight)); // compute the specular multiplier (sans exponent) float specularPower = facingLight * max(0.0, diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 5cbdd04f64..58e90f57d1 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -25,6 +25,9 @@ #include "RenderUtil.h" #include "TextureCache.h" +#include "gpu/Batch.h" +#include "gpu/GLBackend.h" + #include "simple_vert.h" #include "simple_frag.h" @@ -269,7 +272,14 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu light.specular = glm::vec4(specular, 1.0f); light.constantAttenuation = constantAttenuation; light.linearAttenuation = linearAttenuation; - _pointLights.append(light); + + model::LightPointer lp = model::LightPointer(new model::Light()); + lp->setPosition(position); + lp->setAttenuationRadius(radius); + lp->setColor(diffuse); + lp->setIntensity(1.0f); + lp->setType(model::Light::POINT); + _pointLights.push_back(lp); } else { SpotLight light; @@ -283,7 +293,17 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu light.direction = direction; light.exponent = exponent; light.cutoff = cutoff; - _spotLights.append(light); + + model::LightPointer ls = model::LightPointer(new model::Light()); + ls->setPosition(position); + ls->setDirection(direction); + ls->setAttenuationRadius(radius); + ls->setSpotCone(cutoff); + ls->setColor(diffuse); + ls->setIntensity(1.0f); + ls->setType(model::Light::SPOT); + + _spotLights.push_back(ls); } } @@ -436,14 +456,24 @@ void DeferredLightingEffect::render() { auto geometryCache = DependencyManager::get(); - if (!_pointLights.isEmpty()) { + if (!_pointLights.empty()) { _pointLight.bind(); _pointLight.setUniformValue(_pointLightLocations.nearLocation, nearVal); _pointLight.setUniformValue(_pointLightLocations.depthScale, depthScale); _pointLight.setUniformValue(_pointLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); _pointLight.setUniformValue(_pointLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); - foreach (const PointLight& light, _pointLights) { + for (auto light : _pointLights) { + // foreach (const PointLight& light, _pointLights) { + if (_pointLightLocations.lightBufferUnit >= 0) { + gpu::Batch batch; + batch.setUniformBuffer(_pointLightLocations.lightBufferUnit, light->getSchemaBuffer()); + gpu::GLBackend::renderBatch(batch); + } + _spotLight.setUniformValue(_pointLightLocations.radius, light->getAttenuationRadius()); + + +/* _pointLight.setUniformValue(_pointLightLocations.radius, light.radius); glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, (const GLfloat*)&light.diffuse); @@ -452,11 +482,11 @@ void DeferredLightingEffect::render() { glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, (light.constantAttenuation > 0.0f ? light.constantAttenuation : 0.0f)); glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, (light.linearAttenuation > 0.0f ? light.linearAttenuation : 0.0f)); glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, (light.quadraticAttenuation > 0.0f ? light.quadraticAttenuation : 0.0f)); - + */ glPushMatrix(); - float expandedRadius = light.radius * (1.0f + SCALE_EXPANSION); - if (glm::distance(eyePoint, glm::vec3(light.position)) < expandedRadius + nearRadius) { + float expandedRadius = light->getAttenuationRadius() * (1.0f + SCALE_EXPANSION); + if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) { glLoadIdentity(); glTranslatef(0.0f, 0.0f, -1.0f); @@ -470,7 +500,7 @@ void DeferredLightingEffect::render() { glMatrixMode(GL_MODELVIEW); } else { - glTranslatef(light.position.x, light.position.y, light.position.z); + glTranslatef(light->getPosition().x, light->getPosition().y, light->getPosition().z); geometryCache->renderSphere(expandedRadius, 32, 32); } @@ -481,15 +511,24 @@ void DeferredLightingEffect::render() { _pointLight.release(); } - if (!_spotLights.isEmpty()) { + if (!_spotLights.empty()) { _spotLight.bind(); _spotLight.setUniformValue(_spotLightLocations.nearLocation, nearVal); _spotLight.setUniformValue(_spotLightLocations.depthScale, depthScale); _spotLight.setUniformValue(_spotLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); _spotLight.setUniformValue(_spotLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); - foreach (const SpotLight& light, _spotLights) { - _spotLight.setUniformValue(_spotLightLocations.radius, light.radius); + for (auto light : _spotLights) { + // foreach (const SpotLight& light, _spotLights) { + if (_spotLightLocations.lightBufferUnit >= 0) { + gpu::Batch batch; + batch.setUniformBuffer(_spotLightLocations.lightBufferUnit, light->getSchemaBuffer()); + gpu::GLBackend::renderBatch(batch); + } + _spotLight.setUniformValue(_spotLightLocations.radius, light->getAttenuationRadius()); + + /* + _spotLight.setUniformValue(_spotLightLocations.radius, light.radius); glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, (const GLfloat*)&light.diffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, (const GLfloat*)&light.specular); @@ -500,12 +539,13 @@ void DeferredLightingEffect::render() { glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, (const GLfloat*)&light.direction); glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, light.exponent); glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, glm::degrees(light.cutoff)); - + */ + glPushMatrix(); - float expandedRadius = light.radius * (1.0f + SCALE_EXPANSION); - float edgeRadius = expandedRadius / glm::cos(light.cutoff); - if (glm::distance(eyePoint, glm::vec3(light.position)) < edgeRadius + nearRadius) { + float expandedRadius = light->getAttenuationRadius() * (1.0f + SCALE_EXPANSION); + float edgeRadius = expandedRadius / glm::cos(light->getSpotConeAngle()); + if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < edgeRadius + nearRadius) { glLoadIdentity(); glTranslatef(0.0f, 0.0f, -1.0f); @@ -519,12 +559,12 @@ void DeferredLightingEffect::render() { glMatrixMode(GL_MODELVIEW); } else { - glTranslatef(light.position.x, light.position.y, light.position.z); - glm::quat spotRotation = rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), light.direction); + glTranslatef(light->getPosition().x, light->getPosition().y, light->getPosition().z); + glm::quat spotRotation = rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), light->getDirection()); glm::vec3 axis = glm::axis(spotRotation); glRotatef(glm::degrees(glm::angle(spotRotation)), axis.x, axis.y, axis.z); - glTranslatef(0.0f, 0.0f, -light.radius * (1.0f + SCALE_EXPANSION * 0.5f)); - geometryCache->renderCone(expandedRadius * glm::tan(light.cutoff), + glTranslatef(0.0f, 0.0f, -light->getAttenuationRadius() * (1.0f + SCALE_EXPANSION * 0.5f)); + geometryCache->renderCone(expandedRadius * glm::tan(light->getSpotConeAngle()), expandedRadius, 32, 1); } @@ -609,6 +649,31 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit locations.depthTexCoordScale = program.uniformLocation("depthTexCoordScale"); locations.radius = program.uniformLocation("radius"); locations.ambientSphere = program.uniformLocation("ambientSphere.L00"); + + GLint loc = -1; +#if defined(Q_OS_MAC) + loc = program.uniformLocation("lightBuffer"); + if (loc >= 0) { + locations.lightBufferUnit = loc; + } else { + locations.lightBufferUnit = -1; + } +#elif defined(Q_OS_WIN) + loc = glGetUniformBlockIndex(program.programId(), "lightBuffer"); + if (loc >= 0) { + glUniformBlockBinding(program.programId(), loc, 1); + locations.lightBufferUnit = 1; + } else { + locations.lightBufferUnit = -1; + } +#else + loc = program.uniformLocation("lightBuffer"); + if (loc >= 0) { + locations.lightBufferUnit = loc; + } else { + locations.lightBufferUnit = -1; + } +#endif program.release(); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index cd8585eade..5c39c3041e 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -19,6 +19,8 @@ #include "ProgramObject.h" +#include "model/Light.h" + class AbstractViewStateInterface; class PostLightingRenderable; @@ -102,6 +104,7 @@ private: int depthTexCoordScale; int radius; int ambientSphere; + int lightBufferUnit; }; static void loadLightProgram(const char* fragSource, bool limited, ProgramObject& program, LightLocations& locations); @@ -146,9 +149,13 @@ private: float exponent; float cutoff; }; - - QVector _pointLights; - QVector _spotLights; + + typedef std::vector< model::LightPointer > Lights; + + Lights _pointLights; + Lights _spotLights; + // QVector _pointLights; + // QVector _spotLights; QVector _postLightingRenderables; AbstractViewStateInterface* _viewState; diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index e5142b25ce..9d9aecda95 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -15,16 +15,23 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> +// Everything about light +<@include Light.slh@> + // the radius (hard cutoff) of the light effect uniform float radius; void main(void) { // get the depth and exit early if it doesn't pass the test vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; - float depth = texture2D(depthMap, texCoord).r; + + DeferredFragment frag = unpackDeferredFragment(texCoord); + + float depth = frag.depthVal; if (depth < gl_FragCoord.z) { discard; } + // compute the view space position using the depth float z = near / (depth * depthScale - 1.0); vec4 position = vec4((depthTexCoordOffset + texCoord * depthTexCoordScale) * z, z, 1.0); @@ -52,4 +59,6 @@ void main(void) { normalizedNormal)); vec4 specularColor = texture2D(specularMap, texCoord); gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0); + + gl_FragColor = vec4(frag.normal, 0.0); } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index f987760eb8..48e8ab0d61 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -15,20 +15,30 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> +// Everything about light +<@include Light.slh@> + // the radius (hard cutoff) of the light effect uniform float radius; void main(void) { - // get the depth and exit early if it doesn't pass the test vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; - float depth = texture2D(depthMap, texCoord).r; + + DeferredFragment frag = unpackDeferredFragment(texCoord); + + // get the depth and exit early if it doesn't pass the test + float depth = frag.depthVal; if (depth < gl_FragCoord.z) { discard; } + + + // compute the view space position using the depth float z = near / (depth * depthScale - 1.0); vec4 position = vec4((depthTexCoordOffset + texCoord * depthTexCoordScale) * z, z, 1.0); + // get the normal from the map vec4 normal = texture2D(normalMap, texCoord); vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0)); @@ -54,4 +64,6 @@ void main(void) { normalizedNormal)); vec4 specularColor = texture2D(specularMap, texCoord); gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0); + + gl_FragColor = vec4(frag.normal, 0.0); } diff --git a/libraries/shared/src/Transform.h b/libraries/shared/src/Transform.h index e08f00c0ac..346a82a3b0 100644 --- a/libraries/shared/src/Transform.h +++ b/libraries/shared/src/Transform.h @@ -100,6 +100,8 @@ public: // Left will be inversed before the multiplication static Transform& inverseMult(Transform& result, const Transform& left, const Transform& right); + Vec4 transform(const Vec4& pos) const; + protected: enum Flag { @@ -414,6 +416,13 @@ inline Transform& Transform::inverseMult( Transform& result, const Transform& le return result; } +inline Transform::Vec4 Transform::transform(const Vec4& pos) const { + Mat4 m; + getMatrix(m); + return m * pos; +} + + inline Transform::Mat4& Transform::getCachedMatrix(Transform::Mat4& result) const { updateCache(); result = (*_matrix);