From 9c083ce86e6e9ed7e5235f40e90c1592c3168a95 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 13 Jan 2015 15:51:18 -0800 Subject: [PATCH] Using the model::Material for rendering and in shaders --- libraries/render-utils/src/Material.slh | 59 +++++++++++++++++++++++++ libraries/render-utils/src/Model.cpp | 42 +++++++++++++++--- libraries/render-utils/src/Model.h | 1 + libraries/render-utils/src/model.slf | 14 +++--- 4 files changed, 105 insertions(+), 11 deletions(-) create mode 100755 libraries/render-utils/src/Material.slh diff --git a/libraries/render-utils/src/Material.slh b/libraries/render-utils/src/Material.slh new file mode 100755 index 0000000000..4720b19d00 --- /dev/null +++ b/libraries/render-utils/src/Material.slh @@ -0,0 +1,59 @@ + +<@if not MATERIAL_SLH@> +<@def MATERIAL_SLH@> + +struct Material { + vec4 _diffuse; + vec4 _specular; + + float getOpacity() { return _diffuse.a; } + vec3 getDiffuse() { return _diffuse.rgb; } + vec3 getSpecular() { return _specular.rgb; } + float getShininess() { return _specular.a; } +}; + +<@if GLPROFILE == PC_GL@> +uniform materialBuffer { + Material mat; +}; +Material getMaterial() { + return mat; +} +<@elif GLPROFILE == MAC_GL@> +uniform vec4 materialBuffer[2]; +Material getMaterial() { + Material mat; + mat._diffuse = materialBuffer[0]; + mat._specular = materialBuffer[1]; + return mat; +} +<@else@> +uniform vec4 materialBuffer[2]; +Material getMaterial() { + Material mat; + mat._diffuse = materialBuffer[0]; + mat._specular = materialBuffer[1]; + return mat; +} +<@endif@> + + + +<@endif@> \ No newline at end of file diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 6cfad9931d..2b9418b82f 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -198,6 +198,28 @@ void Model::initProgram(ProgramObject& program, Model::Locations& locations, boo locations.emissiveTextureUnit = -1; } + // bindable uniform version +#if defined(Q_OS_MAC) + loc = program.uniformLocation("materialBuffer"); + if (loc >= 0) { + locations.materialBufferUnit = loc; + } else { + locations.materialBufferUnit = -1; + } +#else + loc = glGetUniformBlockIndex(program.programId(), "materialBuffer"); + if (loc >= 0) { + glUniformBlockBinding(program.programId(), loc, 1); + locations.materialBufferUnit = 1; + } else { + locations.materialBufferUnit = -1; + } +#endif + + if (!program.isLinked()) { + program.release(); + } + program.release(); } @@ -2348,6 +2370,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod for (int j = 0; j < networkMesh.parts.size(); j++) { const NetworkMeshPart& networkPart = networkMesh.parts.at(j); const FBXMeshPart& part = mesh.parts.at(j); + model::MaterialPointer material = part._material; if ((networkPart.isTranslucent() || part.opacity != 1.0f) != translucent) { offset += (part.quadIndices.size() + part.triangleIndices.size()) * sizeof(int); continue; @@ -2366,7 +2389,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod qDebug() << "NEW part.materialID:" << part.materialID; } - glm::vec4 diffuse = glm::vec4(part.diffuseColor, part.opacity); + glm::vec4 diffuse = glm::vec4(material->getDiffuse(), material->getOpacity()); if (locations->glowIntensity >= 0) { GLBATCH(glUniform1f)(locations->glowIntensity, glowEffect->getIntensity()); @@ -2374,11 +2397,18 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod if (!(translucent && alphaThreshold == 0.0f)) { GLBATCH(glAlphaFunc)(GL_EQUAL, diffuse.a = glowEffect->getIntensity()); } - glm::vec4 specular = glm::vec4(part.specularColor, 1.0f); - GLBATCH(glMaterialfv)(GL_FRONT, GL_AMBIENT, (const float*)&diffuse); - GLBATCH(glMaterialfv)(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse); - GLBATCH(glMaterialfv)(GL_FRONT, GL_SPECULAR, (const float*)&specular); - GLBATCH(glMaterialf)(GL_FRONT, GL_SHININESS, (part.shininess > 128.0f ? 128.0f: part.shininess)); + glm::vec4 specular = glm::vec4(material->getSpecular(), 1.0f); + float shininess = material->getShininess(); + shininess = (shininess > 128.0f ? 128.0f: shininess); + + if (locations->materialBufferUnit >= 0) { + batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer()); + } else { + GLBATCH(glMaterialfv)(GL_FRONT, GL_AMBIENT, (const float*)&diffuse); + GLBATCH(glMaterialfv)(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse); + GLBATCH(glMaterialfv)(GL_FRONT, GL_SPECULAR, (const float*)&specular); + GLBATCH(glMaterialf)(GL_FRONT, GL_SHININESS, shininess); + } Texture* diffuseMap = networkPart.diffuseTexture.data(); if (mesh.isEye && diffuseMap) { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index ef97e7dfd8..e10f218563 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -339,6 +339,7 @@ private: int emissiveTextureUnit; int emissiveParams; int glowIntensity; + int materialBufferUnit; }; static Locations _locations; diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index bbff368c2d..396935b4b8 100755 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -13,6 +13,8 @@ <@include DeferredBufferWrite.slh@> +<@include Material.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -20,13 +22,15 @@ uniform sampler2D diffuseMap; varying vec4 normal; void main(void) { - // set the diffuse, normal, specular data + // Fetch diffuse map vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + Material mat = getMaterial(); + packDeferredFragment( normalize(normal.xyz), - evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), - gl_Color.rgb * diffuse.rgb, - gl_FrontMaterial.specular.rgb, - gl_FrontMaterial.shininess); + evalOpaqueFinalAlpha(mat.getOpacity(), diffuse.a), + mat.getDiffuse()/* * diffuse.rgb*/, + mat.getSpecular(), + mat.getShininess()); }