Subversion Repositories AndroidProjects

Rev

Rev 369 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
369 chris 1
package com.gebauz.Bauzoid.graphics.shader;
2
 
3
import java.nio.IntBuffer;
4
import java.util.ArrayList;
5
import java.util.List;
6
 
7
import com.badlogic.gdx.Gdx;
8
import com.badlogic.gdx.graphics.GL20;
9
import com.badlogic.gdx.utils.BufferUtils;
10
import com.gebauz.Bauzoid.app.Consts;
11
import com.gebauz.Bauzoid.graphics.Graphics;
12
import com.gebauz.Bauzoid.graphics.GraphicsObject;
13
import com.gebauz.Bauzoid.graphics.model.VertexAttribute;
537 chris 14
import com.gebauz.Bauzoid.math.Matrix4;
369 chris 15
 
16
public class ShaderProgram extends GraphicsObject
17
{
18
        private static List<ShaderProgram> mManagedShaders = new ArrayList<ShaderProgram>();
19
 
20
        public static String ATTRIB_POSITION = "aPosition";
21
        public static String ATTRIB_COLOR = "aColor";
22
        public static String ATTRIB_NORMAL= "aNormal";
23
        public static String ATTRIB_TEXCOORD0 = "aTexCoord0";
24
        public static String ATTRIB_TEXCOORD1 = "aTexCoord1";
25
        public static String ATTRIB_BLENDINDICES = "aBlendIndex";
26
        public static String ATTRIB_BLENDWEIGHTS = "aBlendWeight";
27
 
28
        public class Shader
29
        {
30
                private int mShaderID = 0;
31
                private int mShaderType;
32
                private String mShaderCode;
33
 
34
                public Shader(int shaderType)
35
                {
36
                        mShaderType = shaderType;
37
                }
38
 
39
                public void loadShader(String shaderCode)
40
                {
41
                        ShaderUtil.log(Consts.LOG_TAG, "Loading " + (mShaderType == GL20.GL_VERTEX_SHADER ? "Vertex" : "Fragment") + " Shader");
42
 
43
                        mShaderCode = shaderCode;
44
 
45
                        if (mShaderID != 0)
46
                                unloadShader();
47
 
48
                        mShaderID = Gdx.gl20.glCreateShader(mShaderType);
49
 
50
                        Gdx.gl20.glShaderSource(mShaderID, mShaderCode);
51
                        Gdx.gl20.glCompileShader(mShaderID);
52
 
53
                        Gdx.gl20.glGetShaderiv(mShaderID, GL20.GL_COMPILE_STATUS, COMPILESTATUS);
54
 
55
                        if (COMPILESTATUS.get(0) != GL20.GL_TRUE)
56
                        {
57
                                ShaderUtil.log(Consts.LOG_TAG, Gdx.gl20.glGetShaderInfoLog(mShaderID));
58
                                return;
59
                        }
60
 
61
                        ShaderUtil.log(Consts.LOG_TAG, "Shader loading successful!");
62
                }
63
 
64
                public void reloadShader()
65
                {                      
66
                        mShaderID = 0;
67
                        loadShader(mShaderCode);
68
                }
69
 
70
                public void unloadShader()
71
                {
72
                        Gdx.gl20.glDeleteShader(mShaderID);
73
                        mShaderID = 0;
74
                        mShaderCode = "";
75
                }
76
        };
77
 
78
        private static final IntBuffer COMPILESTATUS = BufferUtils.newIntBuffer(1);
79
 
80
        private Shader mVertexShader = null;
81
        private Shader mFragmentShader = null;
82
        private int mProgramID = 0;
83
 
84
        // Standard uniforms
85
        private ShaderUniform mModelViewProjection = null;
537 chris 86
        private Matrix4 mModelViewProjectionMatrix = new Matrix4();
369 chris 87
 
88
        public ShaderProgram(Graphics graphics)
89
        {
90
                super(graphics);
91
 
92
                mVertexShader = new Shader(GL20.GL_VERTEX_SHADER);
93
                mFragmentShader = new Shader(GL20.GL_FRAGMENT_SHADER);
94
        }
95
 
96
        public void loadShaderProgram(String vertexShaderCode, String fragmentShaderCode)
97
        {
98
                mVertexShader.loadShader(vertexShaderCode);
99
                mFragmentShader.loadShader(fragmentShaderCode);
100
 
101
                mProgramID = Gdx.gl20.glCreateProgram();
102
 
103
                Gdx.gl20.glAttachShader(mProgramID, mVertexShader.mShaderID);
104
                Gdx.gl20.glAttachShader(mProgramID, mFragmentShader.mShaderID);
105
 
106
                // default attrib locations
107
                /*GLES20.glBindAttribLocation(mProgramID, SimpleGeometry.COORD_ATTRIB_INDEX, "vPosition");
108
                GLES20.glBindAttribLocation(mProgramID, SimpleGeometry.COLOR_ATTRIB_INDEX, "vColor");
109
                GLES20.glBindAttribLocation(mProgramID, SimpleGeometry.NORMAL_ATTRIB_INDEX, "vNormal");
110
                GLES20.glBindAttribLocation(mProgramID, SimpleGeometry.TEX_COORD_ATTRIB_INDEX, "vTexCoord");*/
111
 
112
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.POSITION, ATTRIB_POSITION);
113
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.COLOR, ATTRIB_COLOR);
114
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.NORMAL, ATTRIB_NORMAL);
115
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.TEXCOORD0, ATTRIB_TEXCOORD0);
116
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.TEXCOORD1, ATTRIB_TEXCOORD1);
117
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.BLENDINDICES, ATTRIB_BLENDINDICES);
118
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.BLENDWEIGHTS, ATTRIB_BLENDWEIGHTS);
119
 
120
                Gdx.gl20.glLinkProgram(mProgramID);
121
 
122
                // obtain uniforms for standard names
123
                mModelViewProjection = getUniform("uMVPMatrix");
124
 
125
                mManagedShaders.add(this);
126
        }
127
 
128
        public void reloadShaderProgram()
129
        {
130
                mVertexShader.reloadShader();
131
                mFragmentShader.reloadShader();
132
 
133
                mProgramID = Gdx.gl20.glCreateProgram();
134
 
135
                Gdx.gl20.glAttachShader(mProgramID, mVertexShader.mShaderID);
136
                Gdx.gl20.glAttachShader(mProgramID, mFragmentShader.mShaderID);
137
 
138
                // default attrib locations
139
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.POSITION, ATTRIB_POSITION);
140
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.COLOR, ATTRIB_COLOR);
141
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.NORMAL, ATTRIB_NORMAL);
142
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.TEXCOORD0, ATTRIB_TEXCOORD0);
143
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.TEXCOORD1, ATTRIB_TEXCOORD1);
144
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.BLENDINDICES, ATTRIB_BLENDINDICES);
145
                Gdx.gl20.glBindAttribLocation(mProgramID, VertexAttribute.BLENDWEIGHTS, ATTRIB_BLENDWEIGHTS);
146
 
147
                Gdx.gl20.glLinkProgram(mProgramID);
148
        }
149
 
150
        public void dispose()
151
        {
152
                mManagedShaders.remove(this);
153
 
154
                Gdx.gl20.glDeleteProgram(mProgramID);  
155
 
156
                mVertexShader.unloadShader();
157
                mFragmentShader.unloadShader();
158
 
159
                mProgramID = 0;
160
        }
161
 
162
        public void activate()
163
        {
164
                // TODO: state management!
165
                Gdx.gl20.glUseProgram(mProgramID);
166
 
167
                // apply standard uniforms
168
                if (mModelViewProjection != null)
537 chris 169
                {
170
                        getRenderStates().getModelViewProjection(mModelViewProjectionMatrix);
171
                        mModelViewProjection.set(mModelViewProjectionMatrix);
172
                }
369 chris 173
        }
174
 
175
        public void deactivate()
176
        {
177
                Gdx.gl20.glUseProgram(0);
178
        }
179
 
180
        public ShaderUniform getUniform(String uniformName)
181
        {
182
                if (mProgramID == 0)
183
                        return null;
184
 
185
                int handle = getUniformHandle(uniformName);
186
 
187
                if (handle == -1)
188
                {
189
                        //Log.e(Consts.LOG_TAG, "Error getting uniform '" + uniformName + "'!");
190
                        return null;
191
                }
192
 
193
                return new ShaderUniform(this, uniformName);
194
        }
195
 
196
        public int getUniformHandle(String uniformName)
197
        {
198
                return Gdx.gl20.glGetUniformLocation(mProgramID, uniformName);
199
        }
200
 
201
        public Shader getVertexShader()
202
        {
203
                return mVertexShader;
204
        }
205
 
206
        public Shader getFragmentShader()
207
        {
208
                return mFragmentShader;
209
        }
210
 
211
        public static void reloadManagedShaders()
212
        {
213
                for (int i = 0; i < mManagedShaders.size(); i++)
214
                {
215
                        ShaderProgram shader = mManagedShaders.get(i);
216
                        shader.reloadShaderProgram();
217
                        ShaderUtil.log(Consts.LOG_TAG, "ShaderProgram reloaded!");
218
                }
219
        }
220
}
221
 
222