package org.andork.jogl.awt;
import static com.jogamp.opengl.GL.GL_ARRAY_BUFFER;
import static com.jogamp.opengl.GL.GL_BLEND;
import static com.jogamp.opengl.GL.GL_DEPTH_TEST;
import static com.jogamp.opengl.GL.GL_FLOAT;
import static com.jogamp.opengl.GL.GL_ONE_MINUS_SRC_ALPHA;
import static com.jogamp.opengl.GL.GL_SRC_ALPHA;
import static com.jogamp.opengl.GL.GL_TEXTURE0;
import static com.jogamp.opengl.GL.GL_TEXTURE_2D;
import static com.jogamp.opengl.GL.GL_TRIANGLES;
import org.andork.jogl.JoglDrawContext;
import org.andork.jogl.JoglResourceManager;
import org.andork.jogl.awt.JoglText.Segment;
import org.andork.jogl.util.JoglUtils;
import org.andork.jogl.util.JoglUtils.LoadedProgram;
import com.jogamp.opengl.GL2ES2;
public class JoglTextBillboardProgram extends JoglTextProgram {
private static final String vertexShaderCode = "uniform mat4 p;" +
"uniform mat4 v;" +
"uniform mat4 m;" +
"uniform vec2 px;" +
"uniform vec3 u_origin;" +
"attribute vec3 a_pos;" +
"attribute vec2 a_texcoord;" +
"varying vec2 v_texcoord;" +
"void main() {" +
" v_texcoord = a_texcoord;" +
" gl_Position = p * v * m * vec4(u_origin, 1.0);" +
" gl_Position.xy += vec2(a_pos.xy * px * gl_Position.w);" +
"}";
private static final String fragmentShaderCode = "uniform sampler2D u_texture;" +
"uniform vec4 u_color;" +
"varying vec2 v_texcoord;" +
"void main() {" +
// " gl_FragColor = vec4(u_color.xyz , u_color.w *
// texture2D(u_texture, v_texcoord).r);" +
" gl_FragColor = vec4(u_color * texture2D(u_texture, v_texcoord));" +
" if (gl_FragColor.a == 0.0) {" +
" discard;" +
" }" +
"}";
private LoadedProgram program;
private int mLoc;
private int vLoc;
private int pLoc;
private int pxLoc;
private int u_originLoc;
private int u_colorLoc;
private int a_posLoc;
private int a_texcoordLoc;
private int u_textureLoc;
public JoglTextBillboardProgram(JoglResourceManager manager) {
super(manager);
}
@Override
protected void doDispose(GL2ES2 gl) {
program.dispose(gl);
program = null;
}
@Override
protected void doInit(GL2ES2 gl) {
program = JoglUtils.loadProgram2(gl, vertexShaderCode, fragmentShaderCode);
mLoc = gl.glGetUniformLocation(program.program, "m");
vLoc = gl.glGetUniformLocation(program.program, "v");
pLoc = gl.glGetUniformLocation(program.program, "p");
pxLoc = gl.glGetUniformLocation(program.program, "px");
u_originLoc = gl.glGetUniformLocation(program.program, "u_origin");
u_colorLoc = gl.glGetUniformLocation(program.program, "u_color");
a_posLoc = gl.glGetAttribLocation(program.program, "a_pos");
a_texcoordLoc = gl.glGetAttribLocation(program.program, "a_texcoord");
u_textureLoc = gl.glGetUniformLocation(program.program, "u_texture");
}
@Override
public void draw(JoglText text, JoglDrawContext context, GL2ES2 gl, float[] m, float[] n) {
gl.glUseProgram(program.program);
gl.glEnable(GL_DEPTH_TEST);
gl.glEnable(GL_BLEND);
gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl.glUniformMatrix4fv(mLoc, 1, false, m, 0);
gl.glUniformMatrix4fv(vLoc, 1, false, context.viewXform(), 0);
gl.glUniformMatrix4fv(pLoc, 1, false, context.projXform(), 0);
gl.glUniform2fv(pxLoc, 1, context.pixelScale(), 0);
gl.glUniform3fv(u_originLoc, 1, text.origin, 0);
gl.glUniform1i(u_textureLoc, 0);
gl.glEnableVertexAttribArray(a_posLoc);
gl.glEnableVertexAttribArray(a_texcoordLoc);
gl.glActiveTexture(GL_TEXTURE0);
for (Segment segment : text.segments) {
gl.glBindBuffer(GL_ARRAY_BUFFER, segment.buffer());
gl.glBindTexture(GL_TEXTURE_2D, segment.page.getTexture());
gl.glUniform4fv(u_colorLoc, 1, segment.color, 0);
gl.glVertexAttribPointer(a_posLoc, 3, GL_FLOAT, false, 20, 0);
gl.glVertexAttribPointer(a_texcoordLoc, 2, GL_FLOAT, false, 20, 12);
gl.glDrawArrays(GL_TRIANGLES, 0, segment.count);
}
gl.glBindBuffer(GL_ARRAY_BUFFER, 0);
gl.glBindTexture(GL_TEXTURE_2D, 0);
gl.glDisable(GL_BLEND);
gl.glDisable(GL_DEPTH_TEST);
gl.glUseProgram(0);
}
}