Skip to content

@mattdesl /RGBATextureTest.java
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Simple implementation of a software shader; uploading RGBA data to a texture every frame.
package mdesl.test;
import static org.lwjgl.opengl.GL11.glClearColor;
import java.nio.ByteBuffer;
import mdesl.graphics.Color;
import mdesl.graphics.SpriteBatch;
import mdesl.graphics.Texture;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
public class RGBATextureTest extends SimpleGame {
public static void main(String[] args) throws LWJGLException {
Game game = new RGBATextureTest();
game.setDisplayMode(640, 480, false);
game.start();
}
final int TEX_SIZE = 256;
//our sprite batch
SpriteBatch batch;
//our procedural texture
Texture tex;
ByteBuffer buffer;
float time = 0;
SoftwareShader shader;
protected void create() throws LWJGLException {
super.create();
//create an empty texture
tex = new Texture(TEX_SIZE, TEX_SIZE, Texture.LINEAR, Texture.REPEAT);
buffer = BufferUtils.createByteBuffer(tex.getWidth() * tex.getHeight() * 4);
shader = new Kaliset();
glClearColor(0.5f, .5f, .5f, 1f);
batch = new SpriteBatch();
}
protected void render() throws LWJGLException {
time += this.getDeltaTime();
int w = tex.getWidth();
int h = tex.getHeight();
Color color = new Color();
buffer.clear(); //clear our RGBA buffer
for (int i=0; i<w * h; i++) {
//offset to (x, y)
int y = i / w;
int x = i - w*y;
shader.getPixelColor(x, y, w, h, time, color);
//place R, G, B, A bytes
buffer.put( (byte)(Math.min(255, Math.max(0, color.r*255))) )
.put( (byte)(Math.min(255, Math.max(0, color.g*255))) )
.put( (byte)(Math.min(255, Math.max(0, color.b*255))) )
.put( (byte)(Math.min(255, Math.max(0, color.a*255))) );
}
buffer.flip();
tex.upload(GL11.GL_RGBA, buffer);
super.render();
batch.begin();
batch.draw(tex, 0, 0);
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());
}
//emulates shaders in software
interface SoftwareShader {
/**
* Gets the pixel color for the specified input values, placing it in the "out" param.
*
* @param x the x position of this pixel
* @param y the y position of this pixel
* @param width the width of the texture in pixels
* @param height the height of the texture in pixels
* @param time a time offset for effects
* @param the output color
*/
public void getPixelColor(int x, int y, int width, int height, float time, Color out);
}
//Kaliset fractal
//https://bitbucket.org/sharow/pijockey/src/tip/shaders/kaliset.glsl
class Kaliset implements SoftwareShader {
public static final int ITERATIONS = 22;
public void getPixelColor(int x, int y, int width, int height, float time, Color out) {
float cx = (float)(-0.5 * (2.5 + Math.sin(time * 0.0025)) / 2.0 + 0.3);
float cy = (float)(-0.5 * (2.5 + Math.sin(time * 0.0025)) / 2.0 + 0.3);
float zx = (x / (float)width) * 3f - 1.5f;
float zy = (y / (float)height) * 3f - 1.5f;
float total = 0f;
float m = 0f;
for (int i=0; i<ITERATIONS; i++) {
float pm = m;
m = zx*zx + zy*zy;
zx = Math.abs(zx) / m + cx;
zy = Math.abs(zy) / m + cy;
total += (float)Math.exp(-1.0 / Math.abs(m - pm));
}
total = total / 20f;
out.r = total*.5f;
out.g = total;
out.b = (float)(total/Math.sin(Math.cos(time/10f)));
out.a = 1.0f;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.