Tessellation shaders (control, evaluation) support

Discuss your feature requests for the next release of Ardor3D here.
Forum rules
Discuss your feature requests for the next release of Ardor3D here. Please make a ticket and reference it in your first post.

Tessellation shaders (control, evaluation) support

Postby gouessej » Thu Jun 28, 2012 5:54 am

Hi

I'm gonna provide some very small patches to add the support of tessellation shaders into Ardor3D.

I have to modify those classes:
- com.ardor3d.renderer.ContextCapabilities (I just plan to add _tessellationShadersSupported, accessors and the correct copy in one of the constructors)
- com.ardor3d.scene.state.jogl.JoglShaderObjectsStateUtil (removeTessControlShader(), removeTessEvalShader(), another step in sendToGL(...))
- com.ardor3d.renderer.state.GLSLShaderObjectsState (_tessControlShader and _tessEvalShader, their names, ids, etc...)
- com.ardor3d.renderer.jogl.JoglContextCapabilities (_tessellationShaders4Supported = gl.isExtensionAvailable("GL_ARB_tessellation_shader") && _glslSupported)

Feel free to port this code to the renderer based on LWJGL and the "legacy" renderer based on JOGL 1 (it might not work as JOGL 1 does not support tessellation shaders). I will implement it only in the renderer based on JOGL 2.0.

As I'm not an expert of shaders, I will rely on you to give it a try and test it. Best regards.
gouessej
regular
 
Posts: 1186
Joined: Fri May 01, 2009 3:26 am
Location: France

Re: Tessellation shaders (control, evaluation) support

Postby gouessej » Thu Jun 28, 2012 1:28 pm

Ok the patch is below, it is quite trivial:
### Eclipse Workspace Patch 1.0
#P ardor3d-core
Index: src/main/java/com/ardor3d/renderer/ContextCapabilities.java
===================================================================
--- src/main/java/com/ardor3d/renderer/ContextCapabilities.java (revision 1854)
+++ src/main/java/com/ardor3d/renderer/ContextCapabilities.java (working copy)
@@ -37,6 +37,7 @@
protected boolean _glslSupported = false;
protected boolean _geometryShader4Supported = false;
protected boolean _geometryInstancingSupported = false;
+ protected boolean _tessellationShadersSupported = false;
protected int _maxGLSLVertexAttribs;

protected boolean _pbufferSupported = false;
@@ -147,6 +148,7 @@
_geometryShader4Supported = source._geometryShader4Supported;
_glslSupported = source._glslSupported;
_geometryInstancingSupported = source._geometryInstancingSupported;
+ _tessellationShadersSupported = source._tessellationShadersSupported;
_maxAnisotropic = source._maxAnisotropic;
_maxFBOColorAttachments = source._maxFBOColorAttachments;
_maxFBOSamples = source._maxFBOSamples;
@@ -325,6 +327,14 @@
}

/**
+ * @return <code>true</code> if the GLSL is supported and GL_ARB_tessellation_shader is supported by current
+ * graphics configuration
+ */
+ public boolean isTessellationShadersSupported() {
+ return _tessellationShadersSupported;
+ }
+
+ /**
* @return true if the ARB_shader_objects extension is supported by current graphics configuration.
*/
public boolean isPbufferSupported() {
Index: src/main/java/com/ardor3d/renderer/state/GLSLShaderObjectsState.java
===================================================================
--- src/main/java/com/ardor3d/renderer/state/GLSLShaderObjectsState.java (revision 1854)
+++ src/main/java/com/ardor3d/renderer/state/GLSLShaderObjectsState.java (working copy)
@@ -74,7 +74,7 @@
/** Storage for shader attribute values */
protected List<ShaderVariable> _shaderAttributes = new ArrayList<ShaderVariable>();

- protected ByteBuffer _vertShader, _fragShader, _geomShader;
+ protected ByteBuffer _vertShader, _fragShader, _geomShader, _tessControlShader, _tessEvalShader;

// XXX: The below fields are public for brevity mostly as a way to remember that this class needs revisiting.

@@ -101,6 +101,12 @@
/** OpenGL id for the attached geometry shader. */
public int _geometryShaderID = -1;

+ /** OpenGL id for the attached tessellation control shader. */
+ public int _tessellationControlShaderID = -1;
+
+ /** OpenGL id for the attached tessellation evaluation shader. */
+ public int _tessellationEvaluationShaderID = -1;
+
/** if true, we'll send our vertex attributes to the shader via vbo */
private boolean _useAttributeVBO;

@@ -113,6 +119,12 @@
/** optional name for our geometry shader, used for debugging details. */
public String _geometryShaderName;

+ /** optional name for our tessellation control shader, used for debugging details. */
+ public String _tessellationControlShaderName;
+
+ /** optional name for our tessellation evaluation shader, used for debugging details. */
+ public String _tessellationEvaluationShaderName;
+
/**
* Gets the currently loaded vertex shader.
*
@@ -140,6 +152,24 @@
return _geomShader;
}

+ /**
+ * Gets the currently loaded tessellation control shader.
+ *
+ * @return
+ */
+ public ByteBuffer getTessellationControlShader() {
+ return _tessControlShader;
+ }
+
+ /**
+ * Gets the currently loaded tessellation evaluation shader.
+ *
+ * @return
+ */
+ public ByteBuffer getTessellationEvaluationShader() {
+ return _tessEvalShader;
+ }
+
public void setVertexShader(final InputStream stream) throws IOException {
setVertexShader(stream, "");
}
@@ -167,6 +197,24 @@
_geometryShaderName = name;
}

+ public void setTessellationControlShader(final InputStream stream) throws IOException {
+ setTessellationControlShader(stream, "");
+ }
+
+ public void setTessellationControlShader(final InputStream stream, final String name) throws IOException {
+ setTessellationControlShader(load(stream));
+ _tessellationControlShaderName = name;
+ }
+
+ public void setTessellationEvaluationShader(final InputStream stream) throws IOException {
+ setTessellationEvaluationShader(stream, "");
+ }
+
+ public void setTessellationEvaluationShader(final InputStream stream, final String name) throws IOException {
+ setTessellationEvaluationShader(load(stream));
+ _tessellationEvaluationShaderName = name;
+ }
+
protected ByteBuffer load(final InputStream in) throws IOException {
DataInputStream dataStream = null;
try {
@@ -263,6 +311,52 @@
}

/**
+ * Set the contents for our tessellation control shader
+ *
+ * @param shader
+ * the shader contents.
+ */
+ public void setTessellationControlShader(final ByteBuffer shader) {
+ setTessellationControlShader(shader, "");
+ }
+
+ /**
+ * Set the contents for our tessellation control shader
+ *
+ * @param shader
+ * the shader contents.
+ * @param name
+ * a label for this shader, displayer upon shader errors.
+ */
+ public void setTessellationControlShader(final ByteBuffer shader, final String name) {
+ _tessControlShader = shader;
+ _tessellationControlShaderName = name;
+ }
+
+ /**
+ * Set the contents for our tessellation evaluation shader
+ *
+ * @param shader
+ * the shader contents.
+ */
+ public void setTessellationEvaluationShader(final ByteBuffer shader) {
+ setTessellationEvaluationShader(shader, "");
+ }
+
+ /**
+ * Set the contents for our tessellation evaluation shader
+ *
+ * @param shader
+ * the shader contents.
+ * @param name
+ * a label for this shader, displayer upon shader errors.
+ */
+ public void setTessellationEvaluationShader(final ByteBuffer shader, final String name) {
+ _tessEvalShader = shader;
+ _tessellationEvaluationShaderName = name;
+ }
+
+ /**
* Set the contents for our vertex shader
*
* @param shader
@@ -331,6 +425,52 @@
_geometryShaderName = name;
}

+ /**
+ * Set the contents for our tessellation control shader
+ *
+ * @param shader
+ * the shader contents.
+ */
+ public void setTessellationControlShader(final String shader) {
+ setTessellationControlShader(shader, "");
+ }
+
+ /**
+ * Set the contents for our tessellation control shader
+ *
+ * @param shader
+ * the shader contents.
+ * @param name
+ * a label for this shader, displayer upon shader errors.
+ */
+ public void setTessellationControlShader(final String shader, final String name) {
+ _tessControlShader = stringToByteBuffer(shader);
+ _tessellationControlShaderName = name;
+ }
+
+ /**
+ * Set the contents for our tessellation evaluation shader
+ *
+ * @param shader
+ * the shader contents.
+ */
+ public void setTessellationEvaluationShader(final String shader) {
+ setTessellationEvaluationShader(shader, "");
+ }
+
+ /**
+ * Set the contents for our tessellation evaluation shader
+ *
+ * @param shader
+ * the shader contents.
+ * @param name
+ * a label for this shader, displayer upon shader errors.
+ */
+ public void setTessellationEvaluationShader(final String shader, final String name) {
+ _tessEvalShader = stringToByteBuffer(shader);
+ _tessellationEvaluationShaderName = name;
+ }
+
private ByteBuffer stringToByteBuffer(final String str) {
final byte[] bytes = str.getBytes();
final ByteBuffer buf = BufferUtils.createByteBuffer(bytes.length);
@@ -1152,6 +1292,9 @@
capsule.write(_vertShader, "vertShader", null);
capsule.write(_fragShader, "fragShader", null);
capsule.write(_geomShader, "geomShader", null);
+ capsule.write(_geomShader, "geomShader", null);
+ capsule.write(_tessControlShader, "tessControlShader", null);
+ capsule.write(_tessEvalShader, "tessEvalShader", null);
capsule.write(_useAttributeVBO, "useAttributeVBO", false);

if (_shaderDataLogic instanceof Savable) {
@@ -1167,6 +1310,8 @@
_vertShader = capsule.readByteBuffer("vertShader", null);
_fragShader = capsule.readByteBuffer("fragShader", null);
_geomShader = capsule.readByteBuffer("geomShader", null);
+ _tessControlShader = capsule.readByteBuffer("tessControlShader", null);
+ _tessEvalShader = capsule.readByteBuffer("tessEvalShader", null);
_useAttributeVBO = capsule.readBoolean("useAttributeVBO", false);

final Savable shaderDataLogic = capsule.readSavable("shaderDataLogic", null);




### Eclipse Workspace Patch 1.0
#P ardor3d-jogl2
Index: src/main/java/com/ardor3d/scene/state/jogl/JoglShaderObjectsStateUtil.java
===================================================================
--- src/main/java/com/ardor3d/scene/state/jogl/JoglShaderObjectsStateUtil.java (revision 57)
+++ src/main/java/com/ardor3d/scene/state/jogl/JoglShaderObjectsStateUtil.java (working copy)
@@ -117,11 +117,11 @@
gl.getGL2().glShaderSourceARB(state._geometryShaderID, 1, new String[] { new String(array) },
new int[] { array.length }, 0);

- // Compile the fragment shader
+ // Compile the geometry shader
final IntBuffer compiled = BufferUtils.createIntBuffer(1);
gl.getGL2().glCompileShaderARB(state._geometryShaderID);
gl.getGL2().glGetObjectParameterivARB(state._geometryShaderID, GL2.GL_OBJECT_COMPILE_STATUS_ARB, compiled);
- checkProgramError(compiled, state._geometryShaderID, state._vertexShaderName);
+ checkProgramError(compiled, state._geometryShaderID, state._geometryShaderName);

// Attach the program
gl.getGL2().glAttachObjectARB(state._programID, state._geometryShaderID);
@@ -130,6 +130,61 @@
state._geometryShaderID = -1;
}
}
+
+ if (caps.isTessellationShadersSupported()) {
+ if (state.getTessellationControlShader() != null) {
+ if (state._tessellationControlShaderID != -1) {
+ removeTessControlShader(state);
+ }
+
+ state._tessellationControlShaderID = gl.getGL2().glCreateShaderObjectARB(GL4.GL_TESS_CONTROL_SHADER);
+
+ // Create the sources
+ final byte array[] = new byte[state.getTessellationControlShader().limit()];
+ state.getTessellationControlShader().rewind();
+ state.getTessellationControlShader().get(array);
+ gl.getGL2().glShaderSourceARB(state._tessellationControlShaderID, 1, new String[] { new String(array) },
+ new int[] { array.length }, 0);
+
+ // Compile the tessellation control shader
+ final IntBuffer compiled = BufferUtils.createIntBuffer(1);
+ gl.getGL2().glCompileShaderARB(state._tessellationControlShaderID);
+ gl.getGL2().glGetObjectParameterivARB(state._tessellationControlShaderID, GL2.GL_OBJECT_COMPILE_STATUS_ARB, compiled);
+ checkProgramError(compiled, state._tessellationControlShaderID, state._tessellationControlShaderName);
+
+ // Attach the program
+ gl.getGL2().glAttachObjectARB(state._programID, state._tessellationControlShaderID);
+ } else if (state._tessellationControlShaderID != -1) {
+ removeTessControlShader(state);
+ state._tessellationControlShaderID = -1;
+ }
+ if (state.getTessellationEvaluationShader() != null) {
+ if (state._tessellationEvaluationShaderID != -1) {
+ removeTessEvalShader(state);
+ }
+
+ state._tessellationEvaluationShaderID = gl.getGL2().glCreateShaderObjectARB(GL4.GL_TESS_CONTROL_SHADER);
+
+ // Create the sources
+ final byte array[] = new byte[state.getTessellationEvaluationShader().limit()];
+ state.getTessellationEvaluationShader().rewind();
+ state.getTessellationEvaluationShader().get(array);
+ gl.getGL2().glShaderSourceARB(state._tessellationEvaluationShaderID, 1, new String[] { new String(array) },
+ new int[] { array.length }, 0);
+
+ // Compile the tessellation control shader
+ final IntBuffer compiled = BufferUtils.createIntBuffer(1);
+ gl.getGL2().glCompileShaderARB(state._tessellationEvaluationShaderID);
+ gl.getGL2().glGetObjectParameterivARB(state._tessellationEvaluationShaderID, GL2.GL_OBJECT_COMPILE_STATUS_ARB, compiled);
+ checkProgramError(compiled, state._tessellationEvaluationShaderID, state._tessellationEvaluationShaderName);
+
+ // Attach the program
+ gl.getGL2().glAttachObjectARB(state._programID, state._tessellationEvaluationShaderID);
+ } else if (state._tessellationEvaluationShaderID != -1) {
+ removeTessEvalShader(state);
+ state._tessellationEvaluationShaderID = -1;
+ }
+ }

gl.getGL2().glLinkProgramARB(state._programID);
checkLinkError(state._programID);
@@ -191,6 +246,26 @@
gl.getGL2().glDeleteObjectARB(state._geometryShaderID);
}
}
+
+ /** Removes the tessellation control shader */
+ private static void removeTessControlShader(final GLSLShaderObjectsState state) {
+ final GL gl = GLU.getCurrentGL();
+
+ if (state._tessellationControlShaderID != -1) {
+ gl.getGL2().glDetachObjectARB(state._programID, state._tessellationControlShaderID);
+ gl.getGL2().glDeleteObjectARB(state._tessellationControlShaderID);
+ }
+ }
+
+ /** Removes the tessellation evaluation shader */
+ private static void removeTessEvalShader(final GLSLShaderObjectsState state) {
+ final GL gl = GLU.getCurrentGL();
+
+ if (state._tessellationEvaluationShaderID != -1) {
+ gl.getGL2().glDetachObjectARB(state._programID, state._tessellationEvaluationShaderID);
+ gl.getGL2().glDeleteObjectARB(state._tessellationEvaluationShaderID);
+ }
+ }

/**
* Check for program errors. If an error is detected, program exits.
Index: src/main/java/com/ardor3d/renderer/jogl/JoglContextCapabilities.java
===================================================================
--- src/main/java/com/ardor3d/renderer/jogl/JoglContextCapabilities.java (revision 57)
+++ src/main/java/com/ardor3d/renderer/jogl/JoglContextCapabilities.java (working copy)
@@ -73,6 +73,8 @@

_geometryInstancingSupported = _glslSupported && gl.isExtensionAvailable("GL_EXT_draw_instanced");

+ _tessellationShadersSupported = gl.isExtensionAvailable("GL_ARB_tessellation_shader") && _glslSupported;
+
if (_glslSupported) {
gl.glGetIntegerv(GL2.GL_MAX_VERTEX_ATTRIBS_ARB, buf);
_maxGLSLVertexAttribs = buf.get(0);
gouessej
regular
 
Posts: 1186
Joined: Fri May 01, 2009 3:26 am
Location: France

Re: Tessellation shaders (control, evaluation) support

Postby renanse » Thu Jul 05, 2012 10:25 am

Applied the changes to the core.
Gratitude is a mark of a noble soul and a refined character.
User avatar
renanse
Site Admin
 
Posts: 2955
Joined: Tue Oct 28, 2008 6:49 pm
Location: Austin, TX

Re: Tessellation shaders (control, evaluation) support

Postby gouessej » Thu Jul 05, 2012 4:03 pm

renanse wrote:Applied the changes to the core.

Thanks. I committed the changes in the renderer based on JOGL 2.0.
gouessej
regular
 
Posts: 1186
Joined: Fri May 01, 2009 3:26 am
Location: France


Return to Wishlist

Who is online

Users browsing this forum: No registered users and 1 guest

cron