OSDN Git Service

Merge pull request #589 from jrenner/graphics-array-refactor
[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.materials.BlendingAttribute;
11 import com.badlogic.gdx.graphics.g3d.materials.TextureAttribute;
12 import com.badlogic.gdx.graphics.g3d.utils.RenderContext;
13 import com.badlogic.gdx.graphics.glutils.ShaderProgram;
14
15 public class DepthShader extends DefaultShader {
16         private static String defaultVertexShader = null;
17         public final static String getDefaultVertexShader() {
18                 if (defaultVertexShader == null)
19                         defaultVertexShader = Gdx.files.classpath("com/badlogic/gdx/graphics/g3d/shaders/depth.vertex.glsl").readString();
20                 return defaultVertexShader;
21         }
22         
23         private static String defaultFragmentShader = null;
24         public final static String getDefaultFragmentShader() {
25                 if (defaultFragmentShader == null)
26                         defaultFragmentShader = Gdx.files.classpath("com/badlogic/gdx/graphics/g3d/shaders/depth.fragment.glsl").readString();
27                 return defaultFragmentShader;
28         }
29         
30         public static String createPrefix(final Renderable renderable, int numBones, boolean depthBufferOnly) {
31                 String prefix = "";
32                 final long mask = renderable.material.getMask();
33                 final long attributes = renderable.mesh.getVertexAttributes().getMask();
34                 if ((attributes & Usage.BoneWeight) == Usage.BoneWeight) {
35                         final int n = renderable.mesh.getVertexAttributes().size();
36                         for (int i = 0; i < n; i++) {
37                                 final VertexAttribute attr = renderable.mesh.getVertexAttributes().get(i);
38                                 if (attr.usage == Usage.BoneWeight)
39                                         prefix += "#define boneWeight"+attr.unit+"Flag\n";
40                         }
41                 }
42                 // FIXME Add transparent texture support
43 //              if ((mask & BlendingAttribute.Type) == BlendingAttribute.Type)
44 //                      prefix += "#define "+BlendingAttribute.Alias+"Flag\n";
45 //              if ((mask & TextureAttribute.Diffuse) == TextureAttribute.Diffuse)
46 //                      prefix += "#define "+TextureAttribute.DiffuseAlias+"Flag\n";
47                 if (numBones > 0)
48                         prefix += "#define numBones "+numBones+"\n";
49                 if (!depthBufferOnly)
50                         prefix += "#define PackedDepthFlag\n";
51                 return prefix;
52         }
53         
54         public final int numBones;
55         public final int weights;
56
57         public DepthShader(final Renderable renderable, int numBones, boolean depthBufferOnly) {
58                 this(getDefaultVertexShader(), getDefaultFragmentShader(), renderable, numBones, depthBufferOnly);
59         }
60         
61         public DepthShader(final String vertexShader, final String fragmentShader, final Renderable renderable, int numBones, boolean depthBufferOnly) {
62                 this(createPrefix(renderable, numBones, depthBufferOnly), vertexShader, fragmentShader, renderable, numBones);
63         }
64         
65         public DepthShader(final String prefix, final String vertexShader, final String fragmentShader, final Renderable renderable, int numBones) {
66                 this(new ShaderProgram(prefix + vertexShader, prefix + fragmentShader), renderable, numBones);
67         }
68         
69         public DepthShader(final ShaderProgram shaderProgram, final Renderable renderable, int numBones) {
70                 super(shaderProgram, renderable, false, false, false, false, 0, 0, 0, numBones);
71                 this.numBones = numBones;
72                 int w = 0;
73                 final int n = renderable.mesh.getVertexAttributes().size();
74                 for (int i = 0; i < n; i++) {
75                         final VertexAttribute attr = renderable.mesh.getVertexAttributes().get(i);
76                         if (attr.usage == Usage.BoneWeight)
77                                 w |= (1 << attr.unit);
78                 }
79                 weights = w;
80         }
81         
82         private int originalCullFace;   
83         @Override
84         public void begin (Camera camera, RenderContext context) {
85                 originalCullFace = DefaultShader.defaultCullFace;
86                 DefaultShader.defaultCullFace = GL10.GL_FRONT; //0; //GL10.GL_BACK; //GL10.GL_FRONT;
87                 super.begin(camera, context);
88                 //Gdx.gl20.glEnable(GL20.GL_POLYGON_OFFSET_FILL);
89                 //Gdx.gl20.glPolygonOffset(2.f, 100.f);
90         }
91         
92         @Override
93         public void end () {
94                 super.end();
95                 DefaultShader.defaultCullFace = originalCullFace;
96                 Gdx.gl20.glDisable(GL20.GL_POLYGON_OFFSET_FILL);
97         }
98         
99         @Override
100         public boolean canRender (Renderable renderable) {
101                 final boolean skinned = ((renderable.mesh.getVertexAttributes().getMask() & Usage.BoneWeight) == Usage.BoneWeight);
102                 if (skinned != (numBones > 0))
103                         return false;
104                 if (!skinned)
105                         return true;
106                 int w = 0;
107                 final int n = renderable.mesh.getVertexAttributes().size();
108                 for (int i = 0; i < n; i++) {
109                         final VertexAttribute attr = renderable.mesh.getVertexAttributes().get(i);
110                         if (attr.usage == Usage.BoneWeight)
111                                 w |= (1 << attr.unit);
112                 }
113                 return w == weights;
114         }
115 }