Added support to upload/modify sub texture to Renderer interface introducing a new method:
public void modifyTexture(Texture tex, Image pixels, int x, int y); Implementations added for LWJGL and JOGL. LWJGL seems to work. JOGL is untestet. Android implementation needs to be done by someone else (but is already prepared for). git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10462 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
ee4834d9dc
commit
23c1fddf8f
@ -1603,6 +1603,11 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
setupTextureParams(tex);
|
setupTextureParams(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
|
||||||
|
setTexture(0, tex);
|
||||||
|
TextureUtil.uploadSubTexture(pixels, convertTextureType(tex.getType()), 0, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
public void clearTextureUnits() {
|
public void clearTextureUnits() {
|
||||||
IDList textureList = context.textureIndexList;
|
IDList textureList = context.textureIndexList;
|
||||||
Image[] textures = context.boundTextures;
|
Image[] textures = context.boundTextures;
|
||||||
|
@ -401,4 +401,23 @@ public class TextureUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the texture currently bound to target at with data from the given Image at position x and y. The parameter
|
||||||
|
* index is used as the zoffset in case a 3d texture or texture 2d array is being updated.
|
||||||
|
*
|
||||||
|
* @param image Image with the source data (this data will be put into the texture)
|
||||||
|
* @param target the target texture
|
||||||
|
* @param index the mipmap level to update
|
||||||
|
* @param x the x position where to put the image in the texture
|
||||||
|
* @param y the y position where to put the image in the texture
|
||||||
|
*/
|
||||||
|
public static void uploadSubTexture(
|
||||||
|
Image image,
|
||||||
|
int target,
|
||||||
|
int index,
|
||||||
|
int x,
|
||||||
|
int y) {
|
||||||
|
// FIXME and implement this!
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -238,6 +238,16 @@ public interface Renderer {
|
|||||||
*/
|
*/
|
||||||
public void setTexture(int unit, Texture tex);
|
public void setTexture(int unit, Texture tex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modify the given Texture tex with the given Image. The image will be put at x and y into the texture.
|
||||||
|
*
|
||||||
|
* @param tex the Texture that will be modified
|
||||||
|
* @param pixels the source Image data to copy data from
|
||||||
|
* @param x the x position to put the image into the texture
|
||||||
|
* @param y the y position to put the image into the texture
|
||||||
|
*/
|
||||||
|
public void modifyTexture(Texture tex, Image pixels, int x, int y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a texture from the GPU.
|
* Deletes a texture from the GPU.
|
||||||
*/
|
*/
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.system;
|
package com.jme3.system;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
import com.jme3.light.LightList;
|
import com.jme3.light.LightList;
|
||||||
import com.jme3.material.RenderState;
|
import com.jme3.material.RenderState;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
@ -45,8 +48,6 @@ import com.jme3.shader.Shader.ShaderSource;
|
|||||||
import com.jme3.texture.FrameBuffer;
|
import com.jme3.texture.FrameBuffer;
|
||||||
import com.jme3.texture.Image;
|
import com.jme3.texture.Image;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
|
|
||||||
public class NullRenderer implements Renderer {
|
public class NullRenderer implements Renderer {
|
||||||
|
|
||||||
@ -127,6 +128,9 @@ public class NullRenderer implements Renderer {
|
|||||||
public void setTexture(int unit, Texture tex) {
|
public void setTexture(int unit, Texture tex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
|
||||||
|
}
|
||||||
|
|
||||||
public void updateBufferData(VertexBuffer vb) {
|
public void updateBufferData(VertexBuffer vb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,33 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.renderer.jogl;
|
package com.jme3.renderer.jogl;
|
||||||
|
|
||||||
import com.jme3.light.*;
|
import java.nio.Buffer;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.media.opengl.GL;
|
||||||
|
import javax.media.opengl.GL2;
|
||||||
|
import javax.media.opengl.GL2ES1;
|
||||||
|
import javax.media.opengl.GL2ES2;
|
||||||
|
import javax.media.opengl.GL2GL3;
|
||||||
|
import javax.media.opengl.GLContext;
|
||||||
|
import javax.media.opengl.fixedfunc.GLLightingFunc;
|
||||||
|
import javax.media.opengl.fixedfunc.GLMatrixFunc;
|
||||||
|
import javax.media.opengl.fixedfunc.GLPointerFunc;
|
||||||
|
|
||||||
|
import jme3tools.converters.MipMapGenerator;
|
||||||
|
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
|
import com.jme3.light.Light;
|
||||||
|
import com.jme3.light.LightList;
|
||||||
|
import com.jme3.light.PointLight;
|
||||||
|
import com.jme3.light.SpotLight;
|
||||||
import com.jme3.material.FixedFuncBinding;
|
import com.jme3.material.FixedFuncBinding;
|
||||||
import com.jme3.material.RenderState;
|
import com.jme3.material.RenderState;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
@ -56,16 +82,6 @@ import com.jme3.texture.Texture;
|
|||||||
import com.jme3.texture.Texture.WrapAxis;
|
import com.jme3.texture.Texture.WrapAxis;
|
||||||
import com.jme3.util.BufferUtils;
|
import com.jme3.util.BufferUtils;
|
||||||
import com.jme3.util.NativeObjectManager;
|
import com.jme3.util.NativeObjectManager;
|
||||||
import java.nio.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.media.opengl.*;
|
|
||||||
import javax.media.opengl.fixedfunc.GLLightingFunc;
|
|
||||||
import javax.media.opengl.fixedfunc.GLMatrixFunc;
|
|
||||||
import javax.media.opengl.fixedfunc.GLPointerFunc;
|
|
||||||
import jme3tools.converters.MipMapGenerator;
|
|
||||||
|
|
||||||
public class JoglGL1Renderer implements GL1Renderer {
|
public class JoglGL1Renderer implements GL1Renderer {
|
||||||
|
|
||||||
@ -886,6 +902,11 @@ public class JoglGL1Renderer implements GL1Renderer {
|
|||||||
setupTextureParams(tex);
|
setupTextureParams(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
|
||||||
|
setTexture(0, tex);
|
||||||
|
TextureUtil.uploadSubTexture(pixels, convertTextureType(tex.getType()), 0, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
private void clearTextureUnits() {
|
private void clearTextureUnits() {
|
||||||
Image[] textures = context.boundTextures;
|
Image[] textures = context.boundTextures;
|
||||||
if (textures[0] != null) {
|
if (textures[0] != null) {
|
||||||
|
@ -31,6 +31,25 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.renderer.jogl;
|
package com.jme3.renderer.jogl;
|
||||||
|
|
||||||
|
import java.nio.Buffer;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.media.opengl.GL;
|
||||||
|
import javax.media.opengl.GL2;
|
||||||
|
import javax.media.opengl.GL2ES1;
|
||||||
|
import javax.media.opengl.GL2ES2;
|
||||||
|
import javax.media.opengl.GL2GL3;
|
||||||
|
import javax.media.opengl.GLContext;
|
||||||
|
|
||||||
|
import jme3tools.converters.MipMapGenerator;
|
||||||
|
import jme3tools.shader.ShaderDebug;
|
||||||
|
|
||||||
import com.jme3.light.LightList;
|
import com.jme3.light.LightList;
|
||||||
import com.jme3.material.RenderState;
|
import com.jme3.material.RenderState;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
@ -64,20 +83,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
import com.jme3.util.ListMap;
|
import com.jme3.util.ListMap;
|
||||||
import com.jme3.util.NativeObjectManager;
|
import com.jme3.util.NativeObjectManager;
|
||||||
import com.jme3.util.SafeArrayList;
|
import com.jme3.util.SafeArrayList;
|
||||||
import java.nio.*;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.media.nativewindow.NativeWindowFactory;
|
import javax.media.nativewindow.NativeWindowFactory;
|
||||||
import javax.media.opengl.GL;
|
|
||||||
import javax.media.opengl.GL2;
|
|
||||||
import javax.media.opengl.GL2ES1;
|
|
||||||
import javax.media.opengl.GL2ES2;
|
|
||||||
import javax.media.opengl.GL2GL3;
|
|
||||||
import javax.media.opengl.GLContext;
|
|
||||||
import jme3tools.converters.MipMapGenerator;
|
|
||||||
import jme3tools.shader.ShaderDebug;
|
|
||||||
|
|
||||||
public class JoglRenderer implements Renderer {
|
public class JoglRenderer implements Renderer {
|
||||||
|
|
||||||
@ -2043,6 +2049,11 @@ public class JoglRenderer implements Renderer {
|
|||||||
setupTextureParams(tex);
|
setupTextureParams(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
|
||||||
|
setTexture(0, tex);
|
||||||
|
TextureUtil.uploadSubTexture(pixels, convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), -1), 0, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
public void clearTextureUnits() {
|
public void clearTextureUnits() {
|
||||||
/*GL gl = GLContext.getCurrentGL();
|
/*GL gl = GLContext.getCurrentGL();
|
||||||
IDList textureList = context.textureIndexList;
|
IDList textureList = context.textureIndexList;
|
||||||
|
@ -32,16 +32,18 @@
|
|||||||
|
|
||||||
package com.jme3.renderer.jogl;
|
package com.jme3.renderer.jogl;
|
||||||
|
|
||||||
import com.jme3.renderer.RendererException;
|
|
||||||
import com.jme3.texture.Image;
|
|
||||||
import com.jme3.texture.Image.Format;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import javax.media.opengl.GL;
|
import javax.media.opengl.GL;
|
||||||
import javax.media.opengl.GL2;
|
import javax.media.opengl.GL2;
|
||||||
import javax.media.opengl.GL2ES2;
|
import javax.media.opengl.GL2ES2;
|
||||||
import javax.media.opengl.GL2GL3;
|
import javax.media.opengl.GL2GL3;
|
||||||
import javax.media.opengl.GLContext;
|
import javax.media.opengl.GLContext;
|
||||||
|
|
||||||
|
import com.jme3.renderer.RendererException;
|
||||||
|
import com.jme3.texture.Image;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
|
||||||
public class TextureUtil {
|
public class TextureUtil {
|
||||||
|
|
||||||
private static boolean abgrToRgbaConversionEnabled = false;
|
private static boolean abgrToRgbaConversionEnabled = false;
|
||||||
@ -409,4 +411,94 @@ public class TextureUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the texture currently bound to target at with data from the given Image at position x and y. The parameter
|
||||||
|
* index is used as the zoffset in case a 3d texture or texture 2d array is being updated.
|
||||||
|
*
|
||||||
|
* @param image Image with the source data (this data will be put into the texture)
|
||||||
|
* @param target the target texture
|
||||||
|
* @param index the mipmap level to update
|
||||||
|
* @param x the x position where to put the image in the texture
|
||||||
|
* @param y the y position where to put the image in the texture
|
||||||
|
*/
|
||||||
|
public static void uploadSubTexture(
|
||||||
|
Image image,
|
||||||
|
int target,
|
||||||
|
int index,
|
||||||
|
int x,
|
||||||
|
int y) {
|
||||||
|
GL gl = GLContext.getCurrentGL();
|
||||||
|
Image.Format fmt = image.getFormat();
|
||||||
|
GLImageFormat glFmt = getImageFormatWithError(fmt);
|
||||||
|
|
||||||
|
ByteBuffer data = null;
|
||||||
|
if (index >= 0 && image.getData() != null && image.getData().size() > 0) {
|
||||||
|
data = image.getData(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = image.getWidth();
|
||||||
|
int height = image.getHeight();
|
||||||
|
int depth = image.getDepth();
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] mipSizes = image.getMipMapSizes();
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
// TODO: Remove unneccessary allocation
|
||||||
|
if (mipSizes == null){
|
||||||
|
if (data != null) {
|
||||||
|
mipSizes = new int[]{ data.capacity() };
|
||||||
|
} else {
|
||||||
|
mipSizes = new int[]{ width * height * fmt.getBitsPerPixel() / 8 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int samples = image.getMultiSamples();
|
||||||
|
|
||||||
|
for (int i = 0; i < mipSizes.length; i++){
|
||||||
|
int mipWidth = Math.max(1, width >> i);
|
||||||
|
int mipHeight = Math.max(1, height >> i);
|
||||||
|
int mipDepth = Math.max(1, depth >> i);
|
||||||
|
|
||||||
|
if (data != null){
|
||||||
|
data.position(pos);
|
||||||
|
data.limit(pos + mipSizes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// to remove the cumbersome if/then/else stuff below we'll update the pos right here and use continue after each
|
||||||
|
// gl*Image call in an attempt to unclutter things a bit
|
||||||
|
pos += mipSizes[i];
|
||||||
|
|
||||||
|
int glFmtInternal = glFmt.internalFormat;
|
||||||
|
int glFmtFormat = glFmt.format;
|
||||||
|
int glFmtDataType = glFmt.dataType;
|
||||||
|
|
||||||
|
if (glFmt.compressed && data != null){
|
||||||
|
if (target == GL2ES2.GL_TEXTURE_3D){
|
||||||
|
gl.getGL2ES2().glCompressedTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtInternal, data.limit(), data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all other targets use 2D: array, cubemap, 2d
|
||||||
|
gl.getGL2ES2().glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtInternal, data.limit(), data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == GL2ES2.GL_TEXTURE_3D){
|
||||||
|
gl.getGL2ES2().glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (samples > 1){
|
||||||
|
throw new IllegalStateException("Cannot update multisample textures");
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtFormat, glFmtDataType, data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,28 @@
|
|||||||
package com.jme3.renderer.lwjgl;
|
package com.jme3.renderer.lwjgl;
|
||||||
|
|
||||||
import com.jme3.light.*;
|
import static org.lwjgl.opengl.GL11.*;
|
||||||
|
|
||||||
|
import java.nio.Buffer;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import jme3tools.converters.MipMapGenerator;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL12;
|
||||||
|
import org.lwjgl.opengl.GL14;
|
||||||
|
import org.lwjgl.opengl.GLContext;
|
||||||
|
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
|
import com.jme3.light.Light;
|
||||||
|
import com.jme3.light.LightList;
|
||||||
|
import com.jme3.light.PointLight;
|
||||||
|
import com.jme3.light.SpotLight;
|
||||||
import com.jme3.material.FixedFuncBinding;
|
import com.jme3.material.FixedFuncBinding;
|
||||||
import com.jme3.material.RenderState;
|
import com.jme3.material.RenderState;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
@ -25,16 +47,6 @@ import com.jme3.texture.Texture;
|
|||||||
import com.jme3.texture.Texture.WrapAxis;
|
import com.jme3.texture.Texture.WrapAxis;
|
||||||
import com.jme3.util.BufferUtils;
|
import com.jme3.util.BufferUtils;
|
||||||
import com.jme3.util.NativeObjectManager;
|
import com.jme3.util.NativeObjectManager;
|
||||||
import java.nio.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import jme3tools.converters.MipMapGenerator;
|
|
||||||
import static org.lwjgl.opengl.GL11.*;
|
|
||||||
import org.lwjgl.opengl.GL12;
|
|
||||||
import org.lwjgl.opengl.GL14;
|
|
||||||
import org.lwjgl.opengl.GLContext;
|
|
||||||
|
|
||||||
public class LwjglGL1Renderer implements GL1Renderer {
|
public class LwjglGL1Renderer implements GL1Renderer {
|
||||||
|
|
||||||
@ -836,6 +848,11 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
setupTextureParams(tex);
|
setupTextureParams(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
|
||||||
|
setTexture(0, tex);
|
||||||
|
TextureUtil.uploadSubTexture(pixels, convertTextureType(tex.getType()), 0, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
private void clearTextureUnits() {
|
private void clearTextureUnits() {
|
||||||
Image[] textures = context.boundTextures;
|
Image[] textures = context.boundTextures;
|
||||||
if (textures[0] != null) {
|
if (textures[0] != null) {
|
||||||
|
@ -1946,6 +1946,11 @@ public class LwjglRenderer implements Renderer {
|
|||||||
setupTextureParams(tex);
|
setupTextureParams(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
|
||||||
|
setTexture(0, tex);
|
||||||
|
TextureUtil.uploadSubTexture(pixels, convertTextureType(tex.getType(), pixels.getMultiSamples(), -1), 0, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
public void clearTextureUnits() {
|
public void clearTextureUnits() {
|
||||||
// IDList textureList = context.textureIndexList;
|
// IDList textureList = context.textureIndexList;
|
||||||
// Image[] textures = context.boundTextures;
|
// Image[] textures = context.boundTextures;
|
||||||
|
@ -32,11 +32,29 @@
|
|||||||
|
|
||||||
package com.jme3.renderer.lwjgl;
|
package com.jme3.renderer.lwjgl;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.ARBHalfFloatPixel;
|
||||||
|
import org.lwjgl.opengl.ARBTextureFloat;
|
||||||
|
import org.lwjgl.opengl.ARBTextureMultisample;
|
||||||
|
import org.lwjgl.opengl.ContextCapabilities;
|
||||||
|
import org.lwjgl.opengl.EXTAbgr;
|
||||||
|
import org.lwjgl.opengl.EXTBgra;
|
||||||
|
import org.lwjgl.opengl.EXTPackedFloat;
|
||||||
|
import org.lwjgl.opengl.EXTTextureArray;
|
||||||
|
import org.lwjgl.opengl.EXTTextureCompressionLATC;
|
||||||
|
import org.lwjgl.opengl.EXTTextureCompressionS3TC;
|
||||||
|
import org.lwjgl.opengl.EXTTextureSharedExponent;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.lwjgl.opengl.GL12;
|
||||||
|
import org.lwjgl.opengl.GL13;
|
||||||
|
import org.lwjgl.opengl.GL14;
|
||||||
|
import org.lwjgl.opengl.GL30;
|
||||||
|
import org.lwjgl.opengl.GLContext;
|
||||||
|
|
||||||
import com.jme3.renderer.RendererException;
|
import com.jme3.renderer.RendererException;
|
||||||
import com.jme3.texture.Image;
|
import com.jme3.texture.Image;
|
||||||
import com.jme3.texture.Image.Format;
|
import com.jme3.texture.Image.Format;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import org.lwjgl.opengl.*;
|
|
||||||
|
|
||||||
class TextureUtil {
|
class TextureUtil {
|
||||||
|
|
||||||
@ -349,4 +367,103 @@ class TextureUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the texture currently bound to target at with data from the given Image at position x and y. The parameter
|
||||||
|
* index is used as the zoffset in case a 3d texture or texture 2d array is being updated.
|
||||||
|
*
|
||||||
|
* @param image Image with the source data (this data will be put into the texture)
|
||||||
|
* @param target the target texture
|
||||||
|
* @param index the mipmap level to update
|
||||||
|
* @param x the x position where to put the image in the texture
|
||||||
|
* @param y the y position where to put the image in the texture
|
||||||
|
*/
|
||||||
|
public static void uploadSubTexture(
|
||||||
|
Image image,
|
||||||
|
int target,
|
||||||
|
int index,
|
||||||
|
int x,
|
||||||
|
int y) {
|
||||||
|
Image.Format fmt = image.getFormat();
|
||||||
|
GLImageFormat glFmt = getImageFormatWithError(fmt);
|
||||||
|
|
||||||
|
ByteBuffer data = null;
|
||||||
|
if (index >= 0 && image.getData() != null && image.getData().size() > 0) {
|
||||||
|
data = image.getData(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = image.getWidth();
|
||||||
|
int height = image.getHeight();
|
||||||
|
int depth = image.getDepth();
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] mipSizes = image.getMipMapSizes();
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
// TODO: Remove unneccessary allocation
|
||||||
|
if (mipSizes == null){
|
||||||
|
if (data != null) {
|
||||||
|
mipSizes = new int[]{ data.capacity() };
|
||||||
|
} else {
|
||||||
|
mipSizes = new int[]{ width * height * fmt.getBitsPerPixel() / 8 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int samples = image.getMultiSamples();
|
||||||
|
|
||||||
|
for (int i = 0; i < mipSizes.length; i++){
|
||||||
|
int mipWidth = Math.max(1, width >> i);
|
||||||
|
int mipHeight = Math.max(1, height >> i);
|
||||||
|
int mipDepth = Math.max(1, depth >> i);
|
||||||
|
|
||||||
|
if (data != null){
|
||||||
|
data.position(pos);
|
||||||
|
data.limit(pos + mipSizes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// to remove the cumbersome if/then/else stuff below we'll update the pos right here and use continue after each
|
||||||
|
// gl*Image call in an attempt to unclutter things a bit
|
||||||
|
pos += mipSizes[i];
|
||||||
|
|
||||||
|
int glFmtInternal = glFmt.internalFormat;
|
||||||
|
int glFmtFormat = glFmt.format;
|
||||||
|
int glFmtDataType = glFmt.dataType;
|
||||||
|
|
||||||
|
if (glFmt.compressed && data != null){
|
||||||
|
if (target == GL12.GL_TEXTURE_3D){
|
||||||
|
GL13.glCompressedTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtInternal, data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all other targets use 2D: array, cubemap, 2d
|
||||||
|
GL13.glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtInternal, data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == GL12.GL_TEXTURE_3D){
|
||||||
|
GL12.glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT){
|
||||||
|
// prepare data for 2D array or upload slice
|
||||||
|
if (index == -1){
|
||||||
|
GL12.glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL12.glTexSubImage3D(target, i, x, y, index, width, height, 1, glFmtFormat, glFmtDataType, data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (samples > 1){
|
||||||
|
throw new IllegalStateException("Cannot update multisample textures");
|
||||||
|
}
|
||||||
|
|
||||||
|
GL11.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtFormat, glFmtDataType, data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user