Using the model::Material for rendering and in shaders

This commit is contained in:
Sam Gateau 2015-01-13 15:51:18 -08:00
parent d9efafac7e
commit 9c083ce86e
4 changed files with 105 additions and 11 deletions

View file

@ -0,0 +1,59 @@
<!
// Material.slh
// fragment shader
//
// Created by Sam Gateau on 12/16/14.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
!>
<@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@>
<!/*
bindable uniform struct {
Material mat;
} materialBuffer;
Material getMaterial() {
return materialBuffer.mat;
}
*/!>
<@endif@>

View file

@ -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<int>& 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<int>& 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<int>& 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) {

View file

@ -339,6 +339,7 @@ private:
int emissiveTextureUnit;
int emissiveParams;
int glowIntensity;
int materialBufferUnit;
};
static Locations _locations;

View file

@ -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());
}