Improve support for subimage copying. Allow to copy a part of an image to a texture2D.

fix-openal-soft-deadlink
Riccardo Balbo 5 years ago committed by Riccardo Balbo
parent d935347bde
commit b07a11c9d4
  1. 7
      jme3-core/src/main/java/com/jme3/renderer/Caps.java
  2. 1
      jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java
  3. 31
      jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java
  4. 65
      jme3-core/src/main/java/com/jme3/renderer/opengl/TextureUtil.java

@ -438,10 +438,11 @@ public enum Caps {
/**
* Explicit support of depth 24 textures
*/
Depth24;
Depth24,
UnpackRowLength
;
/**
* Returns true if given the renderer capabilities, the texture

@ -194,6 +194,7 @@ public interface GL {
public static final int GL_VERSION = 0x1F02;
public static final int GL_VERTEX_SHADER = 0x8B31;
public static final int GL_ZERO = 0x0;
public static final int GL_UNPACK_ROW_LENGTH = 0x0CF2;
public void resetStats();

@ -52,6 +52,7 @@ import com.jme3.texture.FrameBuffer;
import com.jme3.texture.FrameBuffer.RenderBuffer;
import com.jme3.texture.Image;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture2D;
import com.jme3.texture.Texture.ShadowCompareMode;
import com.jme3.texture.Texture.WrapAxis;
import com.jme3.texture.image.LastTextureState;
@ -528,6 +529,10 @@ public final class GLRenderer implements Renderer {
if (hasExtension("GL_OES_tessellation_shader") || hasExtension("GL_EXT_tessellation_shader")) {
caps.add(Caps.TesselationShader);
}
if(caps.contains(Caps.OpenGL20)){
caps.add(Caps.UnpackRowLength);
}
// Print context information
logger.log(Level.INFO, "OpenGL Renderer Information\n" +
@ -2537,12 +2542,34 @@ public final class GLRenderer implements Renderer {
setupTextureParams(unit, tex);
}
/**
* @deprecated Use modifyTexture(Texture2D dest, Image src, int destX, int destY, int srcX, int srcY, int areaW, int areaH)
*/
@Deprecated
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
setTexture(0, tex);
int target = convertTextureType(tex.getType(), pixels.getMultiSamples(), -1);
texUtil.uploadSubTexture(pixels, target, 0, x, y, linearizeSrgbImages);
texUtil.uploadSubTexture(target,pixels, 0, x, y,0,0,pixels.getWidth(),pixels.getHeight(), linearizeSrgbImages);
}
/**
* Copy a part of an image to a texture 2d.
* @param dest The destination image, where the source will be copied
* @param src The source image that contains the data to copy
* @param destX First pixel of the destination image from where the src image will be drawn (x component)
* @param destY First pixel of the destination image from where the src image will be drawn (y component)
* @param srcX First pixel to copy (x component)
* @param srcY First pixel to copy (y component)
* @param areaW Width of the area to copy
* @param areaH Height of the area to copy
*/
public void modifyTexture(Texture2D dest, Image src, int destX, int destY, int srcX, int srcY, int areaW, int areaH) {
setTexture(0, dest);
int target = convertTextureType(dest.getType(), src.getMultiSamples(), -1);
texUtil.uploadSubTexture(target, src, 0, destX, destY, srcX, srcY, areaW, areaH, linearizeSrgbImages);
}
public void deleteImage(Image image) {
int texId = image.getId();
if (texId != -1) {

@ -54,6 +54,7 @@ final class TextureUtil {
private final GL2 gl2;
private final GLExt glext;
private GLImageFormat[][] formats;
private boolean supportUnpackRowLength;
public TextureUtil(GL gl, GL2 gl2, GLExt glext) {
this.gl = gl;
@ -62,6 +63,7 @@ final class TextureUtil {
}
public void initialize(EnumSet<Caps> caps) {
supportUnpackRowLength = caps.contains(Caps.UnpackRowLength);
this.formats = GLImageFormats.getFormatsForCaps(caps);
if (logger.isLoggable(Level.FINE)) {
StringBuilder sb = new StringBuilder();
@ -298,6 +300,10 @@ final class TextureUtil {
}
}
/**
* @deprecated Use uploadSubTexture(int target, Image src, int index,int targetX, int targetY,int srcX,int srcY, int areaWidth,int areaHeight, boolean linearizeSrgb)
*/
@Deprecated
public void uploadSubTexture(Image image, int target, int index, int x, int y, boolean linearizeSrgb) {
if (target != GL.GL_TEXTURE_2D || image.getDepth() > 1) {
throw new UnsupportedOperationException("Updating non-2D texture is not supported");
@ -338,4 +344,63 @@ final class TextureUtil {
gl.glTexSubImage2D(target, 0, x, y, image.getWidth(), image.getHeight(),
oglFormat.format, oglFormat.dataType, data);
}
public void uploadSubTexture(int target, Image src, int index, int targetX, int targetY, int areaX, int areaY, int areaWidth, int areaHeight, boolean linearizeSrgb) {
if (target != GL.GL_TEXTURE_2D || src.getDepth() > 1) {
throw new UnsupportedOperationException("Updating non-2D texture is not supported");
}
if (src.getMipMapSizes() != null) {
throw new UnsupportedOperationException("Updating mip-mappped images is not supported");
}
if (src.getMultiSamples() > 1) {
throw new UnsupportedOperationException("Updating multisampled images is not supported");
}
Image.Format jmeFormat = src.getFormat();
if (jmeFormat.isCompressed()) {
throw new UnsupportedOperationException("Updating compressed images is not supported");
} else if (jmeFormat.isDepthFormat()) {
throw new UnsupportedOperationException("Updating depth images is not supported");
}
boolean getSrgbFormat = src.getColorSpace() == ColorSpace.sRGB && linearizeSrgb;
GLImageFormat oglFormat = getImageFormatWithError(jmeFormat, getSrgbFormat);
ByteBuffer data = src.getData(index);
if (data == null) {
throw new IndexOutOfBoundsException("The image index " + index + " is not valid for the given image");
}
int Bpp = src.getFormat().getBitsPerPixel() / 8;
int srcWidth = src.getWidth();
int cpos = data.position();
int skip = areaX;
skip += areaY * srcWidth;
skip *= Bpp;
data.position(skip);
boolean needsStride = srcWidth != areaWidth;
if (needsStride && (!supportUnpackRowLength)) { // doesn't support stride, copy row by row (slower).
for (int i = 0; i < areaHeight; i++) {
data.position(skip + (srcWidth * Bpp * i));
gl.glTexSubImage2D(target, 0, targetX, targetY + i, areaWidth, 1, oglFormat.format, oglFormat.dataType, data);
}
} else {
if (needsStride)
gl2.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, srcWidth);
gl.glTexSubImage2D(target, 0, targetX, targetY, areaWidth, areaHeight, oglFormat.format, oglFormat.dataType, data);
if (needsStride)
gl2.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0);
}
data.position(cpos);
}
}

Loading…
Cancel
Save