Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

starting to add shader lessons

  • Loading branch information...
commit c149cc19a36823d547d933aefd58da2729423c25 1 parent b60ccfc
@mattdesl authored
View
1  .classpath
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/jinput.jar"/>
<classpathentry kind="lib" path="lib/lwjgl_util.jar"/>
View
61 src/mdesl/graphics/Pixmap.java
@@ -0,0 +1,61 @@
+package mdesl.graphics;
+
+import java.nio.ByteBuffer;
+
+import org.lwjgl.BufferUtils;
+
+/**
+ * A simple wrapper around an array of RGBA pixel colors, which can then be passed to a GL texture.
+ * @author davedes
+ */
+public class Pixmap {
+
+ //if we were targeting Android, we might prefer to use byte[] arrays for performance
+ /** The RGBA bytes backing this pixmap. */
+ protected ByteBuffer pixels;
+
+ public static final int BYTES_PER_PIXEL = 4;
+
+ public Pixmap(int width, int height) {
+ pixels = BufferUtils.createByteBuffer(width * height * BYTES_PER_PIXEL);
+ }
+
+ /**
+ * Sets the pixel data to the given array, which should be less
+ * than the size of length(), then flips the buffer.
+ *
+ * @param rgbaData the new pixel data
+ * @return this object, for chaining
+ */
+ public Pixmap set(byte[] rgbaData) {
+ pixels.clear();
+ pixels.put(rgbaData);
+ pixels.flip();
+ return this;
+ }
+
+ /**
+ * Clears the pixel array to transparent black.
+ * @return this object, for chaining
+ */
+ public Pixmap clear() {
+ return clear(0, 0, 0, 0);
+ }
+
+ /**
+ * Clears the pixel array to the specified color, then flips the buffer.
+ *
+ * @param r the red byte
+ * @param g the green byte
+ * @param b the blue byte
+ * @param a the alpha byte
+ * @return this object, for chaining
+ */
+ public Pixmap clear(int r, int g, int b, int a) {
+ pixels.clear();
+ for (int i=0; i<pixels.capacity(); i++)
+ pixels.put((byte)r).put((byte)g).put((byte)b).put((byte)a);
+ pixels.flip();
+ return this;
+ }
+}
View
11 src/mdesl/graphics/SpriteBatch.java
@@ -168,7 +168,7 @@ public void updateUniforms() {
viewMatrix, projViewMatrix);
// bind the program before sending uniforms
- program.begin();
+ program.use();
// Store the the multiplied matrix in the "projViewMatrix"-uniform:
int projView = program.getUniformLocation(U_PROJ_VIEW);
@@ -179,8 +179,6 @@ public void updateUniforms() {
int tex0 = program.getUniformLocation(U_TEXTURE);
if (tex0 != -1)
glUniform1i(tex0, 0);
-
- program.end();
}
/** An advanced call that allows you to change the shader without uploading
@@ -192,13 +190,11 @@ public void updateUniforms() {
public void setShader(ShaderProgram program, boolean updateUniforms) {
if (drawing) {
flush();
- this.program.end();
+ this.program.use();
}
this.program = program;
if (updateUniforms)
updateUniforms();
- if (drawing)
- program.begin();
}
/** Changes the shader and updates it with the current texture and projView
@@ -213,7 +209,7 @@ public void begin() {
if (drawing)
throw new IllegalStateException("must not be drawing before calling begin()");
drawing = true;
- program.begin();
+ program.use();
idx = 0;
renderCalls = 0;
texture = null;
@@ -224,7 +220,6 @@ public void end() {
throw new IllegalStateException("must be drawing before calling end()");
drawing = false;
flush();
- program.end();
}
public void flush() {
View
28 src/mdesl/graphics/glutils/ShaderProgram.java
@@ -96,6 +96,9 @@
* @author davedes */
public class ShaderProgram {
+ private static FloatBuffer fbuf16;
+ private static IntBuffer ibuf4;
+
// a simple struct for attrib data; ideally we should find the
// component count to utilize our VertexAttrib class
protected static class Attrib {
@@ -149,11 +152,6 @@ public static boolean isStrictMode() {
return strict;
}
- /** Unbinds all shader programs. */
- public static void unbind() {
- glUseProgram(0);
- }
-
/** The OpenGL handle for this shader program object. */
protected int program;
/** The log for this program. */
@@ -172,8 +170,6 @@ public static void unbind() {
/** The OpenGL handle for this program's fragment shader object. */
protected int frag;
- private FloatBuffer fbuf16;
- private IntBuffer ibuf4;
/** Creates a new shader program with the given vertex and fragment shader
* source code. The given source code is compiled, then the shaders attached
@@ -353,20 +349,19 @@ public String getLog() {
* the active program.
*
* @throw IllegalStateException if this program is invalid */
- public void begin() {
+ public void use() {
if (!valid())
throw new IllegalStateException("trying to enable a program that is not valid");
glUseProgram(program);
}
- /** Disables shaders (unbind), then detaches and releases the shaders
+ /** Detaches and releases the shaders
* associated with this program. This can be called after linking a program
* in order to free up memory (as the shaders are no longer needed),
* however, since it is not a commonly used feature and thus not well tested
* on all drivers, it should be used with caution. Shaders shouldn't be used
* after being released. */
public void releaseShaders() {
- end();
if (vert != 0) {
glDetachShader(getID(), vert);
glDeleteShader(vert);
@@ -379,27 +374,18 @@ public void releaseShaders() {
}
}
- /** If this program has not yet been released, this will disable shaders
- * (unbind), then releases this program and its shaders. To only release the
+ /** If this program has not yet been released, this will releases
+ * this program and its shaders. To only release the
* shaders (not the program itself), call releaseShaders(). Programs will be
* considered "invalid" after being released, and should no longer be used. */
public void release() {
if (program != 0) {
- unbind();
releaseShaders();
glDeleteProgram(program);
program = 0;
}
}
- /** Unbinds all shaders; this is the equivalent of ShaderProgram.unbindAll(),
- * and only included for consistency with bind() and the rest of the API
- * (i.e. FBO). Users do not need to unbind one shader before binding a new
- * one. */
- public void end() {
- ShaderProgram.unbind();
- }
-
/** Returns the OpenGL handle for this program's vertex shader.
*
* @return the vertex ID */
View
0  src/mdesl/test/Game.java → test/mdesl/test/Game.java
File renamed without changes
View
324 test/mdesl/test/ShaderTest.java
@@ -0,0 +1,324 @@
+/**
+ * Copyright (c) 2012, Matt DesLauriers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary
+ * form must reproduce the above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * * Neither the name of the Matt DesLauriers nor the names
+ * of his contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package mdesl.test;
+
+import static org.lwjgl.opengl.GL11.GL_BLEND;
+import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
+import static org.lwjgl.opengl.GL11.GL_DEPTH;
+import static org.lwjgl.opengl.GL11.GL_FALSE;
+import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
+import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
+import static org.lwjgl.opengl.GL11.GL_PROJECTION;
+import static org.lwjgl.opengl.GL11.GL_QUADS;
+import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
+import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
+import static org.lwjgl.opengl.GL11.glBegin;
+import static org.lwjgl.opengl.GL11.glBlendFunc;
+import static org.lwjgl.opengl.GL11.glClear;
+import static org.lwjgl.opengl.GL11.glClearColor;
+import static org.lwjgl.opengl.GL11.glColor4f;
+import static org.lwjgl.opengl.GL11.glDisable;
+import static org.lwjgl.opengl.GL11.glEnable;
+import static org.lwjgl.opengl.GL11.glEnd;
+import static org.lwjgl.opengl.GL11.glLoadIdentity;
+import static org.lwjgl.opengl.GL11.glMatrixMode;
+import static org.lwjgl.opengl.GL11.glOrtho;
+import static org.lwjgl.opengl.GL11.glTexCoord2f;
+import static org.lwjgl.opengl.GL11.glVertex2f;
+import static org.lwjgl.opengl.GL11.glViewport;
+import static org.lwjgl.opengl.GL20.GL_COMPILE_STATUS;
+import static org.lwjgl.opengl.GL20.GL_FRAGMENT_SHADER;
+import static org.lwjgl.opengl.GL20.GL_INFO_LOG_LENGTH;
+import static org.lwjgl.opengl.GL20.GL_LINK_STATUS;
+import static org.lwjgl.opengl.GL20.GL_VERTEX_SHADER;
+import static org.lwjgl.opengl.GL20.glAttachShader;
+import static org.lwjgl.opengl.GL20.glBindAttribLocation;
+import static org.lwjgl.opengl.GL20.glCompileShader;
+import static org.lwjgl.opengl.GL20.glCreateProgram;
+import static org.lwjgl.opengl.GL20.glCreateShader;
+import static org.lwjgl.opengl.GL20.glDeleteProgram;
+import static org.lwjgl.opengl.GL20.glDeleteShader;
+import static org.lwjgl.opengl.GL20.glDetachShader;
+import static org.lwjgl.opengl.GL20.glGetProgramInfoLog;
+import static org.lwjgl.opengl.GL20.glGetProgrami;
+import static org.lwjgl.opengl.GL20.glGetShaderInfoLog;
+import static org.lwjgl.opengl.GL20.glGetShaderi;
+import static org.lwjgl.opengl.GL20.glGetUniformLocation;
+import static org.lwjgl.opengl.GL20.glLinkProgram;
+import static org.lwjgl.opengl.GL20.glShaderSource;
+import static org.lwjgl.opengl.GL20.glUniform1i;
+import static org.lwjgl.opengl.GL20.glUniformMatrix4;
+import static org.lwjgl.opengl.GL20.glUseProgram;
+
+import java.nio.FloatBuffer;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import mdesl.graphics.Texture;
+
+import org.lwjgl.BufferUtils;
+import org.lwjgl.LWJGLException;
+import org.lwjgl.opengl.Display;
+import org.lwjgl.opengl.DisplayMode;
+import org.lwjgl.util.vector.Matrix4f;
+
+
+public class ShaderTest {
+
+ public static void main(String[] args) throws LWJGLException {
+ final int WIDTH = 800, HEIGHT = 600;
+ Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
+ Display.create();
+
+//
+// Texture tex = null, tex2 = null;
+// try {
+// //TODO: put this into a texture atlas!
+// tex = new Texture(ShaderTest.class.getClassLoader().getResource("res/tiles.png"), Texture.NEAREST, Texture.CLAMP_TO_EDGE);
+// tex2 = new Texture(ShaderTest.class.getClassLoader().getResource("res/grass.png"));
+// } catch (IOException e) {
+// e.printStackTrace();
+// System.exit(0);
+// }
+
+ glViewport(0, 0, WIDTH, HEIGHT);
+
+ //ugly deprecated OpenGL!!! use programmable pipeline instead
+
+ //setup blending
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ //enable textures
+ glEnable(GL_TEXTURE_2D);
+
+ glClearColor(1f, 1f, 1f, 1f);
+ glDisable(GL_DEPTH);
+
+
+ while (!Display.isCloseRequested()) {
+ //clear the screen
+ glClear(GL_COLOR_BUFFER_BIT);
+
+
+
+ Display.update();
+ Display.sync(60);
+ }
+ Display.destroy();
+ }
+
+ public static void debugTexture(Texture tex, float x, float y, float width, float height) {
+ //in a typical OpenGL game, this would be done during initialization rather than within the game loop
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, Display.getWidth(), Display.getHeight(), 0, 1, -1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ tex.bind();
+
+ float srcX = 64;
+ float srcY = 0;
+ float srcWidth = 64;
+ float srcHeight = 64;
+
+ float u = srcX / tex.width;
+ float v = srcY / tex.height;
+ float u2 = (srcX + srcWidth) / tex.width;
+ float v2 = (srcY + srcHeight) / tex.height;
+
+ //immediate mode is deprecated -- we are only using it for quick debugging
+ glColor4f(1f, 1f, 1f, 1f);
+ glBegin(GL_QUADS);
+ glTexCoord2f(u, v);
+ glVertex2f(x, y);
+ glTexCoord2f(u, v2);
+ glVertex2f(x, y + height);
+ glTexCoord2f(u2, v2);
+ glVertex2f(x + width, y + height);
+ glTexCoord2f(u2, v);
+ glVertex2f(x + width, y);
+ glEnd();
+ }
+
+ public static class ShaderProgram {
+
+ protected static FloatBuffer buf16Pool;
+
+ /**
+ * Makes the "default shader" (0) the active program. In GL 3.1+ core profile,
+ * you may run into glErrors if you try rendering with the default shader.
+ */
+ public static void unbind() {
+ glUseProgram(0);
+ }
+
+ public final int program;
+ public final int vertex;
+ public final int fragment;
+ protected String log;
+
+ public ShaderProgram(String vertexSource, String fragmentSource) throws LWJGLException {
+ this(vertexSource, fragmentSource, null);
+ }
+
+ /**
+ * Creates a new shader from vertex and fragment source, and with the given
+ * map of <Integer, String> attrib locations
+ * @param vertexShader the vertex shader source string
+ * @param fragmentShader the fragment shader source string
+ * @param attributes a map of attrib locations for GLSL 120
+ * @throws LWJGLException if the program could not be compiled and linked
+ */
+ public ShaderProgram(String vertexShader, String fragmentShader, Map<Integer, String> attributes) throws LWJGLException {
+ //compile the String source
+ vertex = compileShader(vertexShader, GL_VERTEX_SHADER);
+ fragment = compileShader(fragmentShader, GL_FRAGMENT_SHADER);
+
+ //create the program
+ program = glCreateProgram();
+
+ //attach the shaders
+ glAttachShader(program, vertex);
+ glAttachShader(program, fragment);
+
+ //bind the attrib locations for GLSL 120
+ if (attributes != null)
+ for (Entry<Integer, String> e : attributes.entrySet())
+ glBindAttribLocation(program, e.getKey(), e.getValue());
+
+ //link our program
+ glLinkProgram(program);
+
+ //grab our info log
+ String infoLog = glGetProgramInfoLog(program, glGetProgrami(program, GL_INFO_LOG_LENGTH));
+
+ //if some log exists, append it
+ if (infoLog!=null && infoLog.trim().length()!=0)
+ log += infoLog;
+
+ //if the link failed, throw some sort of exception
+ if (glGetProgrami(program, GL_LINK_STATUS) == GL_FALSE)
+ throw new LWJGLException(
+ "Failure in linking program. Error log:\n" + infoLog);
+
+ //detach and delete the shaders which are no longer needed
+ glDetachShader(program, vertex);
+ glDetachShader(program, fragment);
+ glDeleteShader(vertex);
+ glDeleteShader(fragment);
+ }
+
+ /** Compile the shader source as the given type and return the shader object ID. */
+ protected int compileShader(String source, int type) throws LWJGLException {
+ //create a shader object
+ int shader = glCreateShader(type);
+ //pass the source string
+ glShaderSource(shader, source);
+ //compile the source
+ glCompileShader(shader);
+
+ //if info/warnings are found, append it to our shader log
+ String infoLog = glGetShaderInfoLog(shader,
+ glGetShaderi(shader, GL_INFO_LOG_LENGTH));
+ if (infoLog!=null && infoLog.trim().length()!=0)
+ log += getName(type) +": "+infoLog + "\n";
+
+ //if the compiling was unsuccessful, throw an exception
+ if (glGetShaderi(shader, GL_COMPILE_STATUS) == GL_FALSE)
+ throw new LWJGLException("Failure in compiling " + getName(type)
+ + ". Error log:\n" + infoLog);
+
+ return shader;
+ }
+
+ protected String getName(int shaderType) {
+ if (shaderType == GL_VERTEX_SHADER)
+ return "GL_VERTEX_SHADER";
+ if (shaderType == GL_FRAGMENT_SHADER)
+ return "GL_FRAGMENT_SHADER";
+ else
+ return "shader";
+ }
+
+ /**
+ * Make this shader the active program.
+ */
+ public void use() {
+ glUseProgram(program);
+ }
+
+ /**
+ * Destroy this shader program.
+ */
+ public void destroy() {
+ glDeleteProgram(program);
+ }
+
+ /**
+ * Gets the location of the specified uniform name.
+ * @param str the name of the uniform
+ * @return the location of the uniform in this program
+ */
+ public int getUniformLocation(String str) {
+ return glGetUniformLocation(program, str);
+ }
+
+ /* ------ UNIFORM SETTERS/GETTERS ------ */
+
+ /**
+ * Sets the uniform data at the specified location (the uniform type may be int, bool or sampler2D).
+ * @param loc the location of the int/bool/sampler2D uniform
+ * @param i the value to set
+ */
+ public void setUniformi(int loc, int i) {
+ if (loc==-1) return;
+ glUniform1i(loc, i);
+ }
+
+ /**
+ * Sends a 4x4 matrix to the shader program.
+ * @param loc the location of the mat4 uniform
+ * @param transposed whether the matrix should be transposed
+ * @param mat the matrix to send
+ */
+ public void setUniformMatrix(int loc, boolean transposed, Matrix4f mat) {
+ if (loc==-1) return;
+ if (buf16Pool == null)
+ buf16Pool = BufferUtils.createFloatBuffer(16);
+ buf16Pool.clear();
+ mat.store(buf16Pool);
+ buf16Pool.flip();
+ glUniformMatrix4(loc, transposed, buf16Pool);
+ }
+ }
+}
View
0  src/mdesl/test/SimpleGame.java → test/mdesl/test/SimpleGame.java
File renamed without changes
View
236 test/mdesl/test/TexTest.java
@@ -0,0 +1,236 @@
+/**
+ * Copyright (c) 2012, Matt DesLauriers All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary
+ * form must reproduce the above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * * Neither the name of the Matt DesLauriers nor the names
+ * of his contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package mdesl.test;
+
+import static org.lwjgl.opengl.GL11.GL_BLEND;
+import static org.lwjgl.opengl.GL11.GL_CLAMP;
+import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
+import static org.lwjgl.opengl.GL11.GL_DEPTH;
+import static org.lwjgl.opengl.GL11.GL_LINEAR;
+import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
+import static org.lwjgl.opengl.GL11.GL_NEAREST;
+import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
+import static org.lwjgl.opengl.GL11.GL_PACK_ALIGNMENT;
+import static org.lwjgl.opengl.GL11.GL_PROJECTION;
+import static org.lwjgl.opengl.GL11.GL_QUADS;
+import static org.lwjgl.opengl.GL11.GL_REPEAT;
+import static org.lwjgl.opengl.GL11.GL_RGBA;
+import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
+import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
+import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
+import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
+import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
+import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
+import static org.lwjgl.opengl.GL11.GL_UNPACK_ALIGNMENT;
+import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
+import static org.lwjgl.opengl.GL11.glBegin;
+import static org.lwjgl.opengl.GL11.glBindTexture;
+import static org.lwjgl.opengl.GL11.glBlendFunc;
+import static org.lwjgl.opengl.GL11.glClear;
+import static org.lwjgl.opengl.GL11.glClearColor;
+import static org.lwjgl.opengl.GL11.glColor4f;
+import static org.lwjgl.opengl.GL11.glDisable;
+import static org.lwjgl.opengl.GL11.glEnable;
+import static org.lwjgl.opengl.GL11.glEnd;
+import static org.lwjgl.opengl.GL11.glGenTextures;
+import static org.lwjgl.opengl.GL11.glLoadIdentity;
+import static org.lwjgl.opengl.GL11.glMatrixMode;
+import static org.lwjgl.opengl.GL11.glOrtho;
+import static org.lwjgl.opengl.GL11.glPixelStorei;
+import static org.lwjgl.opengl.GL11.glTexCoord2f;
+import static org.lwjgl.opengl.GL11.glTexImage2D;
+import static org.lwjgl.opengl.GL11.glTexParameteri;
+import static org.lwjgl.opengl.GL11.glVertex2f;
+import static org.lwjgl.opengl.GL11.glViewport;
+import static org.lwjgl.opengl.GL12.GL_CLAMP_TO_EDGE;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.ByteBuffer;
+
+import org.lwjgl.BufferUtils;
+import org.lwjgl.LWJGLException;
+import org.lwjgl.opengl.Display;
+import org.lwjgl.opengl.DisplayMode;
+import org.lwjgl.opengl.GLContext;
+
+import de.matthiasmann.twl.utils.PNGDecoder;
+
+
+public class TexTest {
+
+ public static void main(String[] args) throws LWJGLException {
+ final int WIDTH = 800, HEIGHT = 600;
+ Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
+ Display.create();
+
+
+ Texture tex = null, tex2 = null;
+ try {
+ //TODO: put this into a texture atlas!
+ tex = new Texture(TexTest.class.getClassLoader().getResource("res/tiles.png"), Texture.NEAREST, Texture.CLAMP_TO_EDGE);
+ tex2 = new Texture(TexTest.class.getClassLoader().getResource("res/grass.png"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.exit(0);
+ }
+
+ glViewport(0, 0, WIDTH, HEIGHT);
+
+ //ugly deprecated OpenGL!!! use programmable pipeline instead
+
+ //setup blending
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ //enable textures
+ glEnable(GL_TEXTURE_2D);
+
+ glClearColor(1f, 1f, 1f, 1f);
+ glDisable(GL_DEPTH);
+
+
+ while (!Display.isCloseRequested()) {
+ //clear the screen
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ debugTexture(tex, 50, 50, 64, 64);
+// drawSprite(tex2, 150, 150, 1f);
+
+
+ Display.update();
+ Display.sync(60);
+ }
+ Display.destroy();
+ }
+
+ public static void debugTexture(Texture tex, float x, float y, float width, float height) {
+ //in a typical OpenGL game, this would be done during initialization rather than within the game loop
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, Display.getWidth(), Display.getHeight(), 0, 1, -1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ tex.bind();
+
+ float srcX = 64;
+ float srcY = 0;
+ float srcWidth = 64;
+ float srcHeight = 64;
+
+ float u = srcX / tex.width;
+ float v = srcY / tex.height;
+ float u2 = (srcX + srcWidth) / tex.width;
+ float v2 = (srcY + srcHeight) / tex.height;
+
+ //immediate mode is deprecated -- we are only using it for quick debugging
+ glColor4f(1f, 1f, 1f, 1f);
+ glBegin(GL_QUADS);
+ glTexCoord2f(u, v);
+ glVertex2f(x, y);
+ glTexCoord2f(u, v2);
+ glVertex2f(x, y + height);
+ glTexCoord2f(u2, v2);
+ glVertex2f(x + width, y + height);
+ glTexCoord2f(u2, v);
+ glVertex2f(x + width, y);
+ glEnd();
+ }
+
+ //put this in its own file rather than having it as an inner class
+ public static class Texture {
+ static int bound = 0;
+
+ public final int target = GL_TEXTURE_2D;
+ public final int id;
+ public final int width;
+ public final int height;
+
+ public static final int LINEAR = GL_LINEAR;
+ public static final int NEAREST = GL_NEAREST;
+
+ public static final int CLAMP = GL_CLAMP;
+ public static final int CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE;
+ public static final int REPEAT = GL_REPEAT;
+
+ public static void clearLastBind() {
+ bound = 0;
+ }
+
+ public Texture(URL pngRef) throws IOException {
+ this(pngRef, GL_NEAREST);
+ }
+
+ public Texture(URL pngRef, int filter) throws IOException {
+ this(pngRef, filter, GL_CLAMP_TO_EDGE);
+ }
+
+ public Texture(URL pngRef, int filter, int wrap) throws IOException {
+ InputStream input = null;
+ try {
+ input = pngRef.openStream();
+ PNGDecoder dec = new PNGDecoder(input);
+
+ width = dec.getWidth();
+ height = dec.getHeight();
+ ByteBuffer buf = BufferUtils.createByteBuffer(4 * width * height);
+ dec.decode(buf, width * 4, PNGDecoder.Format.RGBA);
+ buf.flip();
+
+ glEnable(target);
+ id = glGenTextures();
+
+ bind();
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);
+
+ glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
+ } finally {
+ if (input != null) {
+ try { input.close(); } catch (IOException e) { }
+ }
+ }
+ }
+
+ public void bind() {
+ if (id != bound)
+ glBindTexture(target, id);
+ }
+ }
+}
View
6 src/mdesl/test/TextureBlendTest.java → test/mdesl/test/TextureBlendTest.java
@@ -57,13 +57,11 @@ public void create() throws LWJGLException {
ShaderProgram shader = new ShaderProgram(VERT_SHADER, FRAG_SHADER, SpriteBatch.ATTRIBUTES);
//setup our custom uniforms
- shader.begin();
+ shader.use();
shader.setUniformi(TEX_ALT, 1);
shader.setUniformi(TEX_MASK, 2);
-
- shader.end();
-
+
System.out.println(VERT_SHADER);
System.out.println();
System.out.println(FRAG_SHADER);
View
0  src/mdesl/test/VertexArrayExample.java → test/mdesl/test/VertexArrayExample.java
File renamed without changes
View
66 test/mdesl/test/shadertut/ShaderLesson1.java
@@ -0,0 +1,66 @@
+package mdesl.test.shadertut;
+
+import java.io.IOException;
+
+import mdesl.graphics.SpriteBatch;
+import mdesl.graphics.Texture;
+import mdesl.graphics.glutils.ShaderProgram;
+import mdesl.test.Game;
+import mdesl.test.SimpleGame;
+import mdesl.util.Util;
+
+import org.lwjgl.LWJGLException;
+import org.lwjgl.opengl.Display;
+
+public class ShaderLesson1 extends SimpleGame {
+
+ public static void main(String[] args) throws LWJGLException {
+ Game game = new ShaderLesson1();
+ game.setDisplayMode(800, 600, false);
+ game.start();
+ }
+
+ //our texture
+ Texture tex;
+
+ //our sprite batch
+ SpriteBatch batch;
+
+ protected void create() throws LWJGLException {
+ super.create();
+
+ // Load our textures
+ try {
+ tex = new Texture(Util.getResource("res/grass.png"), Texture.LINEAR);
+ } catch (IOException e) {
+ throw new RuntimeException("couldn't decode texture");
+ }
+
+ // As explained in SpriteBatch docs, we will use the following
+ // attributes:
+
+ // create a new shader program
+ // ShaderProgram program = new ShaderProgram(VERTEX, FRAGMENT,
+ // SpriteBatch.ATTRIBUTES);
+ batch = new SpriteBatch(1000);
+ }
+
+ protected void render() throws LWJGLException {
+ super.render();
+
+ // Begin rendering:
+ batch.begin();
+
+ // batch.draw(tex, 10, 10);
+
+ batch.end();
+ }
+
+ // called to resize the display
+ protected void resize() throws LWJGLException {
+ super.resize();
+
+ // resize our batch with the new screen size
+ batch.resize(Display.getWidth(), Display.getHeight());
+ }
+}
View
0  src/res/dirt.png → test/res/dirt.png
File renamed without changes
View
0  src/res/font0.png → test/res/font0.png
File renamed without changes
View
0  src/res/grass.png → test/res/grass.png
File renamed without changes
View
BIN  test/res/heart.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0  src/res/mask.png → test/res/mask.png
File renamed without changes
View
0  test/res/shaders/test1.frag
No changes.
View
0  test/res/shaders/test1.vert
No changes.
View
0  src/res/tiles.png → test/res/tiles.png
File renamed without changes
Please sign in to comment.
Something went wrong with that request. Please try again.