|
|
|
|
@@ -19,6 +19,7 @@ import com.badlogic.gdx.Gdx;
|
|
|
|
|
import com.badlogic.gdx.graphics.Camera;
|
|
|
|
|
import com.badlogic.gdx.graphics.Color;
|
|
|
|
|
import com.badlogic.gdx.graphics.GL20;
|
|
|
|
|
import com.badlogic.gdx.graphics.VertexAttributes;
|
|
|
|
|
import com.badlogic.gdx.graphics.g3d.Renderable;
|
|
|
|
|
import com.badlogic.gdx.graphics.g3d.Shader;
|
|
|
|
|
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
|
|
|
|
|
@@ -30,59 +31,100 @@ import com.badlogic.gdx.math.Vector3;
|
|
|
|
|
import com.badlogic.gdx.utils.GdxRuntimeException;
|
|
|
|
|
|
|
|
|
|
public class SingleLightPerPixelShader implements Shader{
|
|
|
|
|
private static final String VERTEX_SHADER_PATH = "shaders/directionalPerPixelSingleLight/directionalPerPixel_vert.glsl";
|
|
|
|
|
private static final String FRAGMENT_SHADER_PATH = "shaders/directionalPerPixelSingleLight/directionalPerPixel_frag.glsl";
|
|
|
|
|
private static final int MAX_NUM_BONES = 4;
|
|
|
|
|
private static final Matrix4 IDENTITY = new Matrix4();
|
|
|
|
|
private static final String VERTEX_SHADER_PATH = "shaders/directionalPerPixelSingleLight/directionalPerPixel_vert.glsl";
|
|
|
|
|
private static final String FRAGMENT_SHADER_PATH = "shaders/directionalPerPixelSingleLight/directionalPerPixel_frag.glsl";
|
|
|
|
|
private static final String INCLUDE_SKINNING = "#define SKINNING\n";
|
|
|
|
|
|
|
|
|
|
private ShaderProgram program;
|
|
|
|
|
private ShaderProgram skinningProgram;
|
|
|
|
|
private ShaderProgram baseProgram;
|
|
|
|
|
private Camera camera;
|
|
|
|
|
private RenderContext context;
|
|
|
|
|
private Matrix4 normalMatrix;
|
|
|
|
|
|
|
|
|
|
// Uniform locations.
|
|
|
|
|
private int u_geomTrans;
|
|
|
|
|
private int u_projTrans;
|
|
|
|
|
private int u_lightPos;
|
|
|
|
|
private int u_lightDiffuse;
|
|
|
|
|
private int u_specular;
|
|
|
|
|
private int u_ambient;
|
|
|
|
|
private int u_shiny;
|
|
|
|
|
private int u_cameraPos;
|
|
|
|
|
private int u_materialDiffuse;
|
|
|
|
|
private int u_normalMatrix;
|
|
|
|
|
private int[] u_geomTrans;
|
|
|
|
|
private int[] u_projTrans;
|
|
|
|
|
private int[] u_lightPos;
|
|
|
|
|
private int[] u_lightDiffuse;
|
|
|
|
|
private int[] u_specular;
|
|
|
|
|
private int[] u_ambient;
|
|
|
|
|
private int[] u_shiny;
|
|
|
|
|
private int[] u_cameraPos;
|
|
|
|
|
private int[] u_materialDiffuse;
|
|
|
|
|
private int[] u_normalMatrix;
|
|
|
|
|
private int[] u_bones;
|
|
|
|
|
|
|
|
|
|
public SingleLightPerPixelShader(){
|
|
|
|
|
program = null;
|
|
|
|
|
camera = null;
|
|
|
|
|
context = null;
|
|
|
|
|
skinningProgram = null;
|
|
|
|
|
baseProgram = null;
|
|
|
|
|
camera = null;
|
|
|
|
|
context = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void init() throws GdxRuntimeException{
|
|
|
|
|
normalMatrix = new Matrix4().idt();
|
|
|
|
|
u_bones = new int[MAX_NUM_BONES];
|
|
|
|
|
|
|
|
|
|
// Compile the shader.
|
|
|
|
|
program = new ShaderProgram(Gdx.files.internal(VERTEX_SHADER_PATH), Gdx.files.internal(FRAGMENT_SHADER_PATH));
|
|
|
|
|
String vertexCode = Gdx.files.internal(VERTEX_SHADER_PATH).readString();
|
|
|
|
|
String fragmentCode = Gdx.files.internal(FRAGMENT_SHADER_PATH).readString();
|
|
|
|
|
|
|
|
|
|
if(!program.isCompiled())
|
|
|
|
|
throw new GdxRuntimeException(program.getLog());
|
|
|
|
|
skinningProgram = new ShaderProgram(INCLUDE_SKINNING + vertexCode, fragmentCode);
|
|
|
|
|
baseProgram = new ShaderProgram(vertexCode, fragmentCode);
|
|
|
|
|
|
|
|
|
|
if(!skinningProgram.isCompiled())
|
|
|
|
|
throw new GdxRuntimeException(skinningProgram.getLog());
|
|
|
|
|
|
|
|
|
|
if(!baseProgram.isCompiled())
|
|
|
|
|
throw new GdxRuntimeException(skinningProgram.getLog());
|
|
|
|
|
|
|
|
|
|
// Create uniform locations.
|
|
|
|
|
u_projTrans = new int[2];
|
|
|
|
|
u_geomTrans = new int[2];
|
|
|
|
|
u_lightPos = new int[2];
|
|
|
|
|
u_lightDiffuse = new int[2];
|
|
|
|
|
u_specular = new int[2];
|
|
|
|
|
u_ambient = new int[2];
|
|
|
|
|
u_shiny = new int[2];
|
|
|
|
|
u_cameraPos = new int[2];
|
|
|
|
|
u_materialDiffuse = new int[2];
|
|
|
|
|
u_normalMatrix = new int[2];
|
|
|
|
|
|
|
|
|
|
// Cache uniform locations.
|
|
|
|
|
u_projTrans = program.getUniformLocation("u_projTrans");
|
|
|
|
|
u_geomTrans = program.getUniformLocation("u_geomTrans");
|
|
|
|
|
u_lightPos = program.getUniformLocation("u_lightPos");
|
|
|
|
|
u_lightDiffuse = program.getUniformLocation("u_lightDiffuse");
|
|
|
|
|
u_specular = program.getUniformLocation("u_specular");
|
|
|
|
|
u_ambient = program.getUniformLocation("u_ambient");
|
|
|
|
|
u_shiny = program.getUniformLocation("u_shiny");
|
|
|
|
|
u_cameraPos = program.getUniformLocation("u_cameraPos");
|
|
|
|
|
u_materialDiffuse = program.getUniformLocation("u_materialDiffuse");
|
|
|
|
|
u_normalMatrix = program.getUniformLocation("u_normalMatrix");
|
|
|
|
|
u_projTrans [0] = skinningProgram.getUniformLocation("u_projTrans");
|
|
|
|
|
u_geomTrans [0] = skinningProgram.getUniformLocation("u_geomTrans");
|
|
|
|
|
u_lightPos [0] = skinningProgram.getUniformLocation("u_lightPos");
|
|
|
|
|
u_lightDiffuse [0] = skinningProgram.getUniformLocation("u_lightDiffuse");
|
|
|
|
|
u_specular [0] = skinningProgram.getUniformLocation("u_specular");
|
|
|
|
|
u_ambient [0] = skinningProgram.getUniformLocation("u_ambient");
|
|
|
|
|
u_shiny [0] = skinningProgram.getUniformLocation("u_shiny");
|
|
|
|
|
u_cameraPos [0] = skinningProgram.getUniformLocation("u_cameraPos");
|
|
|
|
|
u_materialDiffuse [0] = skinningProgram.getUniformLocation("u_materialDiffuse");
|
|
|
|
|
u_normalMatrix [0] = skinningProgram.getUniformLocation("u_normalMatrix");
|
|
|
|
|
|
|
|
|
|
u_projTrans [1] = baseProgram.getUniformLocation("u_projTrans");
|
|
|
|
|
u_geomTrans [1] = baseProgram.getUniformLocation("u_geomTrans");
|
|
|
|
|
u_lightPos [1] = baseProgram.getUniformLocation("u_lightPos");
|
|
|
|
|
u_lightDiffuse [1] = baseProgram.getUniformLocation("u_lightDiffuse");
|
|
|
|
|
u_specular [1] = baseProgram.getUniformLocation("u_specular");
|
|
|
|
|
u_ambient [1] = baseProgram.getUniformLocation("u_ambient");
|
|
|
|
|
u_shiny [1] = baseProgram.getUniformLocation("u_shiny");
|
|
|
|
|
u_cameraPos [1] = baseProgram.getUniformLocation("u_cameraPos");
|
|
|
|
|
u_materialDiffuse [1] = baseProgram.getUniformLocation("u_materialDiffuse");
|
|
|
|
|
u_normalMatrix [1] = baseProgram.getUniformLocation("u_normalMatrix");
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < MAX_NUM_BONES; i++){
|
|
|
|
|
u_bones[i] = skinningProgram.getUniformLocation("u_bone" + Integer.toString(i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void dispose(){
|
|
|
|
|
if(program != null)
|
|
|
|
|
program.dispose();
|
|
|
|
|
if(skinningProgram != null) skinningProgram.dispose();
|
|
|
|
|
if(baseProgram != null) baseProgram.dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@@ -118,11 +160,6 @@ public class SingleLightPerPixelShader implements Shader{
|
|
|
|
|
|
|
|
|
|
this.camera = camera;
|
|
|
|
|
this.context = context;
|
|
|
|
|
program.begin();
|
|
|
|
|
|
|
|
|
|
// Set camera dependant uniforms.
|
|
|
|
|
program.setUniformMatrix(u_projTrans, this.camera.combined);
|
|
|
|
|
program.setUniformf(u_cameraPos, this.camera.position);
|
|
|
|
|
|
|
|
|
|
// Set render context.
|
|
|
|
|
this.context.setDepthTest(GL20.GL_LEQUAL);
|
|
|
|
|
@@ -131,6 +168,10 @@ public class SingleLightPerPixelShader implements Shader{
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void render(Renderable renderable){
|
|
|
|
|
ShaderProgram program;
|
|
|
|
|
int index;
|
|
|
|
|
boolean bonesEnabled;
|
|
|
|
|
|
|
|
|
|
// Get material colors.
|
|
|
|
|
Vector3 lightPosition = renderable.environment.directionalLights.get(0).direction;
|
|
|
|
|
Color diffuseLightColor = renderable.environment.directionalLights.get(0).color;
|
|
|
|
|
@@ -139,24 +180,49 @@ public class SingleLightPerPixelShader implements Shader{
|
|
|
|
|
Color ambientColor = ((ColorAttribute)renderable.environment.get(ColorAttribute.AmbientLight)).color;
|
|
|
|
|
float shininess = ((FloatAttribute)renderable.material.get(FloatAttribute.Shininess)).value;
|
|
|
|
|
|
|
|
|
|
// Set model dependant uniforms.
|
|
|
|
|
program.setUniformMatrix(u_geomTrans, renderable.worldTransform);
|
|
|
|
|
program.setUniformMatrix(u_normalMatrix, normalMatrix.idt().mul(renderable.worldTransform).inv().tra());
|
|
|
|
|
program.setUniformf(u_lightPos, lightPosition);
|
|
|
|
|
program.setUniformf(u_lightDiffuse, diffuseLightColor);
|
|
|
|
|
program.setUniformf(u_materialDiffuse, diffuseColor);
|
|
|
|
|
program.setUniformf(u_specular, specularColor);
|
|
|
|
|
program.setUniformf(u_ambient, ambientColor);
|
|
|
|
|
program.setUniformf(u_shiny, shininess);
|
|
|
|
|
if(renderable.mesh.getVertexAttribute(VertexAttributes.Usage.BoneWeight) != null){
|
|
|
|
|
program = skinningProgram;
|
|
|
|
|
index = 0;
|
|
|
|
|
bonesEnabled = true;
|
|
|
|
|
}else{
|
|
|
|
|
program = baseProgram;
|
|
|
|
|
index = 1;
|
|
|
|
|
bonesEnabled = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
program.begin();
|
|
|
|
|
|
|
|
|
|
// Set camera dependant uniforms.
|
|
|
|
|
program.setUniformMatrix(u_projTrans[index], this.camera.combined);
|
|
|
|
|
program.setUniformf(u_cameraPos[index], this.camera.position);
|
|
|
|
|
|
|
|
|
|
// Set model dependant uniforms.
|
|
|
|
|
program.setUniformMatrix(u_geomTrans[index], renderable.worldTransform);
|
|
|
|
|
program.setUniformMatrix(u_normalMatrix[index], normalMatrix.idt().mul(renderable.worldTransform).inv().tra());
|
|
|
|
|
program.setUniformf(u_lightPos[index], lightPosition);
|
|
|
|
|
program.setUniformf(u_lightDiffuse[index], diffuseLightColor);
|
|
|
|
|
program.setUniformf(u_materialDiffuse[index], diffuseColor);
|
|
|
|
|
program.setUniformf(u_specular[index], specularColor);
|
|
|
|
|
program.setUniformf(u_ambient[index], ambientColor);
|
|
|
|
|
program.setUniformf(u_shiny[index], shininess);
|
|
|
|
|
|
|
|
|
|
// Set the bones uniforms.
|
|
|
|
|
if(bonesEnabled){
|
|
|
|
|
for(int i = 0; i < MAX_NUM_BONES; i++){
|
|
|
|
|
if(renderable.bones != null && i < renderable.bones.length && renderable.bones[i] != null)
|
|
|
|
|
skinningProgram.setUniformMatrix(u_bones[i], renderable.bones[i]);
|
|
|
|
|
else
|
|
|
|
|
skinningProgram.setUniformMatrix(u_bones[i], IDENTITY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Render.
|
|
|
|
|
renderable.mesh.render(program, renderable.primitiveType, renderable.meshPartOffset, renderable.meshPartSize);
|
|
|
|
|
|
|
|
|
|
program.end();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void end(){
|
|
|
|
|
program.end();
|
|
|
|
|
|
|
|
|
|
this.camera = null;
|
|
|
|
|
this.context = null;
|
|
|
|
|
}
|
|
|
|
|
|