OSDN Git Service

Various changes regarding lights/environment/defaultshaders
[mikumikustudio/libgdx-mikumikustudio.git] / gdx / src / com / badlogic / gdx / graphics / g3d / shaders / DepthShader.java
1 package com.badlogic.gdx.graphics.g3d.shaders;
2
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;
15
16 public class DepthShader extends DefaultShader {
17         public static class Config extends DefaultShader.Config {
18                 public boolean depthBufferOnly = false;
19                 
20                 public Config () {
21                         super();
22                 }
23                 public Config (String vertexShader, String fragmentShader) {
24                         super(vertexShader, fragmentShader);
25                 }
26         }
27         
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;
33         }
34         
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;
40         }
41         
42         public static String createPrefix(final Renderable renderable, final Config config) {
43                 String prefix = "";
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";
52                         }
53                 }
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";
63                 return prefix;
64         }
65         
66         public final int numBones;
67         public final int weights;
68         
69         public DepthShader(final Renderable renderable) {
70                 this(renderable, new Config());
71         }
72         
73         public DepthShader(final Renderable renderable, final Config config) {
74                 this(renderable, config, createPrefix(renderable, config));
75         }
76
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());
81         }
82         
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));
85         }
86         
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;
90                 int w = 0;
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);
96                 }
97                 weights = w;
98         }
99         
100         private int originalCullFace;   
101         @Override
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);
108         }
109         
110         @Override
111         public void end () {
112                 super.end();
113                 DefaultShader.defaultCullFace = originalCullFace;
114                 Gdx.gl20.glDisable(GL20.GL_POLYGON_OFFSET_FILL);
115         }
116         
117         @Override
118         public boolean canRender (Renderable renderable) {
119                 final boolean skinned = ((renderable.mesh.getVertexAttributes().getMask() & Usage.BoneWeight) == Usage.BoneWeight);
120                 if (skinned != (numBones > 0))
121                         return false;
122                 if (!skinned)
123                         return true;
124                 int w = 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);
130                 }
131                 return w == weights;
132         }
133 }