@Override public boolean canRender(final Renderable renderable) { final Attributes attributes = combineAttributes(renderable); return (attributesMask == (attributes.getMask() | optionalAttributes)) && (vertexMask == renderable.meshPart.mesh.getVertexAttributes().getMask()) && (renderable.environment != null) == lighting; }
@Override public void set( BaseShader shader, int inputID, Renderable renderable, Attributes combinedAttributes) { if (combinedAttributes.has(CubemapAttribute.EnvironmentMap)) { shader.set( inputID, shader.context.textureBinder.bind( ((CubemapAttribute) combinedAttributes.get(CubemapAttribute.EnvironmentMap)) .textureDescription)); } }
@Override public void render(Renderable renderable, Attributes combinedAttributes) { if (!combinedAttributes.has(BlendingAttribute.Type)) context.setBlending(false, GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); bindMaterial(combinedAttributes); if (lighting) bindLights(renderable, combinedAttributes); super.render(renderable, combinedAttributes); }
@Override public void set( BaseShader shader, int inputID, Renderable renderable, Attributes combinedAttributes) { shader.set( inputID, ((ColorAttribute) (combinedAttributes.get(ColorAttribute.Diffuse))).color); }
@Override public void set( BaseShader shader, int inputID, Renderable renderable, Attributes combinedAttributes) { final TextureAttribute ta = (TextureAttribute) (combinedAttributes.get(TextureAttribute.Ambient)); shader.set(inputID, ta.offsetU, ta.offsetV, ta.scaleU, ta.scaleV); }
@Override public void set( BaseShader shader, int inputID, Renderable renderable, Attributes combinedAttributes) { shader.set( inputID, ((FloatAttribute) (combinedAttributes.get(FloatAttribute.Shininess))).value); }
@Override public void set( BaseShader shader, int inputID, Renderable renderable, Attributes combinedAttributes) { final int unit = shader.context.textureBinder.bind( ((TextureAttribute) (combinedAttributes.get(TextureAttribute.Ambient))) .textureDescription); shader.set(inputID, unit); }
@Override public void set( BaseShader shader, int inputID, Renderable renderable, Attributes combinedAttributes) { if (renderable.environment == null) shader.program.setUniform3fv(shader.loc(inputID), ones, 0, ones.length); else { renderable.worldTransform.getTranslation(tmpV1); if (combinedAttributes.has(ColorAttribute.AmbientLight)) cacheAmbientCubemap.set( ((ColorAttribute) combinedAttributes.get(ColorAttribute.AmbientLight)).color); if (combinedAttributes.has(DirectionalLightsAttribute.Type)) { Array<DirectionalLight> lights = ((DirectionalLightsAttribute) combinedAttributes.get(DirectionalLightsAttribute.Type)) .lights; for (int i = dirLightsOffset; i < lights.size; i++) cacheAmbientCubemap.add(lights.get(i).color, lights.get(i).direction); } if (combinedAttributes.has(PointLightsAttribute.Type)) { Array<PointLight> lights = ((PointLightsAttribute) combinedAttributes.get(PointLightsAttribute.Type)).lights; for (int i = pointLightsOffset; i < lights.size; i++) cacheAmbientCubemap.add( lights.get(i).color, lights.get(i).position, tmpV1, lights.get(i).intensity); } cacheAmbientCubemap.clamp(); shader.program.setUniform3fv( shader.loc(inputID), cacheAmbientCubemap.data, 0, cacheAmbientCubemap.data.length); } }
public static String createPrefix(final Renderable renderable, final Config config) { final Attributes attributes = combineAttributes(renderable); String prefix = ""; final long attributesMask = attributes.getMask(); final long vertexMask = renderable.meshPart.mesh.getVertexAttributes().getMask(); if (and(vertexMask, Usage.Position)) prefix += "#define positionFlag\n"; if (or(vertexMask, Usage.ColorUnpacked | Usage.ColorPacked)) prefix += "#define colorFlag\n"; if (and(vertexMask, Usage.BiNormal)) prefix += "#define binormalFlag\n"; if (and(vertexMask, Usage.Tangent)) prefix += "#define tangentFlag\n"; if (and(vertexMask, Usage.Normal)) prefix += "#define normalFlag\n"; if (and(vertexMask, Usage.Normal) || and(vertexMask, Usage.Tangent | Usage.BiNormal)) { if (renderable.environment != null) { prefix += "#define lightingFlag\n"; prefix += "#define ambientCubemapFlag\n"; prefix += "#define numDirectionalLights " + config.numDirectionalLights + "\n"; prefix += "#define numPointLights " + config.numPointLights + "\n"; prefix += "#define numSpotLights " + config.numSpotLights + "\n"; if (attributes.has(ColorAttribute.Fog)) { prefix += "#define fogFlag\n"; } if (renderable.environment.shadowMap != null) prefix += "#define shadowMapFlag\n"; if (attributes.has(CubemapAttribute.EnvironmentMap)) prefix += "#define environmentCubemapFlag\n"; } } final int n = renderable.meshPart.mesh.getVertexAttributes().size(); for (int i = 0; i < n; i++) { final VertexAttribute attr = renderable.meshPart.mesh.getVertexAttributes().get(i); if (attr.usage == Usage.BoneWeight) prefix += "#define boneWeight" + attr.unit + "Flag\n"; else if (attr.usage == Usage.TextureCoordinates) prefix += "#define texCoord" + attr.unit + "Flag\n"; } if ((attributesMask & BlendingAttribute.Type) == BlendingAttribute.Type) prefix += "#define " + BlendingAttribute.Alias + "Flag\n"; if ((attributesMask & TextureAttribute.Diffuse) == TextureAttribute.Diffuse) { prefix += "#define " + TextureAttribute.DiffuseAlias + "Flag\n"; prefix += "#define " + TextureAttribute.DiffuseAlias + "Coord texCoord0\n"; // FIXME implement UV mapping } if ((attributesMask & TextureAttribute.Specular) == TextureAttribute.Specular) { prefix += "#define " + TextureAttribute.SpecularAlias + "Flag\n"; prefix += "#define " + TextureAttribute.SpecularAlias + "Coord texCoord0\n"; // FIXME implement UV mapping } if ((attributesMask & TextureAttribute.Normal) == TextureAttribute.Normal) { prefix += "#define " + TextureAttribute.NormalAlias + "Flag\n"; prefix += "#define " + TextureAttribute.NormalAlias + "Coord texCoord0\n"; // FIXME implement UV mapping } if ((attributesMask & TextureAttribute.Emissive) == TextureAttribute.Emissive) { prefix += "#define " + TextureAttribute.EmissiveAlias + "Flag\n"; prefix += "#define " + TextureAttribute.EmissiveAlias + "Coord texCoord0\n"; // FIXME implement UV mapping } if ((attributesMask & TextureAttribute.Reflection) == TextureAttribute.Reflection) { prefix += "#define " + TextureAttribute.ReflectionAlias + "Flag\n"; prefix += "#define " + TextureAttribute.ReflectionAlias + "Coord texCoord0\n"; // FIXME implement UV mapping } if ((attributesMask & TextureAttribute.Ambient) == TextureAttribute.Ambient) { prefix += "#define " + TextureAttribute.AmbientAlias + "Flag\n"; prefix += "#define " + TextureAttribute.AmbientAlias + "Coord texCoord0\n"; // FIXME implement UV mapping } if ((attributesMask & ColorAttribute.Diffuse) == ColorAttribute.Diffuse) prefix += "#define " + ColorAttribute.DiffuseAlias + "Flag\n"; if ((attributesMask & ColorAttribute.Specular) == ColorAttribute.Specular) prefix += "#define " + ColorAttribute.SpecularAlias + "Flag\n"; if ((attributesMask & ColorAttribute.Emissive) == ColorAttribute.Emissive) prefix += "#define " + ColorAttribute.EmissiveAlias + "Flag\n"; if ((attributesMask & ColorAttribute.Reflection) == ColorAttribute.Reflection) prefix += "#define " + ColorAttribute.ReflectionAlias + "Flag\n"; if ((attributesMask & FloatAttribute.Shininess) == FloatAttribute.Shininess) prefix += "#define " + FloatAttribute.ShininessAlias + "Flag\n"; if ((attributesMask & FloatAttribute.AlphaTest) == FloatAttribute.AlphaTest) prefix += "#define " + FloatAttribute.AlphaTestAlias + "Flag\n"; if (renderable.bones != null && config.numBones > 0) prefix += "#define numBones " + config.numBones + "\n"; return prefix; }
// TODO: Perhaps move responsibility for combining attributes to RenderableProvider? private static final Attributes combineAttributes(final Renderable renderable) { tmpAttributes.clear(); if (renderable.environment != null) tmpAttributes.set(renderable.environment); if (renderable.material != null) tmpAttributes.set(renderable.material); return tmpAttributes; }
public DefaultShader( final Renderable renderable, final Config config, final ShaderProgram shaderProgram) { final Attributes attributes = combineAttributes(renderable); this.config = config; this.program = shaderProgram; this.lighting = renderable.environment != null; this.environmentCubemap = attributes.has(CubemapAttribute.EnvironmentMap) || (lighting && attributes.has(CubemapAttribute.EnvironmentMap)); this.shadowMap = lighting && renderable.environment.shadowMap != null; this.renderable = renderable; attributesMask = attributes.getMask() | optionalAttributes; vertexMask = renderable.meshPart.mesh.getVertexAttributes().getMask(); this.directionalLights = new DirectionalLight [lighting && config.numDirectionalLights > 0 ? config.numDirectionalLights : 0]; for (int i = 0; i < directionalLights.length; i++) directionalLights[i] = new DirectionalLight(); this.pointLights = new PointLight[lighting && config.numPointLights > 0 ? config.numPointLights : 0]; for (int i = 0; i < pointLights.length; i++) pointLights[i] = new PointLight(); this.spotLights = new SpotLight[lighting && config.numSpotLights > 0 ? config.numSpotLights : 0]; for (int i = 0; i < spotLights.length; i++) spotLights[i] = new SpotLight(); if (!config.ignoreUnimplemented && (implementedFlags & attributesMask) != attributesMask) throw new GdxRuntimeException("Some attributes not implemented yet (" + attributesMask + ")"); // Global uniforms u_projTrans = register(Inputs.projTrans, Setters.projTrans); u_viewTrans = register(Inputs.viewTrans, Setters.viewTrans); u_projViewTrans = register(Inputs.projViewTrans, Setters.projViewTrans); u_cameraPosition = register(Inputs.cameraPosition, Setters.cameraPosition); u_cameraDirection = register(Inputs.cameraDirection, Setters.cameraDirection); u_cameraUp = register(Inputs.cameraUp, Setters.cameraUp); u_time = register(new Uniform("u_time")); // Object uniforms u_worldTrans = register(Inputs.worldTrans, Setters.worldTrans); u_viewWorldTrans = register(Inputs.viewWorldTrans, Setters.viewWorldTrans); u_projViewWorldTrans = register(Inputs.projViewWorldTrans, Setters.projViewWorldTrans); u_normalMatrix = register(Inputs.normalMatrix, Setters.normalMatrix); u_bones = (renderable.bones != null && config.numBones > 0) ? register(Inputs.bones, new Setters.Bones(config.numBones)) : -1; u_shininess = register(Inputs.shininess, Setters.shininess); u_opacity = register(Inputs.opacity); u_diffuseColor = register(Inputs.diffuseColor, Setters.diffuseColor); u_diffuseTexture = register(Inputs.diffuseTexture, Setters.diffuseTexture); u_diffuseUVTransform = register(Inputs.diffuseUVTransform, Setters.diffuseUVTransform); u_specularColor = register(Inputs.specularColor, Setters.specularColor); u_specularTexture = register(Inputs.specularTexture, Setters.specularTexture); u_specularUVTransform = register(Inputs.specularUVTransform, Setters.specularUVTransform); u_emissiveColor = register(Inputs.emissiveColor, Setters.emissiveColor); u_emissiveTexture = register(Inputs.emissiveTexture, Setters.emissiveTexture); u_emissiveUVTransform = register(Inputs.emissiveUVTransform, Setters.emissiveUVTransform); u_reflectionColor = register(Inputs.reflectionColor, Setters.reflectionColor); u_reflectionTexture = register(Inputs.reflectionTexture, Setters.reflectionTexture); u_reflectionUVTransform = register(Inputs.reflectionUVTransform, Setters.reflectionUVTransform); u_normalTexture = register(Inputs.normalTexture, Setters.normalTexture); u_normalUVTransform = register(Inputs.normalUVTransform, Setters.normalUVTransform); u_ambientTexture = register(Inputs.ambientTexture, Setters.ambientTexture); u_ambientUVTransform = register(Inputs.ambientUVTransform, Setters.ambientUVTransform); u_alphaTest = register(Inputs.alphaTest); u_ambientCubemap = lighting ? register( Inputs.ambientCube, new Setters.ACubemap(config.numDirectionalLights, config.numPointLights)) : -1; u_environmentCubemap = environmentCubemap ? register(Inputs.environmentCubemap, Setters.environmentCubemap) : -1; }
protected void bindLights(final Renderable renderable, final Attributes attributes) { final Environment lights = renderable.environment; final DirectionalLightsAttribute dla = attributes.get(DirectionalLightsAttribute.class, DirectionalLightsAttribute.Type); final Array<DirectionalLight> dirs = dla == null ? null : dla.lights; final PointLightsAttribute pla = attributes.get(PointLightsAttribute.class, PointLightsAttribute.Type); final Array<PointLight> points = pla == null ? null : pla.lights; final SpotLightsAttribute sla = attributes.get(SpotLightsAttribute.class, SpotLightsAttribute.Type); final Array<SpotLight> spots = sla == null ? null : sla.lights; if (dirLightsLoc >= 0) { for (int i = 0; i < directionalLights.length; i++) { if (dirs == null || i >= dirs.size) { if (lightsSet && directionalLights[i].color.r == 0f && directionalLights[i].color.g == 0f && directionalLights[i].color.b == 0f) continue; directionalLights[i].color.set(0, 0, 0, 1); } else if (lightsSet && directionalLights[i].equals(dirs.get(i))) continue; else directionalLights[i].set(dirs.get(i)); int idx = dirLightsLoc + i * dirLightsSize; program.setUniformf( idx + dirLightsColorOffset, directionalLights[i].color.r, directionalLights[i].color.g, directionalLights[i].color.b); program.setUniformf( idx + dirLightsDirectionOffset, directionalLights[i].direction.x, directionalLights[i].direction.y, directionalLights[i].direction.z); if (dirLightsSize <= 0) break; } } if (pointLightsLoc >= 0) { for (int i = 0; i < pointLights.length; i++) { if (points == null || i >= points.size) { if (lightsSet && pointLights[i].intensity == 0f) continue; pointLights[i].intensity = 0f; } else if (lightsSet && pointLights[i].equals(points.get(i))) continue; else pointLights[i].set(points.get(i)); int idx = pointLightsLoc + i * pointLightsSize; program.setUniformf( idx + pointLightsColorOffset, pointLights[i].color.r * pointLights[i].intensity, pointLights[i].color.g * pointLights[i].intensity, pointLights[i].color.b * pointLights[i].intensity); program.setUniformf( idx + pointLightsPositionOffset, pointLights[i].position.x, pointLights[i].position.y, pointLights[i].position.z); if (pointLightsIntensityOffset >= 0) program.setUniformf(idx + pointLightsIntensityOffset, pointLights[i].intensity); if (pointLightsSize <= 0) break; } } if (spotLightsLoc >= 0) { for (int i = 0; i < spotLights.length; i++) { if (spots == null || i >= spots.size) { if (lightsSet && spotLights[i].intensity == 0f) continue; spotLights[i].intensity = 0f; } else if (lightsSet && spotLights[i].equals(spots.get(i))) continue; else spotLights[i].set(spots.get(i)); int idx = spotLightsLoc + i * spotLightsSize; program.setUniformf( idx + spotLightsColorOffset, spotLights[i].color.r * spotLights[i].intensity, spotLights[i].color.g * spotLights[i].intensity, spotLights[i].color.b * spotLights[i].intensity); program.setUniformf(idx + spotLightsPositionOffset, spotLights[i].position); program.setUniformf(idx + spotLightsDirectionOffset, spotLights[i].direction); program.setUniformf(idx + spotLightsCutoffAngleOffset, spotLights[i].cutoffAngle); program.setUniformf(idx + spotLightsExponentOffset, spotLights[i].exponent); if (spotLightsIntensityOffset >= 0) program.setUniformf(idx + spotLightsIntensityOffset, spotLights[i].intensity); if (spotLightsSize <= 0) break; } } if (attributes.has(ColorAttribute.Fog)) { set(u_fogColor, ((ColorAttribute) attributes.get(ColorAttribute.Fog)).color); } if (lights != null && lights.shadowMap != null) { set(u_shadowMapProjViewTrans, lights.shadowMap.getProjViewTrans()); set(u_shadowTexture, lights.shadowMap.getDepthMap()); set(u_shadowPCFOffset, 1.f / (2f * lights.shadowMap.getDepthMap().texture.getWidth())); } lightsSet = true; }