Image
defines a data format for a graphical image. The image
@@ -597,6 +599,61 @@ public boolean isFloatingPont(){
+ }
+
+ public enum Access {
+
+ /**
+ * The image can only read from in a shader.
+ */
+ ReadOnly(true, false, GL20.GL_READ_ONLY),
+
+ /**
+ * The image can written to in a shader.
+ */
+ WriteOnly(false, true, GL20.GL_WRITE_ONLY),
+
+ /**
+ * The image can both be written to and read from in a shader.
+ */
+ ReadWrite(true, true, GL20.GL_READ_WRITE);
+
+ private final boolean read, write;
+ private final int glEnum;
+
+ private Access(boolean read, boolean write, int glEnum) {
+ this.read = read;
+ this.write = write;
+ this.glEnum = glEnum;
+ }
+
+ /**
+ * If true, the image can be read from in a shader.
+ *
+ * @return
+ */
+ public boolean isRead() {
+ return read;
+ }
+
+ /**
+ * If true, the image can be written to in a shader.
+ *
+ * @return
+ */
+ public boolean isWrite() {
+ return write;
+ }
+
+ /**
+ * Corresponding OpenGL enum.
+ *
+ * @return
+ */
+ public int getGlEnum() {
+ return glEnum;
+ }
+
}
// image attributes
@@ -606,11 +663,14 @@ public boolean isFloatingPont(){
protected ArrayList+ * If not null, the image will be bound in such a way as to allow + * {@code imageStore} and {@code imageLoad} functions to work. Otherwise + * the image will be bound normally. + *
+ * default=null + * + * @param access + */ + public void setAccess(Access access) { + if (this.access != access) { + this.access = access; + accessUpdateNeeded = true; + } + } + + /** + * + * @return + * @see #setAccess(com.jme3.texture.Image.Access) + */ + public Access getAccess() { + return access; + } + + /** + * Sets the bind layer used if {@link #getAccess()} does not + * return null. + *
+ * If greater than or equal to zero, only the specified layer will be + * bound. If less than zero, the entire image will be bound. + *
+ * default=-1 + * + * @param bindLayer + */ + public void setBindLayer(int bindLayer) { + if (this.bindLayer != bindLayer) { + this.bindLayer = bindLayer; + accessUpdateNeeded = true; + } + } + + /** + * Sets or clears the update flag indicating that this image must + * be rebound in cases where {@link #getAccess()} is not null. + * + * @param accessUpdateNeeded + */ + public void setAccessUpdateNeeded(boolean accessUpdateNeeded) { + this.accessUpdateNeeded = accessUpdateNeeded; + } + + /** + * Indicates that this image must be rebound in cases + * where {@link #getAccess()} is not null. + * + * @return + */ + public boolean isAccessUpdateNeeded() { + return accessUpdateNeeded; + } + + /** + * + * @return + * @see #setBindLayer(int) + */ + public int getBindLayer() { + return bindLayer; + } + + /** + * Returns true if the entire image will be bound in cases where + * {@link #getAccess()} does not return null. + * + * @return + */ + public boolean isLayered() { + return bindLayer < 0; + } + @Override public String toString(){ StringBuilder sb = new StringBuilder(); @@ -1286,6 +1430,8 @@ public void write(JmeExporter e) throws IOException { capsule.write(multiSamples, "multiSamples", 1); capsule.writeByteBufferArrayList(data, "data", null); capsule.write(colorSpace, "colorSpace", null); + capsule.write(access, "access", null); + capsule.write(bindLayer, "bindLayer", -1); } @Override @@ -1299,7 +1445,8 @@ public void read(JmeImporter importer) throws IOException { multiSamples = capsule.readInt("multiSamples", 1); data = capsule.readByteBufferArrayList("data", null); colorSpace = capsule.readEnum("colorSpace", ColorSpace.class, null); - + access = capsule.readEnum("access", Access.class, null); + bindLayer = capsule.readInt("bindLayer", -1); if (mipMapSizes != null) { needGeneratedMips = false; mipsWereGenerated = true; From 270a41a738dff70b193512573bd13c0a214963f3 Mon Sep 17 00:00:00 2001 From: codex <103840984+codex128@users.noreply.github.com> Date: Sun, 24 Nov 2024 18:16:53 -0500 Subject: [PATCH 02/11] moved glBindImageTexture call to just after glBindTexture call --- .../com/jme3/renderer/opengl/GLRenderer.java | 32 +++++++++++-------- .../src/main/java/com/jme3/texture/Image.java | 25 ++------------- 2 files changed, 20 insertions(+), 37 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java index a375cc8be4..6000f67f96 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java @@ -1986,7 +1986,7 @@ public void updateRenderTexture(FrameBuffer fb, RenderBuffer rb) { // NOTE: For depth textures, sets nearest/no-mips mode // Required to fix "framebuffer unsupported" // for old NVIDIA drivers! - setupTextureParams(0, tex, true); + setupTextureParams(0, tex); } if (rb.getLayer() < 0){ @@ -2393,7 +2393,7 @@ private int convertWrapMode(Texture.WrapMode mode) { } @SuppressWarnings("fallthrough") - private void setupTextureParams(int unit, Texture tex, boolean accessBindUpdate) { + private void setupTextureParams(int unit, Texture tex) { Image image = tex.getImage(); int samples = image != null ? image.getMultiSamples() : 1; int target = convertTextureType(tex.getType(), samples, -1); @@ -2479,15 +2479,6 @@ private void setupTextureParams(int unit, Texture tex, boolean accessBindUpdate) // If at this point we didn't bind the texture, bind it now bindTextureOnly(target, image, unit); - // binds the image so that imageStore and imageLoad operations - // can be used in shaders on the image - if ((accessBindUpdate || image.isAccessUpdateNeeded()) && image.getAccess() != null) { - GL43.glBindImageTexture(unit, image.getId(), 0, image.isLayered(), - Math.max(image.getBindLayer(), 0), image.getAccess().getGlEnum(), - texUtil.getImageFormat(image.getFormat(), false).internalFormat); - image.setAccessUpdateNeeded(false); - } - } /** @@ -2560,6 +2551,13 @@ private void bindTextureAndUnit(int target, Image img, int unit) { } if (context.boundTextures[unit]==null||context.boundTextures[unit].get() != img.getWeakRef().get()) { gl.glBindTexture(target, img.getId()); + if (img.getAccess() != null) { + // binds the image so that imageStore and imageLoad operations + // can be used in shaders on the image + GL43.glBindImageTexture(unit, img.getId(), 0, img.isLayered(), + Math.max(img.getBindLayer(), 0), img.getAccess().getGlEnum(), + texUtil.getImageFormat(img.getFormat(), false).internalFormat); + } context.boundTextures[unit] = img.getWeakRef(); statistics.onTextureUse(img, true); } else { @@ -2582,6 +2580,13 @@ private void bindTextureOnly(int target, Image img, int unit) { context.boundTextureUnit = unit; } gl.glBindTexture(target, img.getId()); + if (img.getAccess() != null) { + // binds the image so that imageStore and imageLoad operations + // can be used in shaders on the image + GL43.glBindImageTexture(unit, img.getId(), 0, img.isLayered(), + Math.max(img.getBindLayer(), 0), img.getAccess().getGlEnum(), + texUtil.getImageFormat(img.getFormat(), false).internalFormat); + } context.boundTextures[unit] = img.getWeakRef(); statistics.onTextureUse(img, true); } else { @@ -2734,8 +2739,7 @@ public void setTexture(int unit, Texture tex) throws TextureUnitException { } Image image = tex.getImage(); - boolean updateNeeded = image.isUpdateNeeded(); - if (updateNeeded || (image.isGeneratedMipmapsRequired() && !image.isMipmapsGenerated())) { + if (image.isUpdateNeeded() || (image.isGeneratedMipmapsRequired() && !image.isMipmapsGenerated())) { // Check NPOT requirements boolean scaleToPot = false; @@ -2759,7 +2763,7 @@ public void setTexture(int unit, Texture tex) throws TextureUnitException { int texId = image.getId(); assert texId != -1; - setupTextureParams(unit, tex, updateNeeded); + setupTextureParams(unit, tex); if (debug && caps.contains(Caps.GLDebug)) { if (tex.getName() != null) glext.glObjectLabel(GL.GL_TEXTURE, tex.getImage().getId(), tex.getName()); } diff --git a/jme3-core/src/main/java/com/jme3/texture/Image.java b/jme3-core/src/main/java/com/jme3/texture/Image.java index f5b72522d4..87ed9f3a48 100644 --- a/jme3-core/src/main/java/com/jme3/texture/Image.java +++ b/jme3-core/src/main/java/com/jme3/texture/Image.java @@ -670,7 +670,6 @@ public int getGlEnum() { // attributes relating to GL object protected boolean mipsWereGenerated = false; protected boolean needGeneratedMips = false; - protected boolean accessUpdateNeeded = true; protected LastTextureState lastTextureState = new LastTextureState(); /** @@ -1284,7 +1283,7 @@ public ColorSpace getColorSpace() { public void setAccess(Access access) { if (this.access != access) { this.access = access; - accessUpdateNeeded = true; + setUpdateNeeded(); } } @@ -1311,30 +1310,10 @@ public Access getAccess() { public void setBindLayer(int bindLayer) { if (this.bindLayer != bindLayer) { this.bindLayer = bindLayer; - accessUpdateNeeded = true; + setUpdateNeeded(); } } - /** - * Sets or clears the update flag indicating that this image must - * be rebound in cases where {@link #getAccess()} is not null. - * - * @param accessUpdateNeeded - */ - public void setAccessUpdateNeeded(boolean accessUpdateNeeded) { - this.accessUpdateNeeded = accessUpdateNeeded; - } - - /** - * Indicates that this image must be rebound in cases - * where {@link #getAccess()} is not null. - * - * @return - */ - public boolean isAccessUpdateNeeded() { - return accessUpdateNeeded; - } - /** * * @return From c57af6a858a7a45e443a313dbe2ec998f0e5880c Mon Sep 17 00:00:00 2001 From: codex <103840984+codex128@users.noreply.github.com> Date: Sun, 24 Nov 2024 18:41:18 -0500 Subject: [PATCH 03/11] revert unnecessary change --- jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java index 6000f67f96..01e346f4d4 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java @@ -2478,7 +2478,6 @@ private void setupTextureParams(int unit, Texture tex) { // If at this point we didn't bind the texture, bind it now bindTextureOnly(target, image, unit); - } /** From ed7246dca361dff60147237745ebc8a569aa1801 Mon Sep 17 00:00:00 2001 From: codex <103840984+codex128@users.noreply.github.com> Date: Sun, 24 Nov 2024 18:56:11 -0500 Subject: [PATCH 04/11] fix direct references to lwjgl in core --- .../main/java/com/jme3/renderer/opengl/GL2.java | 4 ++++ .../main/java/com/jme3/renderer/opengl/GL4.java | 15 +++++++++++++++ .../java/com/jme3/renderer/opengl/GLRenderer.java | 9 ++++----- .../src/main/java/com/jme3/texture/Image.java | 9 ++++----- .../java/com/jme3/renderer/lwjgl/LwjglGL.java | 6 ++++++ 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL2.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL2.java index 89fea8c88c..21be3e5c39 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL2.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL2.java @@ -74,6 +74,10 @@ public interface GL2 extends GL { public static final int GL_TEXTURE_WRAP_R = 0x8072; public static final int GL_VERTEX_PROGRAM_POINT_SIZE = 0x8642; public static final int GL_UNSIGNED_INT_8_8_8_8 = 0x8035; + + public static final int GL_READ_ONLY = 35000; + public static final int GL_WRITE_ONLY = 35001; + public static final int GL_READ_WRITE = 35002; /** *
Reference Page - This function is deprecated and unavailable in the Core profile
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java index 04ad52b2dd..17c0bc4f1c 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java @@ -100,4 +100,19 @@ public interface GL4 extends GL3 { * @param storageBlockBinding The index storage block binding to associate with the specified storage block. */ public void glShaderStorageBlockBinding(int program, int storageBlockIndex, int storageBlockBinding); + + /** + * Binds a single level of a texture to an image unit for the purpose of reading + * and writing it from shaders. + * + * @param unit image unit to bind to + * @param texture texture to bind to the image unit + * @param level level of the texture to bind + * @param layered true to bind all array elements + * @param layer if not layered, the layer to bind + * @param access access types that may be performed + * @param format format to use when performing formatted stores + */ + public void glBindImageTexture(int unit, int texture, int level, boolean layered, int layer, int access, int format); + } diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java index 01e346f4d4..0ad1169546 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java @@ -80,7 +80,6 @@ import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.lwjgl.opengl.GL43; public final class GLRenderer implements Renderer { @@ -2550,10 +2549,10 @@ private void bindTextureAndUnit(int target, Image img, int unit) { } if (context.boundTextures[unit]==null||context.boundTextures[unit].get() != img.getWeakRef().get()) { gl.glBindTexture(target, img.getId()); - if (img.getAccess() != null) { + if (gl4 != null && img.getAccess() != null) { // binds the image so that imageStore and imageLoad operations // can be used in shaders on the image - GL43.glBindImageTexture(unit, img.getId(), 0, img.isLayered(), + gl4.glBindImageTexture(unit, img.getId(), 0, img.isLayered(), Math.max(img.getBindLayer(), 0), img.getAccess().getGlEnum(), texUtil.getImageFormat(img.getFormat(), false).internalFormat); } @@ -2579,10 +2578,10 @@ private void bindTextureOnly(int target, Image img, int unit) { context.boundTextureUnit = unit; } gl.glBindTexture(target, img.getId()); - if (img.getAccess() != null) { + if (gl4 != null && img.getAccess() != null) { // binds the image so that imageStore and imageLoad operations // can be used in shaders on the image - GL43.glBindImageTexture(unit, img.getId(), 0, img.isLayered(), + gl4.glBindImageTexture(unit, img.getId(), 0, img.isLayered(), Math.max(img.getBindLayer(), 0), img.getAccess().getGlEnum(), texUtil.getImageFormat(img.getFormat(), false).internalFormat); } diff --git a/jme3-core/src/main/java/com/jme3/texture/Image.java b/jme3-core/src/main/java/com/jme3/texture/Image.java index 87ed9f3a48..a0bc9b81bc 100644 --- a/jme3-core/src/main/java/com/jme3/texture/Image.java +++ b/jme3-core/src/main/java/com/jme3/texture/Image.java @@ -37,9 +37,9 @@ import com.jme3.export.OutputCapsule; import com.jme3.export.Savable; import com.jme3.math.FastMath; -import com.jme3.opencl.MemoryAccess; import com.jme3.renderer.Caps; import com.jme3.renderer.Renderer; +import com.jme3.renderer.opengl.GL2; import com.jme3.texture.image.ColorSpace; import com.jme3.texture.image.LastTextureState; import com.jme3.util.BufferUtils; @@ -49,7 +49,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.lwjgl.opengl.GL20; /** *Image
defines a data format for a graphical image. The image
@@ -606,17 +605,17 @@ public enum Access {
/**
* The image can only read from in a shader.
*/
- ReadOnly(true, false, GL20.GL_READ_ONLY),
+ ReadOnly(true, false, GL2.GL_READ_ONLY),
/**
* The image can written to in a shader.
*/
- WriteOnly(false, true, GL20.GL_WRITE_ONLY),
+ WriteOnly(false, true, GL2.GL_WRITE_ONLY),
/**
* The image can both be written to and read from in a shader.
*/
- ReadWrite(true, true, GL20.GL_READ_WRITE);
+ ReadWrite(true, true, GL2.GL_READ_WRITE);
private final boolean read, write;
private final int glEnum;
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
index 6c070c83da..6721c24ee8 100644
--- a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
+++ b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
@@ -80,6 +80,12 @@ public void glBindBuffer(final int target, final int buffer) {
public void glBindTexture(final int target, final int texture) {
GL11.glBindTexture(target, texture);
}
+
+ @Override
+ public void glBindImageTexture(final int unit, final int texture, final int level,
+ final boolean layered, final int layer, final int access, final int format) {
+ GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format);
+ }
@Override
public void glBlendEquationSeparate(final int colorMode, final int alphaMode) {
From 2f6a1a220cf1be1a056b2413cc96766a5c168a78 Mon Sep 17 00:00:00 2001
From: codex <103840984+codex128@users.noreply.github.com>
Date: Sun, 24 Nov 2024 19:08:28 -0500
Subject: [PATCH 05/11] reformated glBindImageTexture method
---
jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
index 6721c24ee8..6671587684 100644
--- a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
+++ b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
@@ -83,7 +83,8 @@ public void glBindTexture(final int target, final int texture) {
@Override
public void glBindImageTexture(final int unit, final int texture, final int level,
- final boolean layered, final int layer, final int access, final int format) {
+ final boolean layered, final int layer,
+ final int access, final int format) {
GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format);
}
From 381a2243e37660a511d77c45485aeaf1c56a52c9 Mon Sep 17 00:00:00 2001
From: codex <103840984+codex128@users.noreply.github.com>
Date: Mon, 25 Nov 2024 08:31:09 -0500
Subject: [PATCH 06/11] fixed lwjgl2 gl implementation not overriding
glBindImageTexture
---
.../src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
index 2dcf289584..97a806c3e3 100644
--- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
+++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java
@@ -59,7 +59,14 @@ public void glBindBuffer(int param1, int param2) {
public void glBindTexture(int param1, int param2) {
GL11.glBindTexture(param1, param2);
}
-
+
+ @Override
+ public void glBindImageTexture(final int unit, final int texture, final int level,
+ final boolean layered, final int layer,
+ final int access, final int format) {
+ GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format);
+ }
+
@Override
public void glBlendEquationSeparate(int colorMode, int alphaMode){
GL20.glBlendEquationSeparate(colorMode,alphaMode);
From 819422218f897328574a0864b4464408d631374f Mon Sep 17 00:00:00 2001
From: codex <103840984+codex128@users.noreply.github.com>
Date: Fri, 20 Dec 2024 11:11:59 -0500
Subject: [PATCH 07/11] reverted approach and added TextureImage instead
---
.../main/java/com/jme3/material/Material.java | 15 +-
.../main/java/com/jme3/renderer/Renderer.java | 10 +
.../com/jme3/renderer/opengl/GLRenderer.java | 30 +-
.../com/jme3/renderer/opengl/TextureUtil.java | 4 +-
.../main/java/com/jme3/shader/VarType.java | 21 +-
.../java/com/jme3/system/NullRenderer.java | 7 +
.../src/main/java/com/jme3/texture/Image.java | 126 -------
.../java/com/jme3/texture/TextureImage.java | 308 ++++++++++++++++++
8 files changed, 372 insertions(+), 149 deletions(-)
create mode 100644 jme3-core/src/main/java/com/jme3/texture/TextureImage.java
diff --git a/jme3-core/src/main/java/com/jme3/material/Material.java b/jme3-core/src/main/java/com/jme3/material/Material.java
index 86e8ecca5e..50807db935 100644
--- a/jme3-core/src/main/java/com/jme3/material/Material.java
+++ b/jme3-core/src/main/java/com/jme3/material/Material.java
@@ -50,6 +50,7 @@
import com.jme3.shader.bufferobject.BufferObject;
import com.jme3.texture.Image;
import com.jme3.texture.Texture;
+import com.jme3.texture.TextureImage;
import com.jme3.texture.image.ColorSpace;
import com.jme3.util.ListMap;
import com.jme3.util.SafeArrayList;
@@ -451,7 +452,7 @@ public MatParamTexture getTextureParam(String name) {
}
return null;
}
-
+
/**
* Returns a collection of all parameters set on this material.
*
@@ -514,6 +515,10 @@ public void setParam(String name, VarType type, Object value) {
if (technique != null) {
technique.notifyParamChanged(name, type, value);
}
+ if (type.isImageType()) {
+ // recompute sort id
+ sortingId = -1;
+ }
}
}
@@ -859,9 +864,13 @@ private void updateShaderMaterialParameter(Renderer renderer, VarType type, Shad
Uniform uniform = shader.getUniform(param.getPrefixedName());
if (!override && uniform.isSetByCurrentMaterial()) return;
- if (type.isTextureType()) {
+ if (type.isTextureType() || type.isImageType()) {
try {
- renderer.setTexture(unit.textureUnit, (Texture) param.getValue());
+ if (type.isTextureType()) {
+ renderer.setTexture(unit.textureUnit, (Texture) param.getValue());
+ } else {
+ renderer.setTextureImage(unit.textureUnit, (TextureImage) param.getValue());
+ }
} catch (TextureUnitException exception) {
int numTexParams = unit.textureUnit + 1;
String message = "Too many texture parameters (" + numTexParams + ") assigned\n to " + toString();
diff --git a/jme3-core/src/main/java/com/jme3/renderer/Renderer.java b/jme3-core/src/main/java/com/jme3/renderer/Renderer.java
index c92de923ae..acd0d599e1 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/Renderer.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/Renderer.java
@@ -42,6 +42,7 @@
import com.jme3.texture.FrameBuffer;
import com.jme3.texture.Image;
import com.jme3.texture.Texture;
+import com.jme3.texture.TextureImage;
import com.jme3.util.NativeObject;
import java.nio.ByteBuffer;
import java.util.EnumMap;
@@ -273,6 +274,15 @@ public interface Renderer {
*/
public void setTexture(int unit, Texture tex)
throws TextureUnitException;
+
+ /**
+ * Assigns a TextureImage to the specified texture unit.
+ *
+ * @param unit the index of the texture unit (≥0)
+ * @param tex the texture image to assign
+ * @throws TextureUnitException if the texture unit does not exist
+ */
+ public void setTextureImage(int unit, TextureImage tex) throws TextureUnitException;
/**
* Modifies the given Texture with the given Image.
diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
index 0ad1169546..811bab583c 100644
--- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
+++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
@@ -61,6 +61,7 @@
import com.jme3.texture.Texture2D;
import com.jme3.texture.Texture.ShadowCompareMode;
import com.jme3.texture.Texture.WrapAxis;
+import com.jme3.texture.TextureImage;
import com.jme3.texture.image.LastTextureState;
import com.jme3.util.BufferUtils;
import com.jme3.util.ListMap;
@@ -2549,13 +2550,6 @@ private void bindTextureAndUnit(int target, Image img, int unit) {
}
if (context.boundTextures[unit]==null||context.boundTextures[unit].get() != img.getWeakRef().get()) {
gl.glBindTexture(target, img.getId());
- if (gl4 != null && img.getAccess() != null) {
- // binds the image so that imageStore and imageLoad operations
- // can be used in shaders on the image
- gl4.glBindImageTexture(unit, img.getId(), 0, img.isLayered(),
- Math.max(img.getBindLayer(), 0), img.getAccess().getGlEnum(),
- texUtil.getImageFormat(img.getFormat(), false).internalFormat);
- }
context.boundTextures[unit] = img.getWeakRef();
statistics.onTextureUse(img, true);
} else {
@@ -2578,13 +2572,6 @@ private void bindTextureOnly(int target, Image img, int unit) {
context.boundTextureUnit = unit;
}
gl.glBindTexture(target, img.getId());
- if (gl4 != null && img.getAccess() != null) {
- // binds the image so that imageStore and imageLoad operations
- // can be used in shaders on the image
- gl4.glBindImageTexture(unit, img.getId(), 0, img.isLayered(),
- Math.max(img.getBindLayer(), 0), img.getAccess().getGlEnum(),
- texUtil.getImageFormat(img.getFormat(), false).internalFormat);
- }
context.boundTextures[unit] = img.getWeakRef();
statistics.onTextureUse(img, true);
} else {
@@ -2766,7 +2753,20 @@ public void setTexture(int unit, Texture tex) throws TextureUnitException {
if (tex.getName() != null) glext.glObjectLabel(GL.GL_TEXTURE, tex.getImage().getId(), tex.getName());
}
}
-
+
+ @Override
+ public void setTextureImage(int unit, TextureImage tex) throws TextureUnitException {
+ if (unit < 0 || unit >= RenderContext.maxTextureUnits) {
+ throw new TextureUnitException();
+ }
+ WeakReference- * If not null, the image will be bound in such a way as to allow - * {@code imageStore} and {@code imageLoad} functions to work. Otherwise - * the image will be bound normally. - *
- * default=null - * - * @param access - */ - public void setAccess(Access access) { - if (this.access != access) { - this.access = access; - setUpdateNeeded(); - } - } - - /** - * - * @return - * @see #setAccess(com.jme3.texture.Image.Access) - */ - public Access getAccess() { - return access; - } - - /** - * Sets the bind layer used if {@link #getAccess()} does not - * return null. - *
- * If greater than or equal to zero, only the specified layer will be - * bound. If less than zero, the entire image will be bound. - *
- * default=-1 - * - * @param bindLayer - */ - public void setBindLayer(int bindLayer) { - if (this.bindLayer != bindLayer) { - this.bindLayer = bindLayer; - setUpdateNeeded(); - } - } - - /** - * - * @return - * @see #setBindLayer(int) - */ - public int getBindLayer() { - return bindLayer; - } - - /** - * Returns true if the entire image will be bound in cases where - * {@link #getAccess()} does not return null. - * - * @return - */ - public boolean isLayered() { - return bindLayer < 0; - } - @Override public String toString(){ StringBuilder sb = new StringBuilder(); @@ -1408,8 +1286,6 @@ public void write(JmeExporter e) throws IOException { capsule.write(multiSamples, "multiSamples", 1); capsule.writeByteBufferArrayList(data, "data", null); capsule.write(colorSpace, "colorSpace", null); - capsule.write(access, "access", null); - capsule.write(bindLayer, "bindLayer", -1); } @Override @@ -1423,8 +1299,6 @@ public void read(JmeImporter importer) throws IOException { multiSamples = capsule.readInt("multiSamples", 1); data = capsule.readByteBufferArrayList("data", null); colorSpace = capsule.readEnum("colorSpace", ColorSpace.class, null); - access = capsule.readEnum("access", Access.class, null); - bindLayer = capsule.readInt("bindLayer", -1); if (mipMapSizes != null) { needGeneratedMips = false; mipsWereGenerated = true; diff --git a/jme3-core/src/main/java/com/jme3/texture/TextureImage.java b/jme3-core/src/main/java/com/jme3/texture/TextureImage.java new file mode 100644 index 0000000000..fda8e92f55 --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/texture/TextureImage.java @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2024 jMonkeyEngine + * 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 'jMonkeyEngine' nor the names of its 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 OWNER 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 com.jme3.texture; + +import com.jme3.renderer.opengl.GL2; +import com.jme3.renderer.opengl.GL4; +import com.jme3.renderer.opengl.TextureUtil; +import java.util.Objects; + +/** + * Wraps a texture so that only a single level of the underlying image is bound + * instead of the entire image. + * + * @author codex + */ +public class TextureImage { + + /** + * Enum specifying the shader access hint of the image. + */ + public enum Access { + + /** + * The image can only read from in a shader. + */ + ReadOnly(true, false, GL2.GL_READ_ONLY), + + /** + * The image can written to in a shader. + */ + WriteOnly(false, true, GL2.GL_WRITE_ONLY), + + /** + * The image can both be written to and read from in a shader. + */ + ReadWrite(true, true, GL2.GL_READ_WRITE); + + private final boolean read, write; + private final int glEnum; + + private Access(boolean read, boolean write, int glEnum) { + this.read = read; + this.write = write; + this.glEnum = glEnum; + } + + /** + * If true, the image can be read from in a shader. + * + * @return + */ + public boolean isRead() { + return read; + } + + /** + * If true, the image can be written to in a shader. + * + * @return + */ + public boolean isWrite() { + return write; + } + + /** + * Corresponding OpenGL enum. + * + * @return + */ + public int getGlEnum() { + return glEnum; + } + + } + + private Texture texture; + private int level, layer; + private Access access; + private boolean updateFlag = true; + + public TextureImage(Texture texture) { + this(texture, 0, -1, Access.ReadWrite); + } + public TextureImage(Texture texture, Access access) { + this(texture, 0, -1, access); + } + public TextureImage(Texture texture, int level, int layer) { + this(texture, level, layer, Access.ReadWrite); + } + public TextureImage(Texture texture, int level, int layer, Access access) { + this.texture = Objects.requireNonNull(texture, "Underlying texture cannot be null"); + this.level = level; + this.layer = layer; + this.access = access; + if (this.level < 0) { + throw new IllegalArgumentException("Level cannot be less than zero."); + } + } + + /** + * Binds this texture image to the texture unit. + *
+ * Calling this is not completely sufficient for totally binding an image + * to an image unit. Additionally, the image must be bound beforehand using + * {@link GL2#glBindTexture(int, int)}. + * + * @param gl4 OpenGL4 implementation (not null) + * @param texUtil utility used to convert JME's image format to the corresponding GL enum (not null) + * @param unit texture unit to bind to + */ + public void bindImage(GL4 gl4, TextureUtil texUtil, int unit) { + Image img = texture.getImage(); + gl4.glBindImageTexture(unit, img.getId(), level, isLayered(), Math.max(layer, 0), + access.getGlEnum(), texUtil.getImageFormat(img.getFormat(), false).internalFormat); + } + + /** + * Sets the update flag indicating this texture image needs rebinding. + */ + public void setUpdateNeeded() { + updateFlag = true; + } + + /** + * Clears the update flag and returns the update flag's value before + * it was cleared. + * + * @return + */ + public boolean clearUpdateNeeded() { + boolean f = updateFlag; + updateFlag = false; + return f; + } + + /** + * Sets the underlying texture wrapped by this TextureImage. + * + * @param texture + */ + public void setTexture(Texture texture) { + Objects.requireNonNull(texture, "Wrapped texture cannot be null."); + if (this.texture != texture) { + this.texture = texture; + updateFlag = true; + } + } + + /** + * Sets the image level to bind. + *
+ * The level controls which mipmap level will be bound to the texture unit, + * where zero corresponds to the base level of the texture. + * + * @param level level to bind (cannot be negative) + */ + public void setLevel(int level) { + if (level < 0) { + throw new IllegalArgumentException("Texture image level cannot be negative."); + } + if (this.level != level) { + this.level = level; + updateFlag = true; + } + } + + /** + * Sets the image layer to bind. + *
+ * If the underlying texture is a one/two/three demensional array, + * cube map, cube map array, two demensional multisample array, then this + * specifies which layer of the array to bind. + * + * @param layer layer to bind, or negative to bind all layers + */ + public void setLayer(int layer) { + if (this.layer != layer && (this.layer >= 0 || layer >= 0)) { + this.layer = layer; + updateFlag = true; + } + } + + /** + * Sets the shader access hint with which to bind the image. + * + * @param access + */ + public void setAccess(Access access) { + if (this.access != access) { + this.access = access; + updateFlag = true; + } + } + + /** + * + * @return + * @see #setTexture(com.jme3.texture.Texture) + */ + public Texture getTexture() { + return texture; + } + + /** + * Gets the image belonging to the underlying texture. + * + * @return + */ + public Image getImage() { + return texture.getImage(); + } + + /** + * Gets the format of the image belonging to the underlying texture. + * + * @return + */ + public Image.Format getFormat() { + return texture.getImage().getFormat(); + } + + /** + * Gets the native id of the image belonging to the underlying texture. + * + * @return + */ + public int getImageId() { + return texture.getImage().getId(); + } + + /** + * + * @return + * @see #setLevel(int) + */ + public int getLevel() { + return level; + } + + /** + * + * @return + * @see #setLayer(int) + */ + public int getLayer() { + return layer; + } + + /** + * + * @return + * @see #setAccess(com.jme3.texture.TextureImage.Access) + */ + public Access getAccess() { + return access; + } + + /** + * Returns true if all layers of an image will be bound, when + * {@code layer} is negative. + * + * @return + * @see #setLayer(int) + */ + public boolean isLayered() { + return layer < 0; + } + + /** + * Returns true if the update flag has been set indicating rebinding + * is required. + * + * @return + */ + public boolean isUpdateNeeded() { + return updateFlag; + } + +} From 79c93e0346174094efba6fec3608cdedbfc9e3bf Mon Sep 17 00:00:00 2001 From: codex <103840984+codex128@users.noreply.github.com> Date: Sun, 5 Jan 2025 11:32:37 -0500 Subject: [PATCH 08/11] added test app --- .../jme3test/texture/TestShaderImage.java | 59 +++++++++++++++++++ .../java/com/jme3/renderer/lwjgl/LwjglGL.java | 13 ++-- .../java/com/jme3/renderer/lwjgl/LwjglGL.java | 16 +++-- .../main/resources/Materials/ImageTest.frag | 11 ++++ .../main/resources/Materials/ImageTest.j3md | 20 +++++++ 5 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 jme3-examples/src/main/java/jme3test/texture/TestShaderImage.java create mode 100644 jme3-testdata/src/main/resources/Materials/ImageTest.frag create mode 100644 jme3-testdata/src/main/resources/Materials/ImageTest.j3md diff --git a/jme3-examples/src/main/java/jme3test/texture/TestShaderImage.java b/jme3-examples/src/main/java/jme3test/texture/TestShaderImage.java new file mode 100644 index 0000000000..52f698c99d --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/texture/TestShaderImage.java @@ -0,0 +1,59 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template + */ +package jme3test.texture; + +import com.jme3.app.SimpleApplication; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Box; +import com.jme3.scene.shape.Quad; +import com.jme3.shader.VarType; +import com.jme3.texture.Image; +import com.jme3.texture.Texture2D; +import com.jme3.texture.TextureImage; + +/** + * + * @author codex + */ +public class TestShaderImage extends SimpleApplication { + + private int frame = 0; + + public static void main(String[] args) { + new TestShaderImage().start(); + } + + @Override + public void simpleInitApp() { + + Geometry box = new Geometry("Box", new Box(1, 1, 1)); + Material mat = new Material(assetManager, "Materials/ImageTest.j3md"); + box.setMaterial(mat); + rootNode.attachChild(box); + + int width = context.getFramebufferWidth(); + int height = context.getFramebufferHeight(); + Texture2D target = new Texture2D(width, height, Image.Format.RGBA8); + TextureImage targetImage = new TextureImage(target, TextureImage.Access.WriteOnly); + mat.setParam("TargetImage", VarType.Image2D, targetImage); + + Geometry pic = new Geometry("gui_pic", new Quad(200, 200)); + pic.setLocalTranslation(0, height - 200, 0); + Material picMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + picMat.setTexture("ColorMap", target); + pic.setMaterial(mat); + guiNode.attachChild(pic); + + } + @Override + public void simpleUpdate(float tpf) { + if (frame++ < 5) { + cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y); + } + } + +} diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java index 97a806c3e3..f513bc5bab 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java @@ -60,12 +60,13 @@ public void glBindTexture(int param1, int param2) { GL11.glBindTexture(param1, param2); } - @Override - public void glBindImageTexture(final int unit, final int texture, final int level, - final boolean layered, final int layer, - final int access, final int format) { - GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format); - } +// @Override +// public void glBindImageTexture(final int unit, final int texture, final int level, +// final boolean layered, final int layer, +// final int access, final int format) { +// throw new NullPointerException("lwjgl"); +// //GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format); +// } @Override public void glBlendEquationSeparate(int colorMode, int alphaMode){ diff --git a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java index 6671587684..3205953739 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java @@ -81,13 +81,20 @@ public void glBindTexture(final int target, final int texture) { GL11.glBindTexture(target, texture); } +// @Override +// public void glBindImageTexture(final int unit, final int texture, final int level, +// final boolean layered, final int layer, +// final int access, final int format) { +// throw new NullPointerException("lwjgl3"); +// //GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format); +// } + + @Override - public void glBindImageTexture(final int unit, final int texture, final int level, - final boolean layered, final int layer, - final int access, final int format) { + public void glBindImageTexture(int unit, int texture, int level, boolean layered, int layer, int access, int format) { GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format); } - + @Override public void glBlendEquationSeparate(final int colorMode, final int alphaMode) { GL20.glBlendEquationSeparate(colorMode, alphaMode); @@ -660,4 +667,5 @@ public void glBindBufferBase(final int target, final int index, final int buffer public void glUniformBlockBinding(final int program, final int uniformBlockIndex, final int uniformBlockBinding) { GL31.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); } + } diff --git a/jme3-testdata/src/main/resources/Materials/ImageTest.frag b/jme3-testdata/src/main/resources/Materials/ImageTest.frag new file mode 100644 index 0000000000..5e2339f06a --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/ImageTest.frag @@ -0,0 +1,11 @@ + +#import "Common/ShaderLib/GLSLCompat.glsllib" + +layout(RGBA8) uniform image2D m_TargetImage; + +void main() { + + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + imageStore(m_TargetImage, ivec2(gl_FragCoord.xy), vec4(0.0, 1.0, 0.0, 1.0)); + +} diff --git a/jme3-testdata/src/main/resources/Materials/ImageTest.j3md b/jme3-testdata/src/main/resources/Materials/ImageTest.j3md new file mode 100644 index 0000000000..0e11e66319 --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/ImageTest.j3md @@ -0,0 +1,20 @@ +MaterialDef ImageTest { + + MaterialParameters { + + Image2D TargetImage + + } + + Technique { + + VertexShader GLSL400 GLSL320 GLSL150 : Common/MatDefs/Misc/Unshaded.vert + FragmentShader GLSL400 GLSL320 GLSL150 : Materials/ImageTest.frag + + WorldParameters { + WorldViewProjectionMatrix + } + + } + +} From 2be0bff997cc72acfca3a1b0245364ce91618100 Mon Sep 17 00:00:00 2001 From: codex <103840984+codex128@users.noreply.github.com> Date: Sun, 5 Jan 2025 11:48:40 -0500 Subject: [PATCH 09/11] reverted debugging --- .../main/java/com/jme3/renderer/lwjgl/LwjglGL.java | 13 ++++++------- .../main/java/com/jme3/renderer/lwjgl/LwjglGL.java | 13 +++---------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java index f513bc5bab..97a806c3e3 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java @@ -60,13 +60,12 @@ public void glBindTexture(int param1, int param2) { GL11.glBindTexture(param1, param2); } -// @Override -// public void glBindImageTexture(final int unit, final int texture, final int level, -// final boolean layered, final int layer, -// final int access, final int format) { -// throw new NullPointerException("lwjgl"); -// //GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format); -// } + @Override + public void glBindImageTexture(final int unit, final int texture, final int level, + final boolean layered, final int layer, + final int access, final int format) { + GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format); + } @Override public void glBlendEquationSeparate(int colorMode, int alphaMode){ diff --git a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java index 3205953739..d2c607d747 100644 --- a/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java +++ b/jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java @@ -81,17 +81,10 @@ public void glBindTexture(final int target, final int texture) { GL11.glBindTexture(target, texture); } -// @Override -// public void glBindImageTexture(final int unit, final int texture, final int level, -// final boolean layered, final int layer, -// final int access, final int format) { -// throw new NullPointerException("lwjgl3"); -// //GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format); -// } - - @Override - public void glBindImageTexture(int unit, int texture, int level, boolean layered, int layer, int access, int format) { + public void glBindImageTexture(final int unit, final int texture, final int level, + final boolean layered, final int layer, + final int access, final int format) { GL42.glBindImageTexture(unit, texture, level, layered, layer, access, format); } From 5198ead91dff9065f40d929ccdd6df8e5430569a Mon Sep 17 00:00:00 2001 From: codex <103840984+codex128@users.noreply.github.com> Date: Mon, 6 Jan 2025 12:23:54 -0500 Subject: [PATCH 10/11] fixed formatting and javadoc --- .../main/java/com/jme3/texture/TextureImage.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/texture/TextureImage.java b/jme3-core/src/main/java/com/jme3/texture/TextureImage.java index fda8e92f55..d05b065231 100644 --- a/jme3-core/src/main/java/com/jme3/texture/TextureImage.java +++ b/jme3-core/src/main/java/com/jme3/texture/TextureImage.java @@ -46,6 +46,8 @@ public class TextureImage { /** * Enum specifying the shader access hint of the image. + *
+ * Shader accesses that violate the hint may result in undefined behavior. */ public enum Access { @@ -110,12 +112,15 @@ public int getGlEnum() { public TextureImage(Texture texture) { this(texture, 0, -1, Access.ReadWrite); } + public TextureImage(Texture texture, Access access) { this(texture, 0, -1, access); } + public TextureImage(Texture texture, int level, int layer) { this(texture, level, layer, Access.ReadWrite); } + public TextureImage(Texture texture, int level, int layer, Access access) { this.texture = Objects.requireNonNull(texture, "Underlying texture cannot be null"); this.level = level; @@ -133,7 +138,7 @@ public TextureImage(Texture texture, int level, int layer, Access access) { * to an image unit. Additionally, the image must be bound beforehand using * {@link GL2#glBindTexture(int, int)}. * - * @param gl4 OpenGL4 implementation (not null) + * @param gl4 GL4 implementation (not null) * @param texUtil utility used to convert JME's image format to the corresponding GL enum (not null) * @param unit texture unit to bind to */ @@ -165,7 +170,7 @@ public boolean clearUpdateNeeded() { /** * Sets the underlying texture wrapped by this TextureImage. * - * @param texture + * @param texture wrapped texture (not null) */ public void setTexture(Texture texture) { Objects.requireNonNull(texture, "Wrapped texture cannot be null."); @@ -180,8 +185,10 @@ public void setTexture(Texture texture) { *
* The level controls which mipmap level will be bound to the texture unit, * where zero corresponds to the base level of the texture. + *
+ * default=0 * - * @param level level to bind (cannot be negative) + * @param level level to bind (not negative) */ public void setLevel(int level) { if (level < 0) { @@ -199,6 +206,8 @@ public void setLevel(int level) { * If the underlying texture is a one/two/three demensional array, * cube map, cube map array, two demensional multisample array, then this * specifies which layer of the array to bind. + *
+ * default=-1 * * @param layer layer to bind, or negative to bind all layers */ From d8b63d5610befe644e28274774bd58408bd76a28 Mon Sep 17 00:00:00 2001 From: codex <103840984+codex128@users.noreply.github.com> Date: Mon, 6 Jan 2025 12:29:45 -0500 Subject: [PATCH 11/11] fixed typos and added javadoc --- .../main/java/com/jme3/texture/TextureImage.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/texture/TextureImage.java b/jme3-core/src/main/java/com/jme3/texture/TextureImage.java index d05b065231..31b705fa5d 100644 --- a/jme3-core/src/main/java/com/jme3/texture/TextureImage.java +++ b/jme3-core/src/main/java/com/jme3/texture/TextureImage.java @@ -52,12 +52,12 @@ public class TextureImage { public enum Access { /** - * The image can only read from in a shader. + * The image can only be read from in a shader. */ ReadOnly(true, false, GL2.GL_READ_ONLY), /** - * The image can written to in a shader. + * The image can only be written to in a shader. */ WriteOnly(false, true, GL2.GL_WRITE_ONLY), @@ -204,8 +204,8 @@ public void setLevel(int level) { * Sets the image layer to bind. *
* If the underlying texture is a one/two/three demensional array, - * cube map, cube map array, two demensional multisample array, then this - * specifies which layer of the array to bind. + * cube map, cube map array, or two demensional multisample array, + * then this value specifies which layer of the array to bind. *
* default=-1 * @@ -231,9 +231,9 @@ public void setAccess(Access access) { } /** + * Gets the underlying texture wrapped by this TextureImage. * - * @return - * @see #setTexture(com.jme3.texture.Texture) + * @return underlying texture */ public Texture getTexture() { return texture; @@ -267,6 +267,7 @@ public int getImageId() { } /** + * Gets the level. * * @return * @see #setLevel(int) @@ -276,6 +277,7 @@ public int getLevel() { } /** + * Gets the layer. * * @return * @see #setLayer(int) @@ -285,6 +287,7 @@ public int getLayer() { } /** + * Gets the access hint. * * @return * @see #setAccess(com.jme3.texture.TextureImage.Access)