LwjglRenderer - Preparing for abstraction layer shift

* All GL calls are done via static imports
 * Once again remove dependency on GL21 / GL30 - with the generator it will be possible to choose whether to target GL2+extensions or GL3 core
 * ContextCapabilities is field in Renderer, not allowed to use GLContext to retrieve it anymore
 * Assume depth textures are always supported (they should be since GL1.4)
experimental
shadowislord 11 years ago
parent 2e796444a5
commit 03f8df05b6
  1. 17
      jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL1Renderer.java
  2. 141
      jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglRenderer.java
  3. 320
      jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/TextureUtil.java

@ -47,6 +47,7 @@ import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapAxis;
import com.jme3.util.BufferUtils;
import com.jme3.util.NativeObjectManager;
import org.lwjgl.opengl.ContextCapabilities;
public class LwjglGL1Renderer implements GL1Renderer {
@ -76,6 +77,8 @@ public class LwjglGL1Renderer implements GL1Renderer {
private ArrayList<Light> lightList = new ArrayList<Light>(8);
private ColorRGBA materialAmbientColor = new ColorRGBA();
private Vector3f tempVec = new Vector3f();
private ContextCapabilities ctxCaps;
protected void updateNameBuffer() {
int len = stringBuf.length();
@ -98,7 +101,9 @@ public class LwjglGL1Renderer implements GL1Renderer {
}
public void initialize() {
if (GLContext.getCapabilities().OpenGL12){
ctxCaps = GLContext.getCapabilities();
if (ctxCaps.OpenGL12){
gl12 = true;
}
@ -119,7 +124,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
glEnable(GL_NORMALIZE);
}
if (GLContext.getCapabilities().GL_ARB_texture_non_power_of_two) {
if (ctxCaps.GL_ARB_texture_non_power_of_two) {
caps.add(Caps.NonPowerOfTwoTextures);
} else {
logger.log(Level.WARNING, "Your graphics card does not "
@ -753,7 +758,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
}
// Check sizes if graphics card doesn't support NPOT
if (!GLContext.getCapabilities().GL_ARB_texture_non_power_of_two && img.isNPOT()) {
if (!ctxCaps.GL_ARB_texture_non_power_of_two && img.isNPOT()) {
// Resize texture to Power-of-2 size
MipMapGenerator.resizeToPowerOf2(img);
}
@ -763,7 +768,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
// generate from base level if required
// Check if hardware mips are supported
if (GLContext.getCapabilities().OpenGL14) {
if (ctxCaps.OpenGL14) {
glTexParameteri(target, GL14.GL_GENERATE_MIPMAP, GL_TRUE);
} else {
MipMapGenerator.generateMipMaps(img);
@ -797,7 +802,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
TextureUtil.uploadTexture(img, target, i, 0, tdc);
}
} else {*/
TextureUtil.uploadTexture(img, target, 0, 0, false);
TextureUtil.uploadTexture(ctxCaps, img, target, 0, 0, false);
//}
img.clearUpdateNeeded();
@ -848,7 +853,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
setTexture(0, tex);
TextureUtil.uploadSubTexture(pixels, convertTextureType(tex.getType()), 0, x, y, false);
TextureUtil.uploadSubTexture(ctxCaps, pixels, convertTextureType(tex.getType()), 0, x, y, false);
}
private void clearTextureUnits() {

@ -63,18 +63,30 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import jme3tools.converters.MipMapGenerator;
import jme3tools.shader.ShaderDebug;
import static org.lwjgl.opengl.ARBDrawInstanced.*;
import static org.lwjgl.opengl.ARBInstancedArrays.*;
import static org.lwjgl.opengl.ARBMultisample.*;
import static org.lwjgl.opengl.ARBTextureMultisample.*;
import static org.lwjgl.opengl.ARBVertexArrayObject.*;
import org.lwjgl.opengl.ContextCapabilities;
import static org.lwjgl.opengl.EXTFramebufferBlit.*;
import static org.lwjgl.opengl.EXTFramebufferMultisample.*;
import static org.lwjgl.opengl.EXTFramebufferObject.*;
import static org.lwjgl.opengl.EXTFramebufferSRGB.*;
import static org.lwjgl.opengl.EXTGpuShader4.*;
import static org.lwjgl.opengl.EXTTextureArray.*;
import static org.lwjgl.opengl.EXTTextureFilterAnisotropic.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL14.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import org.lwjgl.opengl.*;
//import static org.lwjgl.opengl.ARBDrawInstanced.*;
import org.lwjgl.opengl.GLContext;
//import static org.lwjgl.opengl.GL21.*;
//import static org.lwjgl.opengl.GL30.*;
public class LwjglRenderer implements Renderer {
@ -113,6 +125,7 @@ public class LwjglRenderer implements Renderer {
private int vpX, vpY, vpW, vpH;
private int clipX, clipY, clipW, clipH;
private boolean linearizeSrgbImages;
private ContextCapabilities ctxCaps;
public LwjglRenderer() {
}
@ -141,7 +154,7 @@ public class LwjglRenderer implements Renderer {
@SuppressWarnings("fallthrough")
public void initialize() {
ContextCapabilities ctxCaps = GLContext.getCapabilities();
ctxCaps = GLContext.getCapabilities();
if (ctxCaps.OpenGL20) {
caps.add(Caps.OpenGL20);
if (ctxCaps.OpenGL21) {
@ -371,24 +384,17 @@ public class LwjglRenderer implements Renderer {
caps.add(Caps.FrameBufferMRT);
logger.log(Level.FINER, "FBO Max MRT renderbuffers: {0}", maxMRTFBOAttachs);
}
// if (ctxCaps.GL_ARB_draw_buffers) {
// caps.add(Caps.FrameBufferMRT);
// glGetInteger(ARBDrawBuffers.GL_MAX_DRAW_BUFFERS_ARB, intBuf16);
// maxMRTFBOAttachs = intBuf16.get(0);
// logger.log(Level.FINER, "FBO Max MRT renderbuffers: {0}", maxMRTFBOAttachs);
//}
}
if (ctxCaps.GL_ARB_multisample) {
glGetInteger(ARBMultisample.GL_SAMPLE_BUFFERS_ARB, intBuf16);
glGetInteger(GL_SAMPLE_BUFFERS_ARB, intBuf16);
boolean available = intBuf16.get(0) != 0;
glGetInteger(ARBMultisample.GL_SAMPLES_ARB, intBuf16);
glGetInteger(GL_SAMPLES_ARB, intBuf16);
int samples = intBuf16.get(0);
logger.log(Level.FINER, "Samples: {0}", samples);
boolean enabled = glIsEnabled(ARBMultisample.GL_MULTISAMPLE_ARB);
boolean enabled = glIsEnabled(GL_MULTISAMPLE_ARB);
if (samples > 0 && available && !enabled) {
glEnable(ARBMultisample.GL_MULTISAMPLE_ARB);
glEnable(GL_MULTISAMPLE_ARB);
}
caps.add(Caps.Multisample);
}
@ -472,11 +478,11 @@ public class LwjglRenderer implements Renderer {
}
public void setAlphaToCoverage(boolean value) {
if (caps.contains(Caps.Multisample)) {
if (ctxCaps.GL_ARB_multisample) {
if (value) {
glEnable(ARBMultisample.GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
} else {
glDisable(ARBMultisample.GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
}
}
}
@ -1068,12 +1074,12 @@ public class LwjglRenderer implements Renderer {
glAttachShader(id, source.getId());
}
if (caps.contains(Caps.OpenGL30)) {
if (ctxCaps.GL_EXT_gpu_shader4) {
// Check if GLSL version is 1.5 for shader
GL30.glBindFragDataLocation(id, 0, "outFragColor");
glBindFragDataLocationEXT(id, 0, "outFragColor");
// For MRT
for (int i = 0; i < maxMRTFBOAttachs; i++) {
GL30.glBindFragDataLocation(id, i, "outFragData[" + i + "]");
glBindFragDataLocationEXT(id, i, "outFragData[" + i + "]");
}
}
@ -1178,7 +1184,7 @@ public class LwjglRenderer implements Renderer {
}
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
if (GLContext.getCapabilities().GL_EXT_framebuffer_blit) {
if (ctxCaps.GL_EXT_framebuffer_blit) {
int srcX0 = 0;
int srcY0 = 0;
int srcX1;
@ -1310,8 +1316,8 @@ public class LwjglRenderer implements Renderer {
String readBuf = getTargetBufferName(glGetInteger(GL_READ_BUFFER));
int fbId = fb.getId();
int curDrawBinding = glGetInteger(ARBFramebufferObject.GL_DRAW_FRAMEBUFFER_BINDING);
int curReadBinding = glGetInteger(ARBFramebufferObject.GL_READ_FRAMEBUFFER_BINDING);
int curDrawBinding = glGetInteger(GL_DRAW_FRAMEBUFFER_BINDING_EXT);
int curReadBinding = glGetInteger(GL_READ_FRAMEBUFFER_BINDING_EXT);
System.out.println("=== OpenGL FBO State ===");
System.out.println("Context doublebuffered? " + doubleBuffer);
@ -1384,9 +1390,9 @@ public class LwjglRenderer implements Renderer {
+ ":" + fb.getHeight() + " is not supported.");
}
TextureUtil.GLImageFormat glFmt = TextureUtil.getImageFormatWithError(rb.getFormat(), fb.isSrgb());
TextureUtil.GLImageFormat glFmt = TextureUtil.getImageFormatWithError(ctxCaps, rb.getFormat(), fb.isSrgb());
if (fb.getSamples() > 1 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample) {
if (fb.getSamples() > 1 && ctxCaps.GL_EXT_framebuffer_multisample) {
int samples = fb.getSamples();
if (maxFBOSamples < samples) {
samples = maxFBOSamples;
@ -1488,6 +1494,9 @@ public class LwjglRenderer implements Renderer {
if (fb.getSamples() <= 1) {
throw new IllegalArgumentException("Framebuffer must be multisampled");
}
if (!ctxCaps.GL_ARB_texture_multisample) {
throw new RendererException("Multisampled textures are not supported");
}
setFrameBuffer(fb);
@ -1507,6 +1516,11 @@ public class LwjglRenderer implements Renderer {
}
public void setFrameBuffer(FrameBuffer fb) {
if (!ctxCaps.GL_EXT_framebuffer_object) {
throw new RendererException("Framebuffer objects are not supported" +
" by the video hardware");
}
if (fb == null && mainFbOverride != null) {
fb = mainFbOverride;
}
@ -1684,18 +1698,23 @@ public class LwjglRenderer implements Renderer {
|* Textures *|
\*********************************************************************/
private int convertTextureType(Texture.Type type, int samples, int face) {
if (samples > 1 && !ctxCaps.GL_ARB_texture_multisample) {
throw new RendererException("Multisample textures are not supported" +
" by the video hardware.");
}
switch (type) {
case TwoDimensional:
if (samples > 1) {
return ARBTextureMultisample.GL_TEXTURE_2D_MULTISAMPLE;
return GL_TEXTURE_2D_MULTISAMPLE;
} else {
return GL_TEXTURE_2D;
}
case TwoDimensionalArray:
if (samples > 1) {
return ARBTextureMultisample.GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
return GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
} else {
return EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT;
return GL_TEXTURE_2D_ARRAY_EXT;
}
case ThreeDimensional:
return GL_TEXTURE_3D;
@ -1771,9 +1790,9 @@ public class LwjglRenderer implements Renderer {
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter);
if (tex.getAnisotropicFilter() > 1) {
if (GLContext.getCapabilities().GL_EXT_texture_filter_anisotropic) {
if (ctxCaps.GL_EXT_texture_filter_anisotropic) {
glTexParameterf(target,
EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT,
GL_TEXTURE_MAX_ANISOTROPY_EXT,
tex.getAnisotropicFilter());
}
}
@ -1853,7 +1872,7 @@ public class LwjglRenderer implements Renderer {
// Image does not have mipmaps, but they are required.
// Generate from base level.
if (!GLContext.getCapabilities().OpenGL30) {
if (!ctxCaps.OpenGL30) {
glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
img.setMipmapsGenerated(true);
} else {
@ -1880,7 +1899,7 @@ public class LwjglRenderer implements Renderer {
}
// Yes, some OpenGL2 cards (GeForce 5) still dont support NPOT.
if (!GLContext.getCapabilities().GL_ARB_texture_non_power_of_two && img.isNPOT()) {
if (!ctxCaps.GL_ARB_texture_non_power_of_two && img.isNPOT()) {
if (img.getData(0) == null) {
throw new RendererException("non-power-of-2 framebuffer textures are not supported by the video hardware");
} else {
@ -1889,7 +1908,7 @@ public class LwjglRenderer implements Renderer {
}
// Check if graphics card doesn't support multisample textures
if (!GLContext.getCapabilities().GL_ARB_texture_multisample) {
if (!ctxCaps.GL_ARB_texture_multisample) {
if (img.getMultiSamples() > 1) {
throw new RendererException("Multisample textures not supported by graphics hardware");
}
@ -1914,9 +1933,9 @@ public class LwjglRenderer implements Renderer {
return;
}
for (int i = 0; i < 6; i++) {
TextureUtil.uploadTexture(img, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0, linearizeSrgbImages);
TextureUtil.uploadTexture(ctxCaps, img, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0, linearizeSrgbImages);
}
} else if (target == EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT) {
} else if (target == GL_TEXTURE_2D_ARRAY_EXT) {
if (!caps.contains(Caps.TextureArray)) {
throw new RendererException("Texture arrays not supported by graphics hardware");
}
@ -1924,22 +1943,22 @@ public class LwjglRenderer implements Renderer {
List<ByteBuffer> data = img.getData();
// -1 index specifies prepare data for 2D Array
TextureUtil.uploadTexture(img, target, -1, 0, linearizeSrgbImages);
TextureUtil.uploadTexture(ctxCaps, img, target, -1, 0, linearizeSrgbImages);
for (int i = 0; i < data.size(); i++) {
// upload each slice of 2D array in turn
// this time with the appropriate index
TextureUtil.uploadTexture(img, target, i, 0, linearizeSrgbImages);
TextureUtil.uploadTexture(ctxCaps, img, target, i, 0, linearizeSrgbImages);
}
} else {
TextureUtil.uploadTexture(img, target, 0, 0, linearizeSrgbImages);
TextureUtil.uploadTexture(ctxCaps, img, target, 0, 0, linearizeSrgbImages);
}
if (img.getMultiSamples() != imageSamples) {
img.setMultiSamples(imageSamples);
}
if (GLContext.getCapabilities().OpenGL30) {
if (ctxCaps.OpenGL30) {
if (!img.hasMipmaps() && img.isGeneratedMipmapsRequired() && img.getData() != null) {
// XXX: Required for ATI
glEnable(target);
@ -1990,7 +2009,7 @@ public class LwjglRenderer implements Renderer {
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, linearizeSrgbImages);
TextureUtil.uploadSubTexture(ctxCaps, pixels, convertTextureType(tex.getType(), pixels.getMultiSamples(), -1), 0, x, y, linearizeSrgbImages);
}
public void clearTextureUnits() {
@ -2050,9 +2069,6 @@ public class LwjglRenderer implements Renderer {
return GL_INT;
case UnsignedInt:
return GL_UNSIGNED_INT;
// case Half:
// return NVHalfFloat.GL_HALF_FLOAT_NV;
// return ARBHalfFloatVertex.GL_HALF_FLOAT;
case Float:
return GL_FLOAT;
case Double:
@ -2175,7 +2191,7 @@ public class LwjglRenderer implements Renderer {
int idx = attribList.oldList[i];
glDisableVertexAttribArray(idx);
if (context.boundAttribs[idx].isInstanced()) {
ARBInstancedArrays.glVertexAttribDivisorARB(idx, 0);
glVertexAttribDivisorARB(idx, 0);
}
context.boundAttribs[idx] = null;
}
@ -2212,8 +2228,8 @@ public class LwjglRenderer implements Renderer {
int slotsRequired = 1;
if (vb.isInstanced()) {
if (!GLContext.getCapabilities().GL_ARB_instanced_arrays
|| !GLContext.getCapabilities().GL_ARB_draw_instanced) {
if (!ctxCaps.GL_ARB_instanced_arrays
|| !ctxCaps.GL_ARB_draw_instanced) {
throw new RendererException("Instancing is required, "
+ "but not supported by the "
+ "graphics hardware");
@ -2278,10 +2294,10 @@ public class LwjglRenderer implements Renderer {
int slot = loc + i;
if (vb.isInstanced() && (attribs[slot] == null || !attribs[slot].isInstanced())) {
// non-instanced -> instanced
ARBInstancedArrays.glVertexAttribDivisorARB(slot, 1);
glVertexAttribDivisorARB(slot, 1);
} else if (!vb.isInstanced() && attribs[slot] != null && attribs[slot].isInstanced()) {
// instanced -> non-instanced
ARBInstancedArrays.glVertexAttribDivisorARB(slot, 0);
glVertexAttribDivisorARB(slot, 0);
}
attribs[slot] = vb;
}
@ -2298,7 +2314,7 @@ public class LwjglRenderer implements Renderer {
public void drawTriangleArray(Mesh.Mode mode, int count, int vertCount) {
boolean useInstancing = count > 1 && caps.contains(Caps.MeshInstancing);
if (useInstancing) {
ARBDrawInstanced.glDrawArraysInstancedARB(convertElementMode(mode), 0,
glDrawArraysInstancedARB(convertElementMode(mode), 0,
vertCount, count);
} else {
glDrawArrays(convertElementMode(mode), 0, vertCount);
@ -2348,7 +2364,7 @@ public class LwjglRenderer implements Renderer {
int elementLength = elementLengths[i];
if (useInstancing) {
ARBDrawInstanced.glDrawElementsInstancedARB(elMode,
glDrawElementsInstancedARB(elMode,
elementLength,
fmt,
curOffset,
@ -2366,7 +2382,7 @@ public class LwjglRenderer implements Renderer {
}
} else {
if (useInstancing) {
ARBDrawInstanced.glDrawElementsInstancedARB(convertElementMode(mesh.getMode()),
glDrawElementsInstancedARB(convertElementMode(mesh.getMode()),
indexBuf.getData().limit(),
convertFormat(indexBuf.getFormat()),
0,
@ -2410,13 +2426,13 @@ public class LwjglRenderer implements Renderer {
int id = mesh.getId();
if (id == -1) {
IntBuffer temp = intBuf1;
ARBVertexArrayObject.glGenVertexArrays(temp);
glGenVertexArrays(temp);
id = temp.get(0);
mesh.setId(id);
}
if (context.boundVertexArray != id) {
ARBVertexArrayObject.glBindVertexArray(id);
glBindVertexArray(id);
context.boundVertexArray = id;
}
@ -2454,7 +2470,7 @@ public class LwjglRenderer implements Renderer {
}
if (context.boundVertexArray != mesh.getId()) {
ARBVertexArrayObject.glBindVertexArray(mesh.getId());
glBindVertexArray(mesh.getId());
context.boundVertexArray = mesh.getId();
}
@ -2546,7 +2562,7 @@ public class LwjglRenderer implements Renderer {
}
statistics.onMeshDrawn(mesh, lod, count);
// if (GLContext.getCapabilities().GL_ARB_vertex_array_object){
// if (ctxCaps.GL_ARB_vertex_array_object){
// renderMeshVertexArray(mesh, lod, count);
// }else{
renderMeshDefault(mesh, lod, count, instanceData);
@ -2568,25 +2584,18 @@ public class LwjglRenderer implements Renderer {
setFrameBuffer(null);
if (enableSrgb) {
if (!glGetBoolean(GL30.GL_FRAMEBUFFER_SRGB_CAPABLE)) {
if (!glGetBoolean(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT)) {
logger.warning("Driver claims that default framebuffer "
+ "is not sRGB capable. Enabling anyway.");
}
int encoding = GL30.glGetFramebufferAttachmentParameteri(GL30.GL_DRAW_FRAMEBUFFER,
GL_FRONT_LEFT,
GL30.GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
if (encoding != GL21.GL_SRGB) {
logger.warning("Driver claims that default framebuffer "
+ "is not using sRGB color encoding. Enabling anyway.");
}
glEnable(GL30.GL_FRAMEBUFFER_SRGB);
glEnable(GL_FRAMEBUFFER_SRGB_EXT);
logger.log(Level.FINER, "SRGB FrameBuffer enabled (Gamma Correction)");
} else {
glDisable(GL30.GL_FRAMEBUFFER_SRGB);
glDisable(GL_FRAMEBUFFER_SRGB_EXT);
}
}

@ -39,20 +39,23 @@ import com.jme3.texture.image.ColorSpace;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.opengl.ARBTextureFloat;
import org.lwjgl.opengl.ARBTextureMultisample;
import static org.lwjgl.opengl.ARBDepthBufferFloat.*;
import static org.lwjgl.opengl.ARBHalfFloatPixel.*;
import static org.lwjgl.opengl.ARBTextureFloat.*;
import static org.lwjgl.opengl.ARBTextureMultisample.*;
import org.lwjgl.opengl.ContextCapabilities;
import org.lwjgl.opengl.EXTTextureArray;
import org.lwjgl.opengl.EXTTextureCompressionLATC;
import org.lwjgl.opengl.EXTTextureCompressionS3TC;
import org.lwjgl.opengl.EXTTextureSRGB;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL14;
import org.lwjgl.opengl.GL21;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GLContext;
import static org.lwjgl.opengl.EXTPackedDepthStencil.*;
import static org.lwjgl.opengl.EXTPackedFloat.*;
import static org.lwjgl.opengl.EXTTextureArray.*;
import static org.lwjgl.opengl.EXTTextureCompressionLATC.*;
import static org.lwjgl.opengl.EXTTextureCompressionS3TC.*;
import static org.lwjgl.opengl.EXTTextureSRGB.*;
import static org.lwjgl.opengl.EXTTextureSharedExponent.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.*;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL14.*;
import static org.lwjgl.opengl.GL20.*;
class TextureUtil {
@ -79,80 +82,80 @@ class TextureUtil {
static {
// Alpha formats
setFormat(Format.Alpha8, GL11.GL_ALPHA8, GL11.GL_ALPHA, GL11.GL_UNSIGNED_BYTE, false);
setFormat(Format.Alpha16, GL11.GL_ALPHA16, GL11.GL_ALPHA, GL11.GL_UNSIGNED_SHORT, false);
setFormat(Format.Alpha8, GL_ALPHA8, GL_ALPHA, GL_UNSIGNED_BYTE, false);
setFormat(Format.Alpha16, GL_ALPHA16, GL_ALPHA, GL_UNSIGNED_SHORT, false);
// Luminance formats
setFormat(Format.Luminance8, GL11.GL_LUMINANCE8, GL11.GL_LUMINANCE, GL11.GL_UNSIGNED_BYTE, false);
setFormat(Format.Luminance16, GL11.GL_LUMINANCE16, GL11.GL_LUMINANCE, GL11.GL_UNSIGNED_SHORT, false);
setFormat(Format.Luminance16F, ARBTextureFloat.GL_LUMINANCE16F_ARB, GL11.GL_LUMINANCE, GL30.GL_HALF_FLOAT, false);
setFormat(Format.Luminance32F, ARBTextureFloat.GL_LUMINANCE32F_ARB, GL11.GL_LUMINANCE, GL11.GL_FLOAT, false);
setFormat(Format.Luminance8, GL_LUMINANCE8, GL_LUMINANCE, GL_UNSIGNED_BYTE, false);
setFormat(Format.Luminance16, GL_LUMINANCE16, GL_LUMINANCE, GL_UNSIGNED_SHORT, false);
setFormat(Format.Luminance16F, GL_LUMINANCE16F_ARB, GL_LUMINANCE, GL_HALF_FLOAT_ARB, false);
setFormat(Format.Luminance32F, GL_LUMINANCE32F_ARB, GL_LUMINANCE, GL_FLOAT, false);
// Luminance alpha formats
setFormat(Format.Luminance8Alpha8, GL11.GL_LUMINANCE8_ALPHA8, GL11.GL_LUMINANCE_ALPHA, GL11.GL_UNSIGNED_BYTE, false);
setFormat(Format.Luminance16Alpha16, GL11.GL_LUMINANCE16_ALPHA16, GL11.GL_LUMINANCE_ALPHA, GL11.GL_UNSIGNED_SHORT, false);
setFormat(Format.Luminance16FAlpha16F, ARBTextureFloat.GL_LUMINANCE_ALPHA16F_ARB, GL11.GL_LUMINANCE_ALPHA, GL30.GL_HALF_FLOAT, false);
setFormat(Format.Luminance8Alpha8, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, false);
setFormat(Format.Luminance16Alpha16, GL_LUMINANCE16_ALPHA16, GL_LUMINANCE_ALPHA, GL_UNSIGNED_SHORT, false);
setFormat(Format.Luminance16FAlpha16F, GL_LUMINANCE_ALPHA16F_ARB, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_ARB, false);
// Depth formats
setFormat(Format.Depth, GL11.GL_DEPTH_COMPONENT, GL11.GL_DEPTH_COMPONENT, GL11.GL_UNSIGNED_BYTE, false);
setFormat(Format.Depth16, GL14.GL_DEPTH_COMPONENT16, GL11.GL_DEPTH_COMPONENT, GL11.GL_UNSIGNED_SHORT, false);
setFormat(Format.Depth24, GL14.GL_DEPTH_COMPONENT24, GL11.GL_DEPTH_COMPONENT, GL11.GL_UNSIGNED_INT, false);
setFormat(Format.Depth32, GL14.GL_DEPTH_COMPONENT32, GL11.GL_DEPTH_COMPONENT, GL11.GL_UNSIGNED_INT, false);
setFormat(Format.Depth32F, GL30.GL_DEPTH_COMPONENT32F, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, false);
setFormat(Format.Depth, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, false);
setFormat(Format.Depth16, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, false);
setFormat(Format.Depth24, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, false);
setFormat(Format.Depth32, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, false);
setFormat(Format.Depth32F, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, false);
// Depth stencil formats
setFormat(Format.Depth24Stencil8, GL30.GL_DEPTH24_STENCIL8, GL30.GL_DEPTH_STENCIL, GL30.GL_UNSIGNED_INT_24_8, false);
setFormat(Format.Depth24Stencil8, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, false);
// RGB formats
setFormat(Format.BGR8, GL11.GL_RGB8, GL12.GL_BGR, GL11.GL_UNSIGNED_BYTE, false);
setFormat(Format.ARGB8, GL11.GL_RGBA8, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8, false);
setFormat(Format.BGRA8, GL11.GL_RGBA8, GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE, false);
setFormat(Format.RGB8, GL11.GL_RGB8, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, false);
// setFormat(Format.RGB10, GL11.GL_RGB10, GL11.GL_RGB, GL12.GL_UNSIGNED_INT_10_10_10_2, false);
setFormat(Format.RGB16, GL11.GL_RGB16, GL11.GL_RGB, GL11.GL_UNSIGNED_SHORT, false);
setFormat(Format.RGB16F, GL30.GL_RGB16F, GL11.GL_RGB, GL30.GL_HALF_FLOAT, false);
setFormat(Format.RGB32F, GL30.GL_RGB32F, GL11.GL_RGB, GL11.GL_FLOAT, false);
setFormat(Format.BGR8, GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE, false);
setFormat(Format.ARGB8, GL_RGBA8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, false);
setFormat(Format.BGRA8, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, false);
setFormat(Format.RGB8, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, false);
// setFormat(Format.RGB10, GL_RGB10, GL_RGB, GL_UNSIGNED_INT_10_10_10_2, false);
setFormat(Format.RGB16, GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT, false);
setFormat(Format.RGB16F, GL_RGB16F_ARB, GL_RGB, GL_HALF_FLOAT_ARB, false);
setFormat(Format.RGB32F, GL_RGB32F_ARB, GL_RGB, GL_FLOAT, false);
// Special RGB formats
setFormat(Format.RGB111110F, GL30.GL_R11F_G11F_B10F, GL11.GL_RGB, GL30.GL_UNSIGNED_INT_10F_11F_11F_REV, false);
setFormat(Format.RGB9E5, GL30.GL_RGB9_E5, GL11.GL_RGB, GL30.GL_UNSIGNED_INT_5_9_9_9_REV, false);
setFormat(Format.RGB16F_to_RGB111110F, GL30.GL_R11F_G11F_B10F, GL11.GL_RGB, GL30.GL_HALF_FLOAT, false);
setFormat(Format.RGB16F_to_RGB9E5, GL30.GL_RGB9_E5, GL11.GL_RGB, GL30.GL_HALF_FLOAT, false);
setFormat(Format.RGB10_A2, GL11.GL_RGB10_A2, GL11.GL_RGBA, GL12.GL_UNSIGNED_INT_10_10_10_2, false);
setFormat(Format.RGB111110F, GL_R11F_G11F_B10F_EXT, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV_EXT, false);
setFormat(Format.RGB9E5, GL_RGB9_E5_EXT, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV_EXT, false);
setFormat(Format.RGB16F_to_RGB111110F, GL_R11F_G11F_B10F_EXT, GL_RGB, GL_HALF_FLOAT_ARB, false);
setFormat(Format.RGB16F_to_RGB9E5, GL_RGB9_E5_EXT, GL_RGB, GL_HALF_FLOAT_ARB, false);
setFormat(Format.RGB10_A2, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_10_10_10_2, false);
// RGBA formats
setFormat(Format.ABGR8, GL11.GL_RGBA8, GL11.GL_RGBA, GL12.GL_UNSIGNED_INT_8_8_8_8, false);
setFormat(Format.RGB5A1, GL11.GL_RGB5_A1, GL11.GL_RGBA, GL12.GL_UNSIGNED_SHORT_5_5_5_1, false);
setFormat(Format.ARGB4444,GL11.GL_RGBA4, GL11.GL_RGBA, GL12.GL_UNSIGNED_SHORT_4_4_4_4_REV, false);
setFormat(Format.RGBA8, GL11.GL_RGBA8, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, false);
setFormat(Format.RGBA16, GL11.GL_RGBA16, GL11.GL_RGBA, GL11.GL_UNSIGNED_SHORT, false); // might be incorrect
setFormat(Format.RGBA16F, GL30.GL_RGBA16F, GL11.GL_RGBA, GL30.GL_HALF_FLOAT, false);
setFormat(Format.RGBA32F, GL30.GL_RGBA32F, GL11.GL_RGBA, GL11.GL_FLOAT, false);
setFormat(Format.ABGR8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, false);
setFormat(Format.RGB5A1, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, false);
setFormat(Format.ARGB4444,GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, false);
setFormat(Format.RGBA8, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false);
setFormat(Format.RGBA16, GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, false); // might be incorrect
setFormat(Format.RGBA16F, GL_RGBA16F_ARB, GL_RGBA, GL_HALF_FLOAT_ARB, false);
setFormat(Format.RGBA32F, GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, false);
// DXT formats
setFormat(Format.DXT1, EXTTextureCompressionS3TC.GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, true);
setFormat(Format.DXT1A, EXTTextureCompressionS3TC.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, true);
setFormat(Format.DXT3, EXTTextureCompressionS3TC.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, true);
setFormat(Format.DXT5, EXTTextureCompressionS3TC.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, true);
setFormat(Format.DXT1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, true);
setFormat(Format.DXT1A, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
setFormat(Format.DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
setFormat(Format.DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
// LTC/LATC/3Dc formats
setFormat(Format.LTC, EXTTextureCompressionLATC.GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL11.GL_LUMINANCE, GL11.GL_UNSIGNED_BYTE, true);
setFormat(Format.LATC, EXTTextureCompressionLATC.GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL11.GL_LUMINANCE_ALPHA, GL11.GL_UNSIGNED_BYTE, true);
setFormat(Format.LTC, GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE, true);
setFormat(Format.LATC, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, true);
}
//sRGB formats
private static final GLImageFormat sRGB_RGB8 = new GLImageFormat(GL21.GL_SRGB8, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_RGBA8 = new GLImageFormat(GL21.GL_SRGB8_ALPHA8, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_Luminance8 = new GLImageFormat(GL21.GL_SLUMINANCE8, GL11.GL_LUMINANCE, GL11.GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_LuminanceAlpha8 = new GLImageFormat(GL21.GL_SLUMINANCE8_ALPHA8, GL11.GL_LUMINANCE_ALPHA, GL11.GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_BGR8 = new GLImageFormat(GL21.GL_SRGB8, GL12.GL_BGR, GL11.GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_ABGR8 = new GLImageFormat(GL21.GL_SRGB8_ALPHA8, GL11.GL_RGBA, GL12.GL_UNSIGNED_INT_8_8_8_8, false);
private static final GLImageFormat sRGB_ARGB8 = new GLImageFormat(GL21.GL_SRGB8_ALPHA8, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8, false);
private static final GLImageFormat sRGB_BGRA8 = new GLImageFormat(GL21.GL_SRGB8_ALPHA8, GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_DXT1 = new GLImageFormat(EXTTextureSRGB.GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, true);
private static final GLImageFormat sRGB_DXT1A = new GLImageFormat(EXTTextureSRGB.GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, true);
private static final GLImageFormat sRGB_DXT3 = new GLImageFormat(EXTTextureSRGB.GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, true);
private static final GLImageFormat sRGB_DXT5 = new GLImageFormat(EXTTextureSRGB.GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, true);
private static final GLImageFormat sRGB_RGB8 = new GLImageFormat(GL_SRGB8_EXT, GL_RGB, GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_RGBA8 = new GLImageFormat(GL_SRGB8_ALPHA8_EXT, GL_RGBA, GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_Luminance8 = new GLImageFormat(GL_SLUMINANCE8_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_LuminanceAlpha8 = new GLImageFormat(GL_SLUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_BGR8 = new GLImageFormat(GL_SRGB8_EXT, GL_BGR, GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_ABGR8 = new GLImageFormat(GL_SRGB8_ALPHA8_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, false);
private static final GLImageFormat sRGB_ARGB8 = new GLImageFormat(GL_SRGB8_ALPHA8_EXT, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, false);
private static final GLImageFormat sRGB_BGRA8 = new GLImageFormat(GL_SRGB8_ALPHA8_EXT, GL_BGRA, GL_UNSIGNED_BYTE, false);
private static final GLImageFormat sRGB_DXT1 = new GLImageFormat(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,GL_RGB, GL_UNSIGNED_BYTE, true);
private static final GLImageFormat sRGB_DXT1A = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
private static final GLImageFormat sRGB_DXT3 = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
private static final GLImageFormat sRGB_DXT5 = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
public static GLImageFormat getImageFormat(ContextCapabilities caps, Format fmt, boolean isSrgb){
switch (fmt){
@ -164,14 +167,6 @@ class TextureUtil {
return null;
}
break;
case Depth:
case Depth16:
case Depth24:
case Depth32:
if (!caps.OpenGL14 && !caps.GL_ARB_depth_texture){
return null;
}
break;
case Depth24Stencil8:
if (!caps.OpenGL30 && !caps.GL_EXT_packed_depth_stencil){
return null;
@ -219,8 +214,8 @@ class TextureUtil {
}
}
public static GLImageFormat getImageFormatWithError(Format fmt, boolean isSrgb) {
GLImageFormat glFmt = getImageFormat(GLContext.getCapabilities(), fmt, isSrgb);
public static GLImageFormat getImageFormatWithError(ContextCapabilities caps, Format fmt, boolean isSrgb) {
GLImageFormat glFmt = getImageFormat(caps, fmt, isSrgb);
if (glFmt == null) {
throw new RendererException("Image format '" + fmt + "' is unsupported by the video hardware.");
}
@ -259,14 +254,15 @@ class TextureUtil {
}
}
public static void uploadTexture(Image image,
public static void uploadTexture(ContextCapabilities caps,
Image image,
int target,
int index,
int border,
boolean linearizeSrgb){
Image.Format fmt = image.getFormat();
GLImageFormat glFmt = getImageFormatWithError(fmt, image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb);
GLImageFormat glFmt = getImageFormatWithError(caps, fmt, image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb);
ByteBuffer data;
if (index >= 0 && image.getData() != null && image.getData().size() > 0){
@ -280,7 +276,7 @@ class TextureUtil {
int depth = image.getDepth();
if (data != null) {
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}
int[] mipSizes = image.getMipMapSizes();
@ -307,63 +303,63 @@ class TextureUtil {
}
if (glFmt.compressed && data != null){
if (target == GL12.GL_TEXTURE_3D){
GL13.glCompressedTexImage3D(target,
i,
glFmt.internalFormat,
mipWidth,
mipHeight,
mipDepth,
border,
data);
if (target == GL_TEXTURE_3D){
glCompressedTexImage3D(target,
i,
glFmt.internalFormat,
mipWidth,
mipHeight,
mipDepth,
border,
data);
}else{
//all other targets use 2D: array, cubemap, 2d
GL13.glCompressedTexImage2D(target,
i,
glFmt.internalFormat,
mipWidth,
mipHeight,
border,
data);
glCompressedTexImage2D(target,
i,
glFmt.internalFormat,
mipWidth,
mipHeight,
border,
data);
}
}else{
if (target == GL12.GL_TEXTURE_3D){
GL12.glTexImage3D(target,
i,
glFmt.internalFormat,
mipWidth,
mipHeight,
mipDepth,
border,
glFmt.format,
glFmt.dataType,
data);
}else if (target == EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT){
if (target == GL_TEXTURE_3D){
glTexImage3D(target,
i,
glFmt.internalFormat,
mipWidth,
mipHeight,
mipDepth,
border,
glFmt.format,
glFmt.dataType,
data);
}else if (target == GL_TEXTURE_2D_ARRAY_EXT){
// prepare data for 2D array
// or upload slice
if (index == -1){
GL12.glTexImage3D(target,
i,
glFmt.internalFormat,
mipWidth,
mipHeight,
image.getData().size(), //# of slices
border,
glFmt.format,
glFmt.dataType,
data);
glTexImage3D(target,
i,
glFmt.internalFormat,
mipWidth,
mipHeight,
image.getData().size(), //# of slices
border,
glFmt.format,
glFmt.dataType,
data);
}else{
GL12.glTexSubImage3D(target,
i, // level
0, // xoffset
0, // yoffset
index, // zoffset
width, // width
height, // height
1, // depth
glFmt.format,
glFmt.dataType,
data);
glTexSubImage3D(target,
i, // level
0, // xoffset
0, // yoffset
index, // zoffset
width, // width
height, // height
1, // depth
glFmt.format,
glFmt.dataType,
data);
}
}else{
if (subtex){
@ -371,31 +367,31 @@ class TextureUtil {
throw new IllegalStateException("Cannot update multisample textures");
}
GL11.glTexSubImage2D(target,
i,
0, 0,
mipWidth, mipHeight,
glFmt.format,
glFmt.dataType,
data);
glTexSubImage2D(target,
i,
0, 0,
mipWidth, mipHeight,
glFmt.format,
glFmt.dataType,
data);
}else{
if (samples > 1){
ARBTextureMultisample.glTexImage2DMultisample(target,
samples,
glFmt.internalFormat,
mipWidth,
mipHeight,
true);
glTexImage2DMultisample(target,
samples,
glFmt.internalFormat,
mipWidth,
mipHeight,
true);
}else{
GL11.glTexImage2D(target,
i,
glFmt.internalFormat,
mipWidth,
mipHeight,
border,
glFmt.format,
glFmt.dataType,
data);
glTexImage2D(target,
i,
glFmt.internalFormat,
mipWidth,
mipHeight,
border,
glFmt.format,
glFmt.dataType,
data);
}
}
}
@ -416,6 +412,7 @@ class TextureUtil {
* @param y the y position where to put the image in the texture
*/
public static void uploadSubTexture(
ContextCapabilities caps,
Image image,
int target,
int index,
@ -423,7 +420,7 @@ class TextureUtil {
int y,
boolean linearizeSrgb) {
Image.Format fmt = image.getFormat();
GLImageFormat glFmt = getImageFormatWithError(fmt, image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb);
GLImageFormat glFmt = getImageFormatWithError(caps, fmt, image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb);
ByteBuffer data = null;
if (index >= 0 && image.getData() != null && image.getData().size() > 0) {
@ -435,7 +432,7 @@ class TextureUtil {
int depth = image.getDepth();
if (data != null) {
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}
int[] mipSizes = image.getMipMapSizes();
@ -471,29 +468,29 @@ class TextureUtil {
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);
if (target == GL_TEXTURE_3D){
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);
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);
if (target == GL_TEXTURE_3D){
glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data);
continue;
}
if (target == EXTTextureArray.GL_TEXTURE_2D_ARRAY_EXT){
if (target == 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);
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);
glTexSubImage3D(target, i, x, y, index, width, height, 1, glFmtFormat, glFmtDataType, data);
continue;
}
@ -501,8 +498,7 @@ class TextureUtil {
throw new IllegalStateException("Cannot update multisample textures");
}
GL11.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtFormat, glFmtDataType, data);
continue;
glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtFormat, glFmtDataType, data);
}
}
}

Loading…
Cancel
Save