* 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
This commit is contained in:
parent
9f4f321098
commit
27bf244729
@ -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;
|
||||||
}
|
}
|
||||||
@ -330,6 +323,9 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
// Allocate buffer for compressed formats.
|
// Allocate buffer for compressed formats.
|
||||||
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++) {
|
||||||
@ -337,9 +333,10 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextureUtil.loadTextureFeatures(extensions);
|
TextureUtil.loadTextureFeatures(extensions);
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1959,6 +2064,8 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
vb.isNormalized(),
|
vb.isNormalized(),
|
||||||
vb.getStride(),
|
vb.getStride(),
|
||||||
0);
|
0);
|
||||||
|
|
||||||
|
RendererUtil.checkGLError();
|
||||||
|
|
||||||
attribs[loc] = vb;
|
attribs[loc] = vb;
|
||||||
}
|
}
|
||||||
@ -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.
|
||||||
@ -2345,8 +2467,11 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
vb.isNormalized(),
|
vb.isNormalized(),
|
||||||
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…
x
Reference in New Issue
Block a user