* Added glGetError() checks after every GL call (its ugly, I know, but it helps with debugging). Added option to disable it with constant on RendererUtil.ENABLE_ERROR_CHECKING.

* Set lastFb in OGLESShaderRenderer when context is reset, this is needed otherwise the state tracker would not work correctly.
 * Fix issue with Mesh.Mode.Hybrid that wasn't rendering triangle fans correctly (was rendering them as triangle strips instead).
 * Remove call to glPointSize in OGLESShaderRenderer (it would most likely crash anyway, since GLES10 calls can't be used in a GLES20 context)
 * TestCustomMesh now uses shorts instead of ints for the index buffer. 32-bit indices are not supported on Android and are slower on Desktop, don't use them if you can avoid it.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10525 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
sha..RD 12 years ago
parent 9f4f321098
commit 27bf244729
  1. 175
      engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java
  2. 53
      engine/src/android/com/jme3/renderer/android/RendererUtil.java
  3. 27
      engine/src/android/com/jme3/renderer/android/TextureUtil.java
  4. 2
      engine/src/lwjgl/com/jme3/renderer/lwjgl/LwjglRenderer.java
  5. 4
      engine/src/test/jme3test/model/shape/TestCustomMesh.java

@ -121,13 +121,6 @@ public class OGLESShaderRenderer implements Renderer {
nameBuf.rewind(); nameBuf.rewind();
} }
private void checkGLError() {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
throw new RendererException("OpenGL Error " + error);
}
}
public Statistics getStatistics() { public Statistics getStatistics() {
return statistics; return statistics;
} }
@ -331,6 +324,9 @@ public class OGLESShaderRenderer implements Renderer {
IntBuffer compressedFormats = BufferUtils.createIntBuffer(numCompressedFormats); IntBuffer compressedFormats = BufferUtils.createIntBuffer(numCompressedFormats);
GLES20.glGetIntegerv(GLES20.GL_COMPRESSED_TEXTURE_FORMATS, compressedFormats); GLES20.glGetIntegerv(GLES20.GL_COMPRESSED_TEXTURE_FORMATS, compressedFormats);
// Check for errors after all glGet calls.
RendererUtil.checkGLError();
// Print compressed formats. // Print compressed formats.
for (int i = 0; i < numCompressedFormats; i++) { for (int i = 0; i < numCompressedFormats; i++) {
logger.log(Level.FINE, "Compressed Texture Formats: {0}", compressedFormats.get(i)); logger.log(Level.FINE, "Compressed Texture Formats: {0}", compressedFormats.get(i));
@ -340,6 +336,7 @@ public class OGLESShaderRenderer implements Renderer {
applyRenderState(RenderState.DEFAULT); applyRenderState(RenderState.DEFAULT);
GLES20.glDisable(GLES20.GL_DITHER); GLES20.glDisable(GLES20.GL_DITHER);
RendererUtil.checkGLError();
useVBO = false; useVBO = false;
@ -363,7 +360,7 @@ public class OGLESShaderRenderer implements Renderer {
objManager.resetObjects(); objManager.resetObjects();
statistics.clearMemory(); statistics.clearMemory();
boundShader = null; boundShader = null;
// lastFb = null; lastFb = null;
context.reset(); context.reset();
} }
@ -383,6 +380,7 @@ public class OGLESShaderRenderer implements Renderer {
\*********************************************************************/ \*********************************************************************/
public void setDepthRange(float start, float end) { public void setDepthRange(float start, float end) {
GLES20.glDepthRangef(start, end); GLES20.glDepthRangef(start, end);
RendererUtil.checkGLError();
} }
public void clearBuffers(boolean color, boolean depth, boolean stencil) { public void clearBuffers(boolean color, boolean depth, boolean stencil) {
@ -398,11 +396,13 @@ public class OGLESShaderRenderer implements Renderer {
} }
if (bits != 0) { if (bits != 0) {
GLES20.glClear(bits); GLES20.glClear(bits);
RendererUtil.checkGLError();
} }
} }
public void setBackgroundColor(ColorRGBA color) { public void setBackgroundColor(ColorRGBA color) {
GLES20.glClearColor(color.r, color.g, color.b, color.a); GLES20.glClearColor(color.r, color.g, color.b, color.a);
RendererUtil.checkGLError();
} }
public void applyRenderState(RenderState state) { public void applyRenderState(RenderState state) {
@ -418,24 +418,30 @@ public class OGLESShaderRenderer implements Renderer {
if (state.isDepthTest() && !context.depthTestEnabled) { if (state.isDepthTest() && !context.depthTestEnabled) {
GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_LEQUAL); GLES20.glDepthFunc(GLES20.GL_LEQUAL);
RendererUtil.checkGLError();
context.depthTestEnabled = true; context.depthTestEnabled = true;
} else if (!state.isDepthTest() && context.depthTestEnabled) { } else if (!state.isDepthTest() && context.depthTestEnabled) {
GLES20.glDisable(GLES20.GL_DEPTH_TEST); GLES20.glDisable(GLES20.GL_DEPTH_TEST);
RendererUtil.checkGLError();
context.depthTestEnabled = false; context.depthTestEnabled = false;
} }
if (state.isDepthWrite() && !context.depthWriteEnabled) { if (state.isDepthWrite() && !context.depthWriteEnabled) {
GLES20.glDepthMask(true); GLES20.glDepthMask(true);
RendererUtil.checkGLError();
context.depthWriteEnabled = true; context.depthWriteEnabled = true;
} else if (!state.isDepthWrite() && context.depthWriteEnabled) { } else if (!state.isDepthWrite() && context.depthWriteEnabled) {
GLES20.glDepthMask(false); GLES20.glDepthMask(false);
RendererUtil.checkGLError();
context.depthWriteEnabled = false; context.depthWriteEnabled = false;
} }
if (state.isColorWrite() && !context.colorWriteEnabled) { if (state.isColorWrite() && !context.colorWriteEnabled) {
GLES20.glColorMask(true, true, true, true); GLES20.glColorMask(true, true, true, true);
RendererUtil.checkGLError();
context.colorWriteEnabled = true; context.colorWriteEnabled = true;
} else if (!state.isColorWrite() && context.colorWriteEnabled) { } else if (!state.isColorWrite() && context.colorWriteEnabled) {
GLES20.glColorMask(false, false, false, false); GLES20.glColorMask(false, false, false, false);
RendererUtil.checkGLError();
context.colorWriteEnabled = false; context.colorWriteEnabled = false;
} }
// if (state.isPointSprite() && !context.pointSprite) { // if (state.isPointSprite() && !context.pointSprite) {
@ -452,6 +458,8 @@ public class OGLESShaderRenderer implements Renderer {
GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL); GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
GLES20.glPolygonOffset(state.getPolyOffsetFactor(), GLES20.glPolygonOffset(state.getPolyOffsetFactor(),
state.getPolyOffsetUnits()); state.getPolyOffsetUnits());
RendererUtil.checkGLError();
context.polyOffsetEnabled = true; context.polyOffsetEnabled = true;
context.polyOffsetFactor = state.getPolyOffsetFactor(); context.polyOffsetFactor = state.getPolyOffsetFactor();
context.polyOffsetUnits = state.getPolyOffsetUnits(); context.polyOffsetUnits = state.getPolyOffsetUnits();
@ -460,6 +468,8 @@ public class OGLESShaderRenderer implements Renderer {
|| state.getPolyOffsetUnits() != context.polyOffsetUnits) { || state.getPolyOffsetUnits() != context.polyOffsetUnits) {
GLES20.glPolygonOffset(state.getPolyOffsetFactor(), GLES20.glPolygonOffset(state.getPolyOffsetFactor(),
state.getPolyOffsetUnits()); state.getPolyOffsetUnits());
RendererUtil.checkGLError();
context.polyOffsetFactor = state.getPolyOffsetFactor(); context.polyOffsetFactor = state.getPolyOffsetFactor();
context.polyOffsetUnits = state.getPolyOffsetUnits(); context.polyOffsetUnits = state.getPolyOffsetUnits();
} }
@ -467,6 +477,8 @@ public class OGLESShaderRenderer implements Renderer {
} else { } else {
if (context.polyOffsetEnabled) { if (context.polyOffsetEnabled) {
GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL); GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
RendererUtil.checkGLError();
context.polyOffsetEnabled = false; context.polyOffsetEnabled = false;
context.polyOffsetFactor = 0; context.polyOffsetFactor = 0;
context.polyOffsetUnits = 0; context.polyOffsetUnits = 0;
@ -475,8 +487,10 @@ public class OGLESShaderRenderer implements Renderer {
if (state.getFaceCullMode() != context.cullMode) { if (state.getFaceCullMode() != context.cullMode) {
if (state.getFaceCullMode() == RenderState.FaceCullMode.Off) { if (state.getFaceCullMode() == RenderState.FaceCullMode.Off) {
GLES20.glDisable(GLES20.GL_CULL_FACE); GLES20.glDisable(GLES20.GL_CULL_FACE);
RendererUtil.checkGLError();
} else { } else {
GLES20.glEnable(GLES20.GL_CULL_FACE); GLES20.glEnable(GLES20.GL_CULL_FACE);
RendererUtil.checkGLError();
} }
switch (state.getFaceCullMode()) { switch (state.getFaceCullMode()) {
@ -484,12 +498,15 @@ public class OGLESShaderRenderer implements Renderer {
break; break;
case Back: case Back:
GLES20.glCullFace(GLES20.GL_BACK); GLES20.glCullFace(GLES20.GL_BACK);
RendererUtil.checkGLError();
break; break;
case Front: case Front:
GLES20.glCullFace(GLES20.GL_FRONT); GLES20.glCullFace(GLES20.GL_FRONT);
RendererUtil.checkGLError();
break; break;
case FrontAndBack: case FrontAndBack:
GLES20.glCullFace(GLES20.GL_FRONT_AND_BACK); GLES20.glCullFace(GLES20.GL_FRONT_AND_BACK);
RendererUtil.checkGLError();
break; break;
default: default:
throw new UnsupportedOperationException("Unrecognized face cull mode: " throw new UnsupportedOperationException("Unrecognized face cull mode: "
@ -502,6 +519,7 @@ public class OGLESShaderRenderer implements Renderer {
if (state.getBlendMode() != context.blendMode) { if (state.getBlendMode() != context.blendMode) {
if (state.getBlendMode() == RenderState.BlendMode.Off) { if (state.getBlendMode() == RenderState.BlendMode.Off) {
GLES20.glDisable(GLES20.GL_BLEND); GLES20.glDisable(GLES20.GL_BLEND);
RendererUtil.checkGLError();
} else { } else {
GLES20.glEnable(GLES20.GL_BLEND); GLES20.glEnable(GLES20.GL_BLEND);
switch (state.getBlendMode()) { switch (state.getBlendMode()) {
@ -532,6 +550,7 @@ public class OGLESShaderRenderer implements Renderer {
throw new UnsupportedOperationException("Unrecognized blend mode: " throw new UnsupportedOperationException("Unrecognized blend mode: "
+ state.getBlendMode()); + state.getBlendMode());
} }
RendererUtil.checkGLError();
} }
context.blendMode = state.getBlendMode(); context.blendMode = state.getBlendMode();
} }
@ -543,6 +562,8 @@ public class OGLESShaderRenderer implements Renderer {
public void setViewPort(int x, int y, int w, int h) { public void setViewPort(int x, int y, int w, int h) {
if (x != vpX || vpY != y || vpW != w || vpH != h) { if (x != vpX || vpY != y || vpW != w || vpH != h) {
GLES20.glViewport(x, y, w, h); GLES20.glViewport(x, y, w, h);
RendererUtil.checkGLError();
vpX = x; vpX = x;
vpY = y; vpY = y;
vpW = w; vpW = w;
@ -553,10 +574,12 @@ public class OGLESShaderRenderer implements Renderer {
public void setClipRect(int x, int y, int width, int height) { public void setClipRect(int x, int y, int width, int height) {
if (!context.clipRectEnabled) { if (!context.clipRectEnabled) {
GLES20.glEnable(GLES20.GL_SCISSOR_TEST); GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
RendererUtil.checkGLError();
context.clipRectEnabled = true; context.clipRectEnabled = true;
} }
if (clipX != x || clipY != y || clipW != width || clipH != height) { if (clipX != x || clipY != y || clipW != width || clipH != height) {
GLES20.glScissor(x, y, width, height); GLES20.glScissor(x, y, width, height);
RendererUtil.checkGLError();
clipX = x; clipX = x;
clipY = y; clipY = y;
clipW = width; clipW = width;
@ -567,6 +590,7 @@ public class OGLESShaderRenderer implements Renderer {
public void clearClipRect() { public void clearClipRect() {
if (context.clipRectEnabled) { if (context.clipRectEnabled) {
GLES20.glDisable(GLES20.GL_SCISSOR_TEST); GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
RendererUtil.checkGLError();
context.clipRectEnabled = false; context.clipRectEnabled = false;
clipX = 0; clipX = 0;
@ -577,10 +601,8 @@ public class OGLESShaderRenderer implements Renderer {
} }
public void onFrame() { public void onFrame() {
int error = GLES20.glGetError(); RendererUtil.checkGLErrorForced();
if (error != GLES20.GL_NO_ERROR){
throw new RendererException("OpenGL Error " + error + ". Enable error checking for more info.");
}
objManager.deleteUnused(this); objManager.deleteUnused(this);
} }
@ -598,6 +620,8 @@ public class OGLESShaderRenderer implements Renderer {
stringBuf.append(uniform.getName()).append('\0'); stringBuf.append(uniform.getName()).append('\0');
updateNameBuffer(); updateNameBuffer();
int loc = GLES20.glGetUniformLocation(shader.getId(), uniform.getName()); int loc = GLES20.glGetUniformLocation(shader.getId(), uniform.getName());
RendererUtil.checkGLError();
if (loc < 0) { if (loc < 0) {
uniform.setLocation(-1); uniform.setLocation(-1);
// uniform is not declared in shader // uniform is not declared in shader
@ -610,6 +634,8 @@ public class OGLESShaderRenderer implements Renderer {
int shaderId = shader.getId(); int shaderId = shader.getId();
if (context.boundShaderProgram != shaderId) { if (context.boundShaderProgram != shaderId) {
GLES20.glUseProgram(shaderId); GLES20.glUseProgram(shaderId);
RendererUtil.checkGLError();
statistics.onShaderUse(shader, true); statistics.onShaderUse(shader, true);
boundShader = shader; boundShader = shader;
context.boundShaderProgram = shaderId; context.boundShaderProgram = shaderId;
@ -626,6 +652,8 @@ public class OGLESShaderRenderer implements Renderer {
if (context.boundShaderProgram != shaderId) { if (context.boundShaderProgram != shaderId) {
GLES20.glUseProgram(shaderId); GLES20.glUseProgram(shaderId);
RendererUtil.checkGLError();
statistics.onShaderUse(shader, true); statistics.onShaderUse(shader, true);
boundShader = shader; boundShader = shader;
context.boundShaderProgram = shaderId; context.boundShaderProgram = shaderId;
@ -730,6 +758,7 @@ public class OGLESShaderRenderer implements Renderer {
default: default:
throw new UnsupportedOperationException("Unsupported uniform type: " + uniform.getVarType()); throw new UnsupportedOperationException("Unsupported uniform type: " + uniform.getVarType());
} }
RendererUtil.checkGLError();
} }
protected void updateShaderUniforms(Shader shader) { protected void updateShaderUniforms(Shader shader) {
@ -775,6 +804,8 @@ public class OGLESShaderRenderer implements Renderer {
if (id == -1) { if (id == -1) {
// Create id // Create id
id = GLES20.glCreateShader(convertShaderType(source.getType())); id = GLES20.glCreateShader(convertShaderType(source.getType()));
RendererUtil.checkGLError();
if (id <= 0) { if (id <= 0) {
throw new RendererException("Invalid ID received when trying to create shader."); throw new RendererException("Invalid ID received when trying to create shader.");
} }
@ -821,7 +852,10 @@ public class OGLESShaderRenderer implements Renderer {
// System.out.println("precision "+precision[0]); // System.out.println("precision "+precision[0]);
GLES20.glCompileShader(id); GLES20.glCompileShader(id);
RendererUtil.checkGLError();
GLES20.glGetShaderiv(id, GLES20.GL_COMPILE_STATUS, intBuf1); GLES20.glGetShaderiv(id, GLES20.GL_COMPILE_STATUS, intBuf1);
RendererUtil.checkGLError();
boolean compiledOK = intBuf1.get(0) == GLES20.GL_TRUE; boolean compiledOK = intBuf1.get(0) == GLES20.GL_TRUE;
String infoLog = null; String infoLog = null;
@ -830,7 +864,7 @@ public class OGLESShaderRenderer implements Renderer {
// even if compile succeeded, check // even if compile succeeded, check
// log for warnings // log for warnings
GLES20.glGetShaderiv(id, GLES20.GL_INFO_LOG_LENGTH, intBuf1); GLES20.glGetShaderiv(id, GLES20.GL_INFO_LOG_LENGTH, intBuf1);
checkGLError(); RendererUtil.checkGLError();
infoLog = GLES20.glGetShaderInfoLog(id); infoLog = GLES20.glGetShaderInfoLog(id);
} }
@ -858,6 +892,7 @@ public class OGLESShaderRenderer implements Renderer {
if (id == -1) { if (id == -1) {
// create program // create program
id = GLES20.glCreateProgram(); id = GLES20.glCreateProgram();
RendererUtil.checkGLError();
if (id <= 0) { if (id <= 0) {
throw new RendererException("Invalid ID received when trying to create shader program."); throw new RendererException("Invalid ID received when trying to create shader program.");
@ -871,23 +906,30 @@ public class OGLESShaderRenderer implements Renderer {
if (source.isUpdateNeeded()) { if (source.isUpdateNeeded()) {
updateShaderSourceData(source); updateShaderSourceData(source);
} }
GLES20.glAttachShader(id, source.getId()); GLES20.glAttachShader(id, source.getId());
RendererUtil.checkGLError();
} }
// link shaders to program // link shaders to program
GLES20.glLinkProgram(id); GLES20.glLinkProgram(id);
RendererUtil.checkGLError();
GLES20.glGetProgramiv(id, GLES20.GL_LINK_STATUS, intBuf1); GLES20.glGetProgramiv(id, GLES20.GL_LINK_STATUS, intBuf1);
RendererUtil.checkGLError();
boolean linkOK = intBuf1.get(0) == GLES20.GL_TRUE; boolean linkOK = intBuf1.get(0) == GLES20.GL_TRUE;
String infoLog = null; String infoLog = null;
if (VALIDATE_SHADER || !linkOK) { if (VALIDATE_SHADER || !linkOK) {
GLES20.glGetProgramiv(id, GLES20.GL_INFO_LOG_LENGTH, intBuf1); GLES20.glGetProgramiv(id, GLES20.GL_INFO_LOG_LENGTH, intBuf1);
RendererUtil.checkGLError();
int length = intBuf1.get(0); int length = intBuf1.get(0);
if (length > 3) { if (length > 3) {
// get infos // get infos
infoLog = GLES20.glGetProgramInfoLog(id); infoLog = GLES20.glGetProgramInfoLog(id);
RendererUtil.checkGLError();
} }
} }
@ -940,7 +982,10 @@ public class OGLESShaderRenderer implements Renderer {
} }
source.clearUpdateNeeded(); source.clearUpdateNeeded();
GLES20.glDeleteShader(source.getId()); GLES20.glDeleteShader(source.getId());
RendererUtil.checkGLError();
source.resetObject(); source.resetObject();
} }
@ -953,11 +998,15 @@ public class OGLESShaderRenderer implements Renderer {
for (ShaderSource source : shader.getSources()) { for (ShaderSource source : shader.getSources()) {
if (source.getId() != -1) { if (source.getId() != -1) {
GLES20.glDetachShader(shader.getId(), source.getId()); GLES20.glDetachShader(shader.getId(), source.getId());
RendererUtil.checkGLError();
deleteShaderSource(source); deleteShaderSource(source);
} }
} }
GLES20.glDeleteProgram(shader.getId()); GLES20.glDeleteProgram(shader.getId());
RendererUtil.checkGLError();
statistics.onDeleteShader(); statistics.onDeleteShader();
shader.resetObject(); shader.resetObject();
} }
@ -1161,12 +1210,16 @@ public class OGLESShaderRenderer implements Renderer {
int id = rb.getId(); int id = rb.getId();
if (id == -1) { if (id == -1) {
GLES20.glGenRenderbuffers(1, intBuf1); GLES20.glGenRenderbuffers(1, intBuf1);
RendererUtil.checkGLError();
id = intBuf1.get(0); id = intBuf1.get(0);
rb.setId(id); rb.setId(id);
} }
if (context.boundRB != id) { if (context.boundRB != id) {
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, id); GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, id);
RendererUtil.checkGLError();
context.boundRB = id; context.boundRB = id;
} }
@ -1198,6 +1251,8 @@ public class OGLESShaderRenderer implements Renderer {
imageFormat.renderBufferStorageFormat, imageFormat.renderBufferStorageFormat,
fb.getWidth(), fb.getWidth(),
fb.getHeight()); fb.getHeight());
RendererUtil.checkGLError();
} }
} }
@ -1229,6 +1284,8 @@ public class OGLESShaderRenderer implements Renderer {
convertTextureType(tex.getType()), convertTextureType(tex.getType()),
image.getId(), image.getId(),
0); 0);
RendererUtil.checkGLError();
} }
public void updateFrameBufferAttachment(FrameBuffer fb, RenderBuffer rb) { public void updateFrameBufferAttachment(FrameBuffer fb, RenderBuffer rb) {
@ -1246,6 +1303,8 @@ public class OGLESShaderRenderer implements Renderer {
convertAttachmentSlot(rb.getSlot()), convertAttachmentSlot(rb.getSlot()),
GLES20.GL_RENDERBUFFER, GLES20.GL_RENDERBUFFER,
rb.getId()); rb.getId());
RendererUtil.checkGLError();
} }
} }
@ -1255,6 +1314,8 @@ public class OGLESShaderRenderer implements Renderer {
intBuf1.clear(); intBuf1.clear();
// create FBO // create FBO
GLES20.glGenFramebuffers(1, intBuf1); GLES20.glGenFramebuffers(1, intBuf1);
RendererUtil.checkGLError();
id = intBuf1.get(0); id = intBuf1.get(0);
fb.setId(id); fb.setId(id);
objManager.registerForCleanup(fb); objManager.registerForCleanup(fb);
@ -1264,6 +1325,8 @@ public class OGLESShaderRenderer implements Renderer {
if (context.boundFBO != id) { if (context.boundFBO != id) {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, id); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, id);
RendererUtil.checkGLError();
// binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0 // binding an FBO automatically sets draw buf to GL_COLOR_ATTACHMENT0
context.boundDrawBuf = 0; context.boundDrawBuf = 0;
context.boundFBO = id; context.boundFBO = id;
@ -1309,6 +1372,7 @@ public class OGLESShaderRenderer implements Renderer {
// int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace()); // int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace());
int textureType = convertTextureType(tex.getType()); int textureType = convertTextureType(tex.getType());
GLES20.glGenerateMipmap(textureType); GLES20.glGenerateMipmap(textureType);
RendererUtil.checkGLError();
} }
} }
} }
@ -1317,6 +1381,8 @@ public class OGLESShaderRenderer implements Renderer {
// unbind any fbos // unbind any fbos
if (context.boundFBO != 0) { if (context.boundFBO != 0) {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
RendererUtil.checkGLError();
statistics.onFrameBufferUse(null, true); statistics.onFrameBufferUse(null, true);
context.boundFBO = 0; context.boundFBO = 0;
@ -1347,6 +1413,8 @@ public class OGLESShaderRenderer implements Renderer {
if (context.boundFBO != fb.getId()) { if (context.boundFBO != fb.getId()) {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb.getId()); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb.getId());
RendererUtil.checkGLError();
statistics.onFrameBufferUse(fb, true); statistics.onFrameBufferUse(fb, true);
// update viewport to reflect framebuffer's resolution // update viewport to reflect framebuffer's resolution
@ -1395,6 +1463,8 @@ public class OGLESShaderRenderer implements Renderer {
// select this draw buffer // select this draw buffer
if (context.boundDrawBuf != rb.getSlot()) { if (context.boundDrawBuf != rb.getSlot()) {
GLES20.glActiveTexture(convertAttachmentSlot(rb.getSlot())); GLES20.glActiveTexture(convertAttachmentSlot(rb.getSlot()));
RendererUtil.checkGLError();
context.boundDrawBuf = rb.getSlot(); context.boundDrawBuf = rb.getSlot();
} }
} }
@ -1427,6 +1497,8 @@ public class OGLESShaderRenderer implements Renderer {
setFrameBuffer(fb); setFrameBuffer(fb);
if (context.boundReadBuf != rb.getSlot()) { if (context.boundReadBuf != rb.getSlot()) {
GLES20.glActiveTexture(convertAttachmentSlot(rb.getSlot())); GLES20.glActiveTexture(convertAttachmentSlot(rb.getSlot()));
RendererUtil.checkGLError();
context.boundReadBuf = rb.getSlot(); context.boundReadBuf = rb.getSlot();
} }
} else { } else {
@ -1434,17 +1506,21 @@ public class OGLESShaderRenderer implements Renderer {
} }
GLES20.glReadPixels(vpX, vpY, vpW, vpH, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuf); GLES20.glReadPixels(vpX, vpY, vpW, vpH, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuf);
RendererUtil.checkGLError();
} }
private void deleteRenderBuffer(FrameBuffer fb, RenderBuffer rb) { private void deleteRenderBuffer(FrameBuffer fb, RenderBuffer rb) {
intBuf1.put(0, rb.getId()); intBuf1.put(0, rb.getId());
GLES20.glDeleteRenderbuffers(1, intBuf1); GLES20.glDeleteRenderbuffers(1, intBuf1);
RendererUtil.checkGLError();
} }
public void deleteFrameBuffer(FrameBuffer fb) { public void deleteFrameBuffer(FrameBuffer fb) {
if (fb.getId() != -1) { if (fb.getId() != -1) {
if (context.boundFBO == fb.getId()) { if (context.boundFBO == fb.getId()) {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
RendererUtil.checkGLError();
context.boundFBO = 0; context.boundFBO = 0;
} }
@ -1457,6 +1533,8 @@ public class OGLESShaderRenderer implements Renderer {
intBuf1.put(0, fb.getId()); intBuf1.put(0, fb.getId());
GLES20.glDeleteFramebuffers(1, intBuf1); GLES20.glDeleteFramebuffers(1, intBuf1);
RendererUtil.checkGLError();
fb.resetObject(); fb.resetObject();
statistics.onDeleteFrameBuffer(); statistics.onDeleteFrameBuffer();
@ -1539,6 +1617,7 @@ public class OGLESShaderRenderer implements Renderer {
GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_MIN_FILTER, minFilter); GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_MIN_FILTER, minFilter);
GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_MAG_FILTER, magFilter); GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_MAG_FILTER, magFilter);
RendererUtil.checkGLError();
/* /*
if (tex.getAnisotropicFilter() > 1){ if (tex.getAnisotropicFilter() > 1){
@ -1565,6 +1644,8 @@ public class OGLESShaderRenderer implements Renderer {
// fall down here is intentional.. // fall down here is intentional..
// case OneDimensional: // case OneDimensional:
GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_S, convertWrapMode(tex.getWrap(WrapAxis.S))); GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_S, convertWrapMode(tex.getWrap(WrapAxis.S)));
RendererUtil.checkGLError();
break; break;
default: default:
throw new UnsupportedOperationException("Unknown texture type: " + tex.getType()); throw new UnsupportedOperationException("Unknown texture type: " + tex.getType());
@ -1594,6 +1675,8 @@ public class OGLESShaderRenderer implements Renderer {
if (texId == -1) { if (texId == -1) {
// create texture // create texture
GLES20.glGenTextures(1, intBuf1); GLES20.glGenTextures(1, intBuf1);
RendererUtil.checkGLError();
texId = intBuf1.get(0); texId = intBuf1.get(0);
img.setId(texId); img.setId(texId);
objManager.registerForCleanup(img); objManager.registerForCleanup(img);
@ -1606,10 +1689,14 @@ public class OGLESShaderRenderer implements Renderer {
if (context.boundTextures[0] != img) { if (context.boundTextures[0] != img) {
if (context.boundTextureUnit != 0) { if (context.boundTextureUnit != 0) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
RendererUtil.checkGLError();
context.boundTextureUnit = 0; context.boundTextureUnit = 0;
} }
GLES20.glBindTexture(target, texId); GLES20.glBindTexture(target, texId);
RendererUtil.checkGLError();
context.boundTextures[0] = img; context.boundTextures[0] = img;
} }
@ -1697,6 +1784,8 @@ public class OGLESShaderRenderer implements Renderer {
} }
GLES20.glBindTexture(type, texId); GLES20.glBindTexture(type, texId);
RendererUtil.checkGLError();
textures[unit] = image; textures[unit] = image;
statistics.onTextureUse(tex.getImage(), true); statistics.onTextureUse(tex.getImage(), true);
@ -1734,6 +1823,8 @@ public class OGLESShaderRenderer implements Renderer {
intBuf1.position(0).limit(1); intBuf1.position(0).limit(1);
GLES20.glDeleteTextures(1, intBuf1); GLES20.glDeleteTextures(1, intBuf1);
RendererUtil.checkGLError();
image.resetObject(); image.resetObject();
statistics.onDeleteTexture(); statistics.onDeleteTexture();
@ -1791,6 +1882,8 @@ public class OGLESShaderRenderer implements Renderer {
if (bufId == -1) { if (bufId == -1) {
// create buffer // create buffer
GLES20.glGenBuffers(1, intBuf1); GLES20.glGenBuffers(1, intBuf1);
RendererUtil.checkGLError();
bufId = intBuf1.get(0); bufId = intBuf1.get(0);
vb.setId(bufId); vb.setId(bufId);
objManager.registerForCleanup(vb); objManager.registerForCleanup(vb);
@ -1804,12 +1897,16 @@ public class OGLESShaderRenderer implements Renderer {
target = GLES20.GL_ELEMENT_ARRAY_BUFFER; target = GLES20.GL_ELEMENT_ARRAY_BUFFER;
if (context.boundElementArrayVBO != bufId) { if (context.boundElementArrayVBO != bufId) {
GLES20.glBindBuffer(target, bufId); GLES20.glBindBuffer(target, bufId);
RendererUtil.checkGLError();
context.boundElementArrayVBO = bufId; context.boundElementArrayVBO = bufId;
} }
} else { } else {
target = GLES20.GL_ARRAY_BUFFER; target = GLES20.GL_ARRAY_BUFFER;
if (context.boundArrayVBO != bufId) { if (context.boundArrayVBO != bufId) {
GLES20.glBindBuffer(target, bufId); GLES20.glBindBuffer(target, bufId);
RendererUtil.checkGLError();
context.boundArrayVBO = bufId; context.boundArrayVBO = bufId;
} }
} }
@ -1825,21 +1922,21 @@ public class OGLESShaderRenderer implements Renderer {
case Byte: case Byte:
case UnsignedByte: case UnsignedByte:
GLES20.glBufferData(target, size, (ByteBuffer) vb.getData(), usage); GLES20.glBufferData(target, size, (ByteBuffer) vb.getData(), usage);
RendererUtil.checkGLError();
break; break;
//case Half:
case Short: case Short:
case UnsignedShort: case UnsignedShort:
GLES20.glBufferData(target, size, (ShortBuffer) vb.getData(), usage); GLES20.glBufferData(target, size, (ShortBuffer) vb.getData(), usage);
RendererUtil.checkGLError();
break; break;
case Int: case Int:
case UnsignedInt: case UnsignedInt:
GLES20.glBufferData(target, size, (IntBuffer) vb.getData(), usage); GLES20.glBufferData(target, size, (IntBuffer) vb.getData(), usage);
RendererUtil.checkGLError();
break; break;
case Float: case Float:
GLES20.glBufferData(target, size, (FloatBuffer) vb.getData(), usage); GLES20.glBufferData(target, size, (FloatBuffer) vb.getData(), usage);
break; RendererUtil.checkGLError();
case Double:
GLES20.glBufferData(target, size, (DoubleBuffer) vb.getData(), usage);
break; break;
default: default:
throw new RuntimeException("Unknown buffer format."); throw new RuntimeException("Unknown buffer format.");
@ -1851,20 +1948,21 @@ public class OGLESShaderRenderer implements Renderer {
case Byte: case Byte:
case UnsignedByte: case UnsignedByte:
GLES20.glBufferSubData(target, 0, size, (ByteBuffer) vb.getData()); GLES20.glBufferSubData(target, 0, size, (ByteBuffer) vb.getData());
RendererUtil.checkGLError();
break; break;
case Short: case Short:
case UnsignedShort: case UnsignedShort:
GLES20.glBufferSubData(target, 0, size, (ShortBuffer) vb.getData()); GLES20.glBufferSubData(target, 0, size, (ShortBuffer) vb.getData());
RendererUtil.checkGLError();
break; break;
case Int: case Int:
case UnsignedInt: case UnsignedInt:
GLES20.glBufferSubData(target, 0, size, (IntBuffer) vb.getData()); GLES20.glBufferSubData(target, 0, size, (IntBuffer) vb.getData());
RendererUtil.checkGLError();
break; break;
case Float: case Float:
GLES20.glBufferSubData(target, 0, size, (FloatBuffer) vb.getData()); GLES20.glBufferSubData(target, 0, size, (FloatBuffer) vb.getData());
break; RendererUtil.checkGLError();
case Double:
GLES20.glBufferSubData(target, 0, size, (DoubleBuffer) vb.getData());
break; break;
default: default:
throw new RuntimeException("Unknown buffer format."); throw new RuntimeException("Unknown buffer format.");
@ -1881,6 +1979,8 @@ public class OGLESShaderRenderer implements Renderer {
intBuf1.position(0).limit(1); intBuf1.position(0).limit(1);
GLES20.glDeleteBuffers(1, intBuf1); GLES20.glDeleteBuffers(1, intBuf1);
RendererUtil.checkGLError();
vb.resetObject(); vb.resetObject();
} }
} }
@ -1891,6 +1991,8 @@ public class OGLESShaderRenderer implements Renderer {
int idx = attribList.oldList[i]; int idx = attribList.oldList[i];
GLES20.glDisableVertexAttribArray(idx); GLES20.glDisableVertexAttribArray(idx);
RendererUtil.checkGLError();
context.boundAttribs[idx] = null; context.boundAttribs[idx] = null;
} }
context.attribIndexList.copyNewToOld(); context.attribIndexList.copyNewToOld();
@ -1920,6 +2022,7 @@ public class OGLESShaderRenderer implements Renderer {
String attributeName = "in" + vb.getBufferType().name(); String attributeName = "in" + vb.getBufferType().name();
loc = GLES20.glGetAttribLocation(programId, attributeName); loc = GLES20.glGetAttribLocation(programId, attributeName);
RendererUtil.checkGLError();
// not really the name of it in the shader (inPosition\0) but // not really the name of it in the shader (inPosition\0) but
// the internal name of the enum (Position). // the internal name of the enum (Position).
@ -1934,6 +2037,7 @@ public class OGLESShaderRenderer implements Renderer {
VertexBuffer[] attribs = context.boundAttribs; VertexBuffer[] attribs = context.boundAttribs;
if (!context.attribIndexList.moveToNew(loc)) { if (!context.attribIndexList.moveToNew(loc)) {
GLES20.glEnableVertexAttribArray(loc); GLES20.glEnableVertexAttribArray(loc);
RendererUtil.checkGLError();
//System.out.println("Enabled ATTRIB IDX: "+loc); //System.out.println("Enabled ATTRIB IDX: "+loc);
} }
if (attribs[loc] != vb) { if (attribs[loc] != vb) {
@ -1946,8 +2050,9 @@ public class OGLESShaderRenderer implements Renderer {
} }
if (context.boundArrayVBO != bufId) { if (context.boundArrayVBO != bufId) {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufId); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufId);
RendererUtil.checkGLError();
context.boundArrayVBO = bufId; context.boundArrayVBO = bufId;
} }
@ -1960,6 +2065,8 @@ public class OGLESShaderRenderer implements Renderer {
vb.getStride(), vb.getStride(),
0); 0);
RendererUtil.checkGLError();
attribs[loc] = vb; attribs[loc] = vb;
} }
} else { } else {
@ -1977,6 +2084,7 @@ public class OGLESShaderRenderer implements Renderer {
vertCount, count); vertCount, count);
}else{*/ }else{*/
GLES20.glDrawArrays(convertElementMode(mode), 0, vertCount); GLES20.glDrawArrays(convertElementMode(mode), 0, vertCount);
RendererUtil.checkGLError();
/* /*
}*/ }*/
} }
@ -1994,11 +2102,13 @@ public class OGLESShaderRenderer implements Renderer {
assert bufId != -1; assert bufId != -1;
if (bufId == -1) { if (bufId == -1) {
logger.warning("invalid buffer id!"); throw new RendererException("Invalid buffer ID");
} }
if (context.boundElementArrayVBO != bufId) { if (context.boundElementArrayVBO != bufId) {
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, bufId); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, bufId);
RendererUtil.checkGLError();
context.boundElementArrayVBO = bufId; context.boundElementArrayVBO = bufId;
} }
@ -2044,6 +2154,7 @@ public class OGLESShaderRenderer implements Renderer {
} else { } else {
indexBuf.getData().position(curOffset); indexBuf.getData().position(curOffset);
GLES20.glDrawElements(elMode, elementLength, fmt, indexBuf.getData()); GLES20.glDrawElements(elMode, elementLength, fmt, indexBuf.getData());
RendererUtil.checkGLError();
/* /*
glDrawRangeElements(elMode, glDrawRangeElements(elMode,
0, 0,
@ -2074,6 +2185,7 @@ public class OGLESShaderRenderer implements Renderer {
indexBuf.getData().limit(), indexBuf.getData().limit(),
convertVertexBufferFormat(indexBuf.getFormat()), convertVertexBufferFormat(indexBuf.getFormat()),
0); 0);
RendererUtil.checkGLError();
} }
} }
} }
@ -2180,6 +2292,7 @@ public class OGLESShaderRenderer implements Renderer {
drawTriangleList_Array(indices, mesh, count); drawTriangleList_Array(indices, mesh, count);
} else { } else {
GLES20.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount()); GLES20.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount());
RendererUtil.checkGLError();
} }
clearVertexAttribs(); clearVertexAttribs();
clearTextureUnits(); clearTextureUnits();
@ -2219,18 +2332,23 @@ public class OGLESShaderRenderer implements Renderer {
} else { } else {
// throw new UnsupportedOperationException("Cannot render without index buffer"); // throw new UnsupportedOperationException("Cannot render without index buffer");
GLES20.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount()); GLES20.glDrawArrays(convertElementMode(mesh.getMode()), 0, mesh.getVertexCount());
RendererUtil.checkGLError();
} }
clearVertexAttribs(); clearVertexAttribs();
clearTextureUnits(); clearTextureUnits();
} }
public void renderMesh(Mesh mesh, int lod, int count) { public void renderMesh(Mesh mesh, int lod, int count) {
/*
* NOTE: not supported in OpenGL ES 2.0.
if (context.pointSize != mesh.getPointSize()) { if (context.pointSize != mesh.getPointSize()) {
GLES10.glPointSize(mesh.getPointSize()); GLES10.glPointSize(mesh.getPointSize());
context.pointSize = mesh.getPointSize(); context.pointSize = mesh.getPointSize();
} }
*/
if (context.lineWidth != mesh.getLineWidth()) { if (context.lineWidth != mesh.getLineWidth()) {
GLES20.glLineWidth(mesh.getLineWidth()); GLES20.glLineWidth(mesh.getLineWidth());
RendererUtil.checkGLError();
context.lineWidth = mesh.getLineWidth(); context.lineWidth = mesh.getLineWidth();
} }
@ -2281,12 +2399,13 @@ public class OGLESShaderRenderer implements Renderer {
if (i == stripStart) { if (i == stripStart) {
elMode = convertElementMode(Mode.TriangleStrip); elMode = convertElementMode(Mode.TriangleStrip);
} else if (i == fanStart) { } else if (i == fanStart) {
elMode = convertElementMode(Mode.TriangleStrip); elMode = convertElementMode(Mode.TriangleFan);
} }
int elementLength = elementLengths[i]; int elementLength = elementLengths[i];
indexBuf.getData().position(curOffset); indexBuf.getData().position(curOffset);
GLES20.glDrawElements(elMode, elementLength, fmt, indexBuf.getData()); GLES20.glDrawElements(elMode, elementLength, fmt, indexBuf.getData());
RendererUtil.checkGLError();
curOffset += elementLength * elSize; curOffset += elementLength * elSize;
} }
@ -2296,6 +2415,7 @@ public class OGLESShaderRenderer implements Renderer {
indexBuf.getData().limit(), indexBuf.getData().limit(),
convertVertexBufferFormat(indexBuf.getFormat()), convertVertexBufferFormat(indexBuf.getFormat()),
indexBuf.getData()); indexBuf.getData());
RendererUtil.checkGLError();
} }
} }
@ -2323,6 +2443,8 @@ public class OGLESShaderRenderer implements Renderer {
String attributeName = "in" + vb.getBufferType().name(); String attributeName = "in" + vb.getBufferType().name();
loc = GLES20.glGetAttribLocation(programId, attributeName); loc = GLES20.glGetAttribLocation(programId, attributeName);
RendererUtil.checkGLError();
if (loc < 0) { if (loc < 0) {
attrib.setLocation(-1); attrib.setLocation(-1);
return; // not available in shader. return; // not available in shader.
@ -2346,7 +2468,10 @@ public class OGLESShaderRenderer implements Renderer {
vb.getStride(), vb.getStride(),
avb.getData()); avb.getData());
RendererUtil.checkGLError();
GLES20.glEnableVertexAttribArray(loc); GLES20.glEnableVertexAttribArray(loc);
RendererUtil.checkGLError();
attribs[loc] = vb; attribs[loc] = vb;
} // if (attribs[loc] != vb) } // if (attribs[loc] != vb)
@ -2366,8 +2491,10 @@ public class OGLESShaderRenderer implements Renderer {
public void setAlphaToCoverage(boolean value) { public void setAlphaToCoverage(boolean value) {
if (value) { if (value) {
GLES20.glEnable(GLES20.GL_SAMPLE_ALPHA_TO_COVERAGE); GLES20.glEnable(GLES20.GL_SAMPLE_ALPHA_TO_COVERAGE);
RendererUtil.checkGLError();
} else { } else {
GLES20.glDisable(GLES20.GL_SAMPLE_ALPHA_TO_COVERAGE); GLES20.glDisable(GLES20.GL_SAMPLE_ALPHA_TO_COVERAGE);
RendererUtil.checkGLError();
} }
} }
@ -2375,6 +2502,6 @@ public class OGLESShaderRenderer implements Renderer {
public void invalidateState() { public void invalidateState() {
context.reset(); context.reset();
boundShader = null; boundShader = null;
// lastFb = null; lastFb = null;
} }
} }

@ -0,0 +1,53 @@
package com.jme3.renderer.android;
import android.opengl.GLES20;
import android.opengl.GLU;
import com.jme3.renderer.RendererException;
/**
* Utility class used by the {@link OGLESShaderRenderer renderer} and sister classes.
*
* @author Kirill Vainer
*/
public class RendererUtil {
/**
* When set to true, every OpenGL call will check for errors and throw
* an exception if there is one, if false, no error checking is performed.
*/
public static boolean ENABLE_ERROR_CHECKING = true;
/**
* Checks for an OpenGL error and throws a {@link RendererException}
* if there is one. Ignores the value of {@link RendererUtil#ENABLE_ERROR_CHECKING}.
*/
public static void checkGLErrorForced() {
int error = GLES20.glGetError();
if (error != 0) {
String message = GLU.gluErrorString(error);
if (message == null) {
throw new RendererException("An unknown OpenGL error has occurred.");
} else {
throw new RendererException("An OpenGL error has occurred: " + message);
}
}
}
/**
* Checks for an OpenGL error and throws a {@link RendererException}
* if there is one. Does nothing if {@link RendererUtil#ENABLE_ERROR_CHECKING}
* is set to <code>false</code>.
*/
public static void checkGLError() {
if (!ENABLE_ERROR_CHECKING) return;
int error = GLES20.glGetError();
if (error != 0) {
String message = GLU.gluErrorString(error);
if (message == null) {
throw new RendererException("An unknown OpenGL error has occurred.");
} else {
throw new RendererException("An OpenGL error has occurred: " + message);
}
}
}
}

@ -103,10 +103,10 @@ public class TextureUtil {
logger.log(Level.FINEST, " - Uploading bitmap directly. Cannot compress as alpha present."); logger.log(Level.FINEST, " - Uploading bitmap directly. Cannot compress as alpha present.");
if (subTexture) { if (subTexture) {
GLUtils.texSubImage2D(target, level, x, y, bitmap); GLUtils.texSubImage2D(target, level, x, y, bitmap);
checkGLError(); RendererUtil.checkGLError();
} else { } else {
GLUtils.texImage2D(target, level, bitmap, 0); GLUtils.texImage2D(target, level, bitmap, 0);
checkGLError(); RendererUtil.checkGLError();
} }
} else { } else {
// Convert to RGB565 // Convert to RGB565
@ -150,7 +150,8 @@ public class TextureUtil {
ETC1.ETC1_RGB8_OES, ETC1.ETC1_RGB8_OES,
etc1tex.getData().capacity(), etc1tex.getData().capacity(),
etc1tex.getData()); etc1tex.getData());
checkGLError();
RendererUtil.checkGLError();
} else { } else {
GLES20.glCompressedTexImage2D(target, GLES20.glCompressedTexImage2D(target,
level, level,
@ -160,7 +161,8 @@ public class TextureUtil {
0, 0,
etc1tex.getData().capacity(), etc1tex.getData().capacity(),
etc1tex.getData()); etc1tex.getData());
checkGLError();
RendererUtil.checkGLError();
} }
// ETC1Util.loadTexture(target, level, 0, GLES20.GL_RGB, // ETC1Util.loadTexture(target, level, 0, GLES20.GL_RGB,
@ -208,17 +210,17 @@ public class TextureUtil {
if (subTexture) { if (subTexture) {
System.err.println("x : " + x + " y :" + y + " , " + bitmap.getWidth() + "/" + bitmap.getHeight()); System.err.println("x : " + x + " y :" + y + " , " + bitmap.getWidth() + "/" + bitmap.getHeight());
GLUtils.texSubImage2D(target, 0, x, y, bitmap); GLUtils.texSubImage2D(target, 0, x, y, bitmap);
checkGLError(); RendererUtil.checkGLError();
} else { } else {
GLUtils.texImage2D(target, 0, bitmap, 0); GLUtils.texImage2D(target, 0, bitmap, 0);
checkGLError(); RendererUtil.checkGLError();
} }
if (needMips) { if (needMips) {
// No pregenerated mips available, // No pregenerated mips available,
// generate from base level if required // generate from base level if required
GLES20.glGenerateMipmap(target); GLES20.glGenerateMipmap(target);
checkGLError(); RendererUtil.checkGLError();
} }
} }
} }
@ -485,13 +487,6 @@ public class TextureUtil {
} }
} }
private static void checkGLError() {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
throw new RendererException("OpenGL Error " + error);
}
}
/** /**
* Update the texture currently bound to target at with data from the given * 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 * Image at position x and y. The parameter index is used as the zoffset in
@ -564,10 +559,10 @@ public class TextureUtil {
if (imageFormat.compress && data != null) { if (imageFormat.compress && data != null) {
GLES20.glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, imageFormat.format, data.remaining(), data); GLES20.glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, imageFormat.format, data.remaining(), data);
checkGLError(); RendererUtil.checkGLError();
} else { } else {
GLES20.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, imageFormat.format, imageFormat.dataType, data); GLES20.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, imageFormat.format, imageFormat.dataType, data);
checkGLError(); RendererUtil.checkGLError();
} }
pos += mipSizes[i]; pos += mipSizes[i];

@ -2256,7 +2256,7 @@ public class LwjglRenderer implements Renderer {
if (i == stripStart) { if (i == stripStart) {
elMode = convertElementMode(Mode.TriangleStrip); elMode = convertElementMode(Mode.TriangleStrip);
} else if (i == fanStart) { } else if (i == fanStart) {
elMode = convertElementMode(Mode.TriangleStrip); elMode = convertElementMode(Mode.TriangleFan);
} }
int elementLength = elementLengths[i]; int elementLength = elementLengths[i];

@ -75,12 +75,12 @@ public class TestCustomMesh extends SimpleApplication {
texCoord[3] = new Vector2f(1,1); texCoord[3] = new Vector2f(1,1);
// Indexes. We define the order in which mesh should be constructed // Indexes. We define the order in which mesh should be constructed
int [] indexes = {2,0,1,1,3,2}; short[] indexes = {2, 0, 1, 1, 3, 2};
// Setting buffers // Setting buffers
m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices)); m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
m.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord)); m.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));
m.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes)); m.setBuffer(Type.Index, 1, BufferUtils.createShortBuffer(indexes));
m.updateBound(); m.updateBound();
// ************************************************************************* // *************************************************************************

Loading…
Cancel
Save