Skip to content
This repository has been archived by the owner on Jan 14, 2023. It is now read-only.

Commit

Permalink
New shader pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonborkholder committed Dec 30, 2011
1 parent 7f595f2 commit e9db0c1
Show file tree
Hide file tree
Showing 12 changed files with 382 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/main/java/glg2d/G2DGLStringDrawer.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,14 @@ protected void setTextColorRespectComposite(TextRenderer renderer, Color color)

public void drawString(String string, Color color, int x, int y) {
TextRenderer renderer = getRenderer(getFont());
setTextColorRespectComposite(renderer, color);

begin(renderer, color);
renderer.draw3D(string, x, g2d.getHeight() - y, 0, 1);
end(renderer);
}

protected void begin(TextRenderer renderer, Color textColor) {
setTextColorRespectComposite(renderer, textColor);

GL gl = g2d.getGLContext().getGL();
gl.glMatrixMode(GL.GL_MODELVIEW);
Expand All @@ -139,9 +146,12 @@ public void drawString(String string, Color color, int x, int y) {
gl.glTranslatef(0, -g2d.getHeight(), 0);

renderer.begin3DRendering();
renderer.draw3D(string, x, g2d.getHeight() - y, 0, 1);
}

protected void end(TextRenderer renderer) {
renderer.end3DRendering();

GL gl = g2d.getGLContext().getGL();
gl.glPopMatrix();
}

Expand Down
138 changes: 138 additions & 0 deletions src/main/java/glg2d/shaders/BasicShader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package glg2d.shaders;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import javax.media.opengl.GL;

public class BasicShader implements Shader {
protected String[] vertexShaderSrc;
protected String[] fragmentShaderSrc;

protected int vertexShaderId;
protected int fragmentShaderId;

protected GL gl;

protected int programId;

public BasicShader(GL gl) {
this.gl = gl;
}

public void readSources(String name) {
try {
vertexShaderSrc = readShader(name + ".v");
fragmentShaderSrc = readShader(name + ".f");
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
public void createAndAttach() {
programId = gl.glCreateProgram();
gl.glAttachShader(programId, vertexShaderId);
gl.glAttachShader(programId, fragmentShaderId);
gl.glLinkProgram(programId);
checkProgramThrowException(GL.GL_LINK_STATUS);

gl.glValidateProgram(programId);
checkProgramThrowException(GL.GL_VALIDATE_STATUS);
}

@Override
public void use(boolean use) {
gl.glUseProgram(use ? programId : 0);
}

@Override
public void delete() {
gl.glDeleteShader(fragmentShaderId);
gl.glDeleteShader(vertexShaderId);
gl.glDeleteProgram(programId);
}

@Override
public void compileVertexShader() {
int[] lengths = lengths(vertexShaderSrc);

vertexShaderId = gl.glCreateShader(GL.GL_VERTEX_SHADER);
gl.glShaderSource(vertexShaderId, vertexShaderSrc.length, vertexShaderSrc, lengths, 0);
gl.glCompileShader(vertexShaderId);

checkShaderThrowException(vertexShaderId);
}

@Override
public void compileFragmentShader() {
int[] lengths = lengths(fragmentShaderSrc);

fragmentShaderId = gl.glCreateShader(GL.GL_FRAGMENT_SHADER);
gl.glShaderSource(fragmentShaderId, fragmentShaderSrc.length, fragmentShaderSrc, lengths, 0);
gl.glCompileShader(fragmentShaderId);

checkShaderThrowException(fragmentShaderId);
}

protected void checkShaderThrowException(int shader) {
int[] result = new int[1];
gl.glGetShaderiv(shader, GL.GL_COMPILE_STATUS, result, 0);
if (result[0] == GL.GL_TRUE) {
return;
}

gl.glGetShaderiv(shader, GL.GL_INFO_LOG_LENGTH, result, 0);
int size = result[0];
byte[] data = new byte[size];
gl.glGetShaderInfoLog(shader, size, result, 0, data, 0);

String error = new String(data, 0, result[0]);
throw new ShaderException(error);
}

protected void checkProgramThrowException(int status) {
int[] result = new int[1];
gl.glGetProgramiv(programId, status, result, 0);
if (result[0] == GL.GL_TRUE) {
return;
}

gl.glGetProgramiv(programId, GL.GL_INFO_LOG_LENGTH, result, 0);
int size = result[0];
byte[] data = new byte[size];
gl.glGetProgramInfoLog(programId, size, result, 0, data, 0);

String error = new String(data, 0, result[0]);
throw new ShaderException(error);
}

protected int[] lengths(String[] lines) {
int[] lengths = new int[lines.length];
for (int i = 0; i < lengths.length; i++) {
lengths[i] = lines[i].length();
}

return lengths;
}

protected String[] readShader(String name) throws IOException {
InputStream stream = BasicShader.class.getResourceAsStream(name);
if (stream == null) {
throw new IOException("Shader " + name + " not found");
}

BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line = null;
List<String> lines = new ArrayList<String>();
while ((line = reader.readLine()) != null) {
lines.add(line);
}

return lines.toArray(new String[lines.size()]);
}
}
3 changes: 3 additions & 0 deletions src/main/java/glg2d/shaders/FixedFuncShader.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
void main() {
gl_FragColor = gl_Color;
}
4 changes: 4 additions & 0 deletions src/main/java/glg2d/shaders/FixedFuncShader.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
void main() {
gl_Position = ftransform();
gl_FrontColor = gl_Color;
}
34 changes: 34 additions & 0 deletions src/main/java/glg2d/shaders/G2DShaderImageDrawer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package glg2d.shaders;

import glg2d.G2DGLImageDrawer;
import glg2d.GLGraphics2D;

import java.awt.Color;
import java.awt.geom.AffineTransform;

import com.sun.opengl.util.texture.Texture;

public class G2DShaderImageDrawer extends G2DGLImageDrawer {
protected Shader shader;

@Override
public void setG2D(GLGraphics2D g2d) {
super.setG2D(g2d);

if (shader == null) {
shader = ((GLShaderGraphics2D) g2d).getShaderRegistry().getTextureShader();
}
}

@Override
protected void begin(Texture texture, AffineTransform xform, Color bgcolor) {
super.begin(texture, xform, bgcolor);
shader.use(true);
}

@Override
protected void end(Texture texture) {
shader.use(false);
super.end(texture);
}
}
33 changes: 33 additions & 0 deletions src/main/java/glg2d/shaders/G2DShaderStringDrawer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package glg2d.shaders;

import glg2d.G2DGLStringDrawer;
import glg2d.GLGraphics2D;

import java.awt.Color;

import com.sun.opengl.util.j2d.TextRenderer;

public class G2DShaderStringDrawer extends G2DGLStringDrawer {
protected Shader shader;

@Override
public void setG2D(GLGraphics2D g2d) {
super.setG2D(g2d);

if (shader == null) {
shader = ((GLShaderGraphics2D) g2d).getShaderRegistry().getTextureShader();
}
}

@Override
protected void begin(TextRenderer renderer, Color textColor) {
super.begin(renderer, textColor);
shader.use(true);
}

@Override
protected void end(TextRenderer renderer) {
shader.use(false);
super.end(renderer);
}
}
31 changes: 31 additions & 0 deletions src/main/java/glg2d/shaders/GLShaderGraphics2D.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package glg2d.shaders;

import glg2d.GLGraphics2D;

import javax.media.opengl.GLAutoDrawable;

public class GLShaderGraphics2D extends GLGraphics2D {
protected ShaderRegistry shaders;

public GLShaderGraphics2D(int width, int height) {
super(width, height);

shaders = new ShaderRegistry();

imageDrawer = new G2DShaderImageDrawer();
stringDrawer = new G2DShaderStringDrawer();
}

@Override
protected void setCanvas(GLAutoDrawable drawable) {
glContext = drawable.getContext();
gl = glContext.getGL();

shaders.setG2D(this);
super.setCanvas(drawable);
}

public ShaderRegistry getShaderRegistry() {
return shaders;
}
}
13 changes: 13 additions & 0 deletions src/main/java/glg2d/shaders/Shader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package glg2d.shaders;

public interface Shader {
void compileVertexShader();

void compileFragmentShader();

void createAndAttach();

void use(boolean use);

void delete();
}
25 changes: 25 additions & 0 deletions src/main/java/glg2d/shaders/ShaderException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package glg2d.shaders;

public class ShaderException extends RuntimeException {
private static final long serialVersionUID = 829519650852350876L;

public ShaderException() {
super();
}

public ShaderException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}

public ShaderException(String message, Throwable cause) {
super(message, cause);
}

public ShaderException(String message) {
super(message);
}

public ShaderException(Throwable cause) {
super(cause);
}
}
75 changes: 75 additions & 0 deletions src/main/java/glg2d/shaders/ShaderRegistry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package glg2d.shaders;

import glg2d.G2DDrawingHelper;
import glg2d.GLGraphics2D;

public class ShaderRegistry implements G2DDrawingHelper {
protected Shader fixedFunction;
protected Shader texture;

protected boolean needsRecompile;

@Override
public void setG2D(GLGraphics2D g2d) {
if (fixedFunction == null) {
fixedFunction = createFixedFunctionShader(g2d);
needsRecompile = true;
}

if (texture == null) {
texture = createTextureShader(g2d);
needsRecompile = true;
}

if (needsRecompile) {
fixedFunction.compileVertexShader();
fixedFunction.compileFragmentShader();
fixedFunction.createAndAttach();

texture.compileVertexShader();
texture.compileFragmentShader();
texture.createAndAttach();

needsRecompile = false;
}
}

@Override
public void dispose() {
fixedFunction.delete();
texture.delete();
needsRecompile = true;
}

public Shader getFixedFunctionShader() {
return fixedFunction;
}

public Shader getTextureShader() {
return texture;
}

protected Shader createFixedFunctionShader(GLGraphics2D g2d) {
BasicShader shader = new BasicShader(g2d.getGLContext().getGL());
shader.readSources("FixedFuncShader");

return shader;
}

protected Shader createTextureShader(GLGraphics2D g2d) {
BasicShader shader = new BasicShader(g2d.getGLContext().getGL());
shader.readSources("TextureShader");

return shader;
}

@Override
public void pop(GLGraphics2D parentG2d) {
// nop
}

@Override
public void push(GLGraphics2D newG2d) {
// nop
}
}
Loading

0 comments on commit e9db0c1

Please sign in to comment.