Created
December 20, 2012 03:56
-
-
Save mattdesl/4342861 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package atmos.tool2d; | |
import com.badlogic.gdx.ApplicationListener; | |
import com.badlogic.gdx.Gdx; | |
import com.badlogic.gdx.backends.lwjgl.LwjglApplication; | |
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; | |
import com.badlogic.gdx.graphics.GL10; | |
import com.badlogic.gdx.graphics.OrthographicCamera; | |
import com.badlogic.gdx.graphics.Texture; | |
import com.badlogic.gdx.graphics.g2d.SpriteBatch; | |
import com.badlogic.gdx.graphics.glutils.ShaderProgram; | |
/** | |
* A port of ShaderLesson4 from lwjgl-basics to LibGDX: | |
* https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson4 | |
* | |
* @author davedes | |
*/ | |
public class ShaderLesson4 implements ApplicationListener { | |
//Minor differences: | |
//LibGDX Position attribute is a vec4 | |
//u_projView is called u_projTrans | |
//we need to set ShaderProgram.pedantic to false | |
//TexCoord attribute requires "0" appended at end to denote GL_TEXTURE0 | |
//ShaderProgram.TEXCOORD_ATTRIBUTE+"0" | |
//It's wise to use LOWP when possible in GL ES | |
//In LibGDX ShaderProgram uses begin() and end() | |
//we can use Texture.bind(int) to bind a texture unit | |
//note that it will leave that unit active -- so we need to reset to zero after! | |
public static void main(String[] args) { | |
LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration(); | |
cfg.title = "Shader Lesson - LibGDX"; | |
cfg.useGL20 = true; | |
cfg.width = 320; | |
cfg.height = 240; | |
cfg.resizable = false; | |
new LwjglApplication(new ShaderLesson4(), cfg); | |
} | |
final String VERT = | |
"attribute vec4 "+ShaderProgram.POSITION_ATTRIBUTE+";\n" + | |
"attribute vec4 "+ShaderProgram.COLOR_ATTRIBUTE+";\n" + | |
"attribute vec2 "+ShaderProgram.TEXCOORD_ATTRIBUTE+"0;\n" + | |
"uniform mat4 u_projTrans;\n" + | |
" \n" + | |
"varying vec4 vColor;\n" + | |
"varying vec2 vTexCoord;\n" + | |
"void main() {\n" + | |
" vColor = "+ShaderProgram.COLOR_ATTRIBUTE+";\n" + | |
" vTexCoord = "+ShaderProgram.TEXCOORD_ATTRIBUTE+"0;\n" + | |
" gl_Position = u_projTrans * " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" + | |
"}"; | |
final String FRAG = | |
//GL ES specific stuff | |
"#ifdef GL_ES\n" // | |
+ "#define LOWP lowp\n" // | |
+ "precision mediump float;\n" // | |
+ "#else\n" // | |
+ "#define LOWP \n" // | |
+ "#endif\n" + // | |
"varying LOWP vec4 vColor;\n" + | |
"varying vec2 vTexCoord;\n" + | |
"uniform sampler2D u_texture;\n" + | |
"uniform sampler2D u_texture1;\n" + | |
"uniform sampler2D u_mask;\n" + | |
"void main(void) {\n" + | |
" //sample the colour from the first texture\n" + | |
" vec4 texColor0 = texture2D(u_texture, vTexCoord);\n" + | |
"\n" + | |
" //sample the colour from the second texture\n" + | |
" vec4 texColor1 = texture2D(u_texture1, vTexCoord);\n" + | |
"\n" + | |
" //get the mask; we will only use the alpha channel\n" + | |
" float mask = texture2D(u_mask, vTexCoord).a;\n" + | |
"\n" + | |
" //interpolate the colours based on the mask\n" + | |
" gl_FragColor = vColor * mix(texColor0, texColor1, mask);\n" + | |
"}"; | |
Texture tex0, tex1, mask; | |
SpriteBatch batch; | |
OrthographicCamera cam; | |
ShaderProgram shader; | |
@Override | |
public void create() { | |
tex0 = new Texture(Gdx.files.internal("data/grass.png")); | |
tex1 = new Texture(Gdx.files.internal("data/dirt.png")); | |
mask = new Texture(Gdx.files.internal("data/mask.png")); | |
//important since we aren't using some uniforms and attributes that SpriteBatch expects | |
ShaderProgram.pedantic = false; | |
//print it out for clarity | |
System.out.println("Vertex Shader:\n-------------\n\n"+VERT); | |
System.out.println("\n"); | |
System.out.println("Fragment Shader:\n-------------\n\n"+FRAG); | |
shader = new ShaderProgram(VERT, FRAG); | |
if (!shader.isCompiled()) { | |
System.err.println(shader.getLog()); | |
System.exit(0); | |
} | |
if (shader.getLog().length()!=0) | |
System.out.println(shader.getLog()); | |
shader.begin(); | |
shader.setUniformi("u_texture1", 1); | |
shader.setUniformi("u_mask", 2); | |
shader.end(); | |
//bind mask to glActiveTexture(GL_TEXTURE2) | |
mask.bind(2); | |
//bind dirt to glActiveTexture(GL_TEXTURE1) | |
tex1.bind(1); | |
//now we need to reset glActiveTexture to zero!!!! since sprite batch does not do this for us | |
Gdx.gl.glActiveTexture(GL10.GL_TEXTURE0); | |
//tex0 will be bound when we call SpriteBatch.draw | |
batch = new SpriteBatch(1000, shader); | |
batch.setShader(shader); | |
cam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); | |
cam.setToOrtho(false); | |
} | |
@Override | |
public void resize(int width, int height) { | |
cam.setToOrtho(false, width, height); | |
batch.setProjectionMatrix(cam.combined); | |
} | |
@Override | |
public void render() { | |
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); | |
batch.begin(); | |
batch.draw(tex0, 0, 0); | |
batch.end(); | |
} | |
@Override | |
public void pause() { | |
} | |
@Override | |
public void resume() { | |
} | |
@Override | |
public void dispose() { | |
batch.dispose(); | |
shader.dispose(); | |
tex0.dispose(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment