Skip to content

Commit 662b4ea

Browse files
authored
Merge pull request #2331 from codex128/imageShaderMod
Enables images to be read and modified per pixel in shader
2 parents 6e125d9 + d8b63d5 commit 662b4ea

File tree

15 files changed

+510
-12
lines changed

15 files changed

+510
-12
lines changed

jme3-core/src/main/java/com/jme3/material/Material.java

+12-3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import com.jme3.shader.bufferobject.BufferObject;
5151
import com.jme3.texture.Image;
5252
import com.jme3.texture.Texture;
53+
import com.jme3.texture.TextureImage;
5354
import com.jme3.texture.image.ColorSpace;
5455
import com.jme3.util.ListMap;
5556
import com.jme3.util.SafeArrayList;
@@ -451,7 +452,7 @@ public MatParamTexture getTextureParam(String name) {
451452
}
452453
return null;
453454
}
454-
455+
455456
/**
456457
* Returns a collection of all parameters set on this material.
457458
*
@@ -514,6 +515,10 @@ public void setParam(String name, VarType type, Object value) {
514515
if (technique != null) {
515516
technique.notifyParamChanged(name, type, value);
516517
}
518+
if (type.isImageType()) {
519+
// recompute sort id
520+
sortingId = -1;
521+
}
517522
}
518523
}
519524

@@ -859,9 +864,13 @@ private void updateShaderMaterialParameter(Renderer renderer, VarType type, Shad
859864
Uniform uniform = shader.getUniform(param.getPrefixedName());
860865
if (!override && uniform.isSetByCurrentMaterial()) return;
861866

862-
if (type.isTextureType()) {
867+
if (type.isTextureType() || type.isImageType()) {
863868
try {
864-
renderer.setTexture(unit.textureUnit, (Texture) param.getValue());
869+
if (type.isTextureType()) {
870+
renderer.setTexture(unit.textureUnit, (Texture) param.getValue());
871+
} else {
872+
renderer.setTextureImage(unit.textureUnit, (TextureImage) param.getValue());
873+
}
865874
} catch (TextureUnitException exception) {
866875
int numTexParams = unit.textureUnit + 1;
867876
String message = "Too many texture parameters (" + numTexParams + ") assigned\n to " + toString();

jme3-core/src/main/java/com/jme3/renderer/Renderer.java

+10
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import com.jme3.texture.FrameBuffer;
4343
import com.jme3.texture.Image;
4444
import com.jme3.texture.Texture;
45+
import com.jme3.texture.TextureImage;
4546
import com.jme3.util.NativeObject;
4647
import java.nio.ByteBuffer;
4748
import java.util.EnumMap;
@@ -273,6 +274,15 @@ public interface Renderer {
273274
*/
274275
public void setTexture(int unit, Texture tex)
275276
throws TextureUnitException;
277+
278+
/**
279+
* Assigns a TextureImage to the specified texture unit.
280+
*
281+
* @param unit the index of the texture unit (≥0)
282+
* @param tex the texture image to assign
283+
* @throws TextureUnitException if the texture unit does not exist
284+
*/
285+
public void setTextureImage(int unit, TextureImage tex) throws TextureUnitException;
276286

277287
/**
278288
* Modifies the given Texture with the given Image.

jme3-core/src/main/java/com/jme3/renderer/opengl/GL2.java

+4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ public interface GL2 extends GL {
7474
public static final int GL_TEXTURE_WRAP_R = 0x8072;
7575
public static final int GL_VERTEX_PROGRAM_POINT_SIZE = 0x8642;
7676
public static final int GL_UNSIGNED_INT_8_8_8_8 = 0x8035;
77+
78+
public static final int GL_READ_ONLY = 35000;
79+
public static final int GL_WRITE_ONLY = 35001;
80+
public static final int GL_READ_WRITE = 35002;
7781

7882
/**
7983
* <p><a target="_blank" href="http://docs.gl/gl3/glAlphaFunc">Reference Page</a> - <em>This function is deprecated and unavailable in the Core profile</em></p>

jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java

+15
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,19 @@ public interface GL4 extends GL3 {
100100
* @param storageBlockBinding The index storage block binding to associate with the specified storage block.
101101
*/
102102
public void glShaderStorageBlockBinding(int program, int storageBlockIndex, int storageBlockBinding);
103+
104+
/**
105+
* Binds a single level of a texture to an image unit for the purpose of reading
106+
* and writing it from shaders.
107+
*
108+
* @param unit image unit to bind to
109+
* @param texture texture to bind to the image unit
110+
* @param level level of the texture to bind
111+
* @param layered true to bind all array elements
112+
* @param layer if not layered, the layer to bind
113+
* @param access access types that may be performed
114+
* @param format format to use when performing formatted stores
115+
*/
116+
public void glBindImageTexture(int unit, int texture, int level, boolean layered, int layer, int access, int format);
117+
103118
}

jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

+15-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
import com.jme3.texture.Texture2D;
6262
import com.jme3.texture.Texture.ShadowCompareMode;
6363
import com.jme3.texture.Texture.WrapAxis;
64+
import com.jme3.texture.TextureImage;
6465
import com.jme3.texture.image.LastTextureState;
6566
import com.jme3.util.BufferUtils;
6667
import com.jme3.util.ListMap;
@@ -2752,7 +2753,20 @@ public void setTexture(int unit, Texture tex) throws TextureUnitException {
27522753
if (tex.getName() != null) glext.glObjectLabel(GL.GL_TEXTURE, tex.getImage().getId(), tex.getName());
27532754
}
27542755
}
2755-
2756+
2757+
@Override
2758+
public void setTextureImage(int unit, TextureImage tex) throws TextureUnitException {
2759+
if (unit < 0 || unit >= RenderContext.maxTextureUnits) {
2760+
throw new TextureUnitException();
2761+
}
2762+
WeakReference<Image> ref = context.boundTextures[unit];
2763+
boolean bindRequired = tex.clearUpdateNeeded() || ref == null || ref.get() != tex.getImage().getWeakRef().get();
2764+
setTexture(unit, tex.getTexture());
2765+
if (gl4 != null && bindRequired) {
2766+
tex.bindImage(gl4, texUtil, unit);
2767+
}
2768+
}
2769+
27562770
@Override
27572771
public void setUniformBufferObject(int bindingPoint, BufferObject bufferObject) {
27582772
if (bufferObject.isUpdateNeeded()) {

jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2021 jMonkeyEngine
2+
* Copyright (c) 2009-2024 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@
4646
*
4747
* @author Kirill Vainer
4848
*/
49-
final class TextureUtil {
49+
public final class TextureUtil {
5050

5151
private static final Logger logger = Logger.getLogger(TextureUtil.class.getName());
5252

jme3-core/src/main/java/com/jme3/shader/VarType.java

+18-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@
4343
import com.jme3.texture.Texture3D;
4444
import com.jme3.texture.TextureArray;
4545
import com.jme3.texture.TextureCubeMap;
46+
import com.jme3.texture.TextureImage;
4647

4748
public enum VarType {
48-
49+
4950
Float("float", float.class, Float.class),
5051
Vector2("vec2", Vector2f.class),
5152
Vector3("vec3", Vector3f.class),
@@ -56,7 +57,8 @@ public enum VarType {
5657
Vector2Array(true, false, "vec2", Vector2f[].class),
5758
Vector3Array(true, false, "vec3", Vector3f[].class),
5859
Vector4Array(true, false, "vec4", Vector4f[].class),
59-
60+
61+
Int("int", int.class, Integer.class),
6062
Boolean("bool", Boolean.class, boolean.class),
6163

6264
Matrix3(true, false, "mat3", Matrix3f.class),
@@ -70,12 +72,16 @@ public enum VarType {
7072
Texture3D(false, true, "sampler3D", Texture3D.class, Texture.class),
7173
TextureArray(false, true, "sampler2DArray|sampler2DArrayShadow", TextureArray.class, Texture.class),
7274
TextureCubeMap(false, true, "samplerCube", TextureCubeMap.class, Texture.class),
73-
Int("int", int.class, Integer.class),
75+
76+
Image2D(false, false, true, "image2D", TextureImage.class),
77+
Image3D(false, false, true, "image3D", TextureImage.class),
78+
7479
UniformBufferObject(false, false, "custom", BufferObject.class),
7580
ShaderStorageBufferObject(false, false, "custom", BufferObject.class);
7681

7782
private boolean usesMultiData = false;
7883
private boolean textureType = false;
84+
private boolean imageType = false;
7985
private final String glslType;
8086
private Class<?>[] javaTypes;
8187

@@ -98,6 +104,11 @@ public enum VarType {
98104
this.javaTypes = new Class<?>[0];
99105
}
100106
}
107+
108+
VarType(boolean multiData, boolean textureType, boolean imageType, String glslType, Class<?>... javaTypes) {
109+
this(multiData, textureType, glslType, javaTypes);
110+
this.imageType = imageType;
111+
}
101112

102113
/**
103114
* Check if the passed object is of a type mapped to this VarType
@@ -126,6 +137,10 @@ public Class<?>[] getJavaType() {
126137
public boolean isTextureType() {
127138
return textureType;
128139
}
140+
141+
public boolean isImageType() {
142+
return imageType;
143+
}
129144

130145
public boolean usesMultiData() {
131146
return usesMultiData;

jme3-core/src/main/java/com/jme3/system/NullRenderer.java

+7
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import com.jme3.texture.FrameBuffer;
4949
import com.jme3.texture.Image;
5050
import com.jme3.texture.Texture;
51+
import com.jme3.texture.TextureImage;
5152

5253
import java.nio.ByteBuffer;
5354
import java.util.EnumMap;
@@ -170,6 +171,11 @@ public void deleteFrameBuffer(FrameBuffer fb) {
170171
public void setTexture(int unit, Texture tex) throws TextureUnitException {
171172
// do nothing
172173
}
174+
175+
@Override
176+
public void setTextureImage(int unit, TextureImage tex) throws TextureUnitException {
177+
// do nothing
178+
}
173179

174180
@Override
175181
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
@@ -314,4 +320,5 @@ public void setShaderStorageBufferObject(int bindingPoint, BufferObject bufferOb
314320
public void setUniformBufferObject(int bindingPoint, BufferObject bufferObject) {
315321

316322
}
323+
317324
}

jme3-core/src/main/java/com/jme3/texture/Image.java

-1
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,6 @@ public void read(JmeImporter importer) throws IOException {
12991299
multiSamples = capsule.readInt("multiSamples", 1);
13001300
data = capsule.readByteBufferArrayList("data", null);
13011301
colorSpace = capsule.readEnum("colorSpace", ColorSpace.class, null);
1302-
13031302
if (mipMapSizes != null) {
13041303
needGeneratedMips = false;
13051304
mipsWereGenerated = true;

0 commit comments

Comments
 (0)