1 package com.badlogic.gdx.graphics.g3d.shaders;
3 import com.badlogic.gdx.Gdx;
4 import com.badlogic.gdx.graphics.Camera;
5 import com.badlogic.gdx.graphics.GL10;
6 import com.badlogic.gdx.graphics.GL20;
7 import com.badlogic.gdx.graphics.VertexAttribute;
8 import com.badlogic.gdx.graphics.VertexAttributes.Usage;
9 import com.badlogic.gdx.graphics.g3d.Renderable;
10 import com.badlogic.gdx.graphics.g3d.attributes.BlendingAttribute;
11 import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute;
12 import com.badlogic.gdx.graphics.g3d.shaders.DefaultShader.Config;
13 import com.badlogic.gdx.graphics.g3d.utils.RenderContext;
14 import com.badlogic.gdx.graphics.glutils.ShaderProgram;
16 public class DepthShader extends DefaultShader {
17 public static class Config extends DefaultShader.Config {
18 public boolean depthBufferOnly = false;
23 public Config (String vertexShader, String fragmentShader) {
24 super(vertexShader, fragmentShader);
28 private static String defaultVertexShader = null;
29 public final static String getDefaultVertexShader() {
30 if (defaultVertexShader == null)
31 defaultVertexShader = Gdx.files.classpath("com/badlogic/gdx/graphics/g3d/shaders/depth.vertex.glsl").readString();
32 return defaultVertexShader;
35 private static String defaultFragmentShader = null;
36 public final static String getDefaultFragmentShader() {
37 if (defaultFragmentShader == null)
38 defaultFragmentShader = Gdx.files.classpath("com/badlogic/gdx/graphics/g3d/shaders/depth.fragment.glsl").readString();
39 return defaultFragmentShader;
42 public static String createPrefix(final Renderable renderable, final Config config) {
44 final long mask = renderable.material.getMask();
45 final long attributes = renderable.mesh.getVertexAttributes().getMask();
46 if ((attributes & Usage.BoneWeight) == Usage.BoneWeight) {
47 final int n = renderable.mesh.getVertexAttributes().size();
48 for (int i = 0; i < n; i++) {
49 final VertexAttribute attr = renderable.mesh.getVertexAttributes().get(i);
50 if (attr.usage == Usage.BoneWeight)
51 prefix += "#define boneWeight"+attr.unit+"Flag\n";
54 // FIXME Add transparent texture support
55 // if ((mask & BlendingAttribute.Type) == BlendingAttribute.Type)
56 // prefix += "#define "+BlendingAttribute.Alias+"Flag\n";
57 // if ((mask & TextureAttribute.Diffuse) == TextureAttribute.Diffuse)
58 // prefix += "#define "+TextureAttribute.DiffuseAlias+"Flag\n";
59 if (renderable.bones != null && config.numBones > 0)
60 prefix += "#define numBones "+config.numBones+"\n";
61 if (!config.depthBufferOnly)
62 prefix += "#define PackedDepthFlag\n";
66 public final int numBones;
67 public final int weights;
69 public DepthShader(final Renderable renderable) {
70 this(renderable, new Config());
73 public DepthShader(final Renderable renderable, final Config config) {
74 this(renderable, config, createPrefix(renderable, config));
77 public DepthShader(final Renderable renderable, final Config config, final String prefix) {
78 this(renderable, config, prefix,
79 config.vertexShader != null ? config.vertexShader : getDefaultVertexShader(),
80 config.fragmentShader != null ? config.fragmentShader : getDefaultFragmentShader());
83 public DepthShader(final Renderable renderable, final Config config, final String prefix, final String vertexShader, final String fragmentShader) {
84 this(renderable, config, new ShaderProgram(prefix + vertexShader, prefix + fragmentShader));
87 public DepthShader(final Renderable renderable, final Config config, final ShaderProgram shaderProgram) {
88 super(renderable, config, shaderProgram);
89 this.numBones = renderable.bones == null ? 0 : config.numBones;
91 final int n = renderable.mesh.getVertexAttributes().size();
92 for (int i = 0; i < n; i++) {
93 final VertexAttribute attr = renderable.mesh.getVertexAttributes().get(i);
94 if (attr.usage == Usage.BoneWeight)
95 w |= (1 << attr.unit);
100 private int originalCullFace;
102 public void begin (Camera camera, RenderContext context) {
103 originalCullFace = DefaultShader.defaultCullFace;
104 DefaultShader.defaultCullFace = GL10.GL_FRONT; //0; //GL10.GL_BACK; //GL10.GL_FRONT;
105 super.begin(camera, context);
106 //Gdx.gl20.glEnable(GL20.GL_POLYGON_OFFSET_FILL);
107 //Gdx.gl20.glPolygonOffset(2.f, 100.f);
113 DefaultShader.defaultCullFace = originalCullFace;
114 Gdx.gl20.glDisable(GL20.GL_POLYGON_OFFSET_FILL);
118 public boolean canRender (Renderable renderable) {
119 final boolean skinned = ((renderable.mesh.getVertexAttributes().getMask() & Usage.BoneWeight) == Usage.BoneWeight);
120 if (skinned != (numBones > 0))
125 final int n = renderable.mesh.getVertexAttributes().size();
126 for (int i = 0; i < n; i++) {
127 final VertexAttribute attr = renderable.mesh.getVertexAttributes().get(i);
128 if (attr.usage == Usage.BoneWeight)
129 w |= (1 << attr.unit);