Additional fix for http://code.google.com/p/jmonkeyengine/issues/detail?id=504.
Fixes displaying leftover characters in BitmapText when setting the text to a smaller string and a weird situation where the scene would stop rendering do to improper buffer limit. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10060 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
609d51dbfd
commit
ab5282fb2d
@ -116,7 +116,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
nameBuf.rewind();
|
nameBuf.rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGLError() {
|
private void checkGLError() {
|
||||||
int error;
|
int error;
|
||||||
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
|
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
|
||||||
@ -131,7 +131,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
public EnumSet<Caps> getCaps() {
|
public EnumSet<Caps> getCaps() {
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int extractVersion(String prefixStr, String versionStr) {
|
private int extractVersion(String prefixStr, String versionStr) {
|
||||||
if (versionStr != null) {
|
if (versionStr != null) {
|
||||||
int spaceIdx = versionStr.indexOf(" ", prefixStr.length());
|
int spaceIdx = versionStr.indexOf(" ", prefixStr.length());
|
||||||
@ -152,32 +152,32 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
logger.log(Level.INFO, "Renderer: {0}", GLES20.glGetString(GLES20.GL_RENDERER));
|
logger.log(Level.INFO, "Renderer: {0}", GLES20.glGetString(GLES20.GL_RENDERER));
|
||||||
logger.log(Level.INFO, "Version: {0}", GLES20.glGetString(GLES20.GL_VERSION));
|
logger.log(Level.INFO, "Version: {0}", GLES20.glGetString(GLES20.GL_VERSION));
|
||||||
logger.log(Level.INFO, "Shading Language Version: {0}", GLES20.glGetString(GLES20.GL_SHADING_LANGUAGE_VERSION));
|
logger.log(Level.INFO, "Shading Language Version: {0}", GLES20.glGetString(GLES20.GL_SHADING_LANGUAGE_VERSION));
|
||||||
|
|
||||||
powerVr = GLES20.glGetString(GLES20.GL_RENDERER).contains("PowerVR");
|
powerVr = GLES20.glGetString(GLES20.GL_RENDERER).contains("PowerVR");
|
||||||
|
|
||||||
// Fix issue in TestRenderToMemory when GL_FRONT is the main
|
// Fix issue in TestRenderToMemory when GL_FRONT is the main
|
||||||
// buffer being used.
|
// buffer being used.
|
||||||
|
|
||||||
// initialDrawBuf = GLES20.glGetIntegeri(GLES20.GL_DRAW_BUFFER);
|
// initialDrawBuf = GLES20.glGetIntegeri(GLES20.GL_DRAW_BUFFER);
|
||||||
// initialReadBuf = GLES20.glGetIntegeri(GLES20.GL_READ_BUFFER);
|
// initialReadBuf = GLES20.glGetIntegeri(GLES20.GL_READ_BUFFER);
|
||||||
|
|
||||||
// Check OpenGL version
|
// Check OpenGL version
|
||||||
int openGlVer = extractVersion("OpenGL ES ", GLES20.glGetString(GLES20.GL_VERSION));
|
int openGlVer = extractVersion("OpenGL ES ", GLES20.glGetString(GLES20.GL_VERSION));
|
||||||
if (openGlVer == -1) {
|
if (openGlVer == -1) {
|
||||||
glslVer = -1;
|
glslVer = -1;
|
||||||
throw new UnsupportedOperationException("OpenGL ES 2.0+ is required for OGLESShaderRenderer!");
|
throw new UnsupportedOperationException("OpenGL ES 2.0+ is required for OGLESShaderRenderer!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check shader language version
|
// Check shader language version
|
||||||
glslVer = extractVersion("OpenGL ES GLSL ES ", GLES20.glGetString(GLES20.GL_SHADING_LANGUAGE_VERSION));
|
glslVer = extractVersion("OpenGL ES GLSL ES ", GLES20.glGetString(GLES20.GL_SHADING_LANGUAGE_VERSION));
|
||||||
switch (glslVer) {
|
switch (glslVer) {
|
||||||
// TODO: When new versions of OpenGL ES shader language come out,
|
// TODO: When new versions of OpenGL ES shader language come out,
|
||||||
// update this.
|
// update this.
|
||||||
default:
|
default:
|
||||||
caps.add(Caps.GLSL100);
|
caps.add(Caps.GLSL100);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, intBuf16);
|
GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, intBuf16);
|
||||||
vertexTextureUnits = intBuf16.get(0);
|
vertexTextureUnits = intBuf16.get(0);
|
||||||
logger.log(Level.INFO, "VTF Units: {0}", vertexTextureUnits);
|
logger.log(Level.INFO, "VTF Units: {0}", vertexTextureUnits);
|
||||||
@ -188,20 +188,20 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_IMAGE_UNITS, intBuf16);
|
GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_IMAGE_UNITS, intBuf16);
|
||||||
fragTextureUnits = intBuf16.get(0);
|
fragTextureUnits = intBuf16.get(0);
|
||||||
logger.log(Level.INFO, "Texture Units: {0}", fragTextureUnits);
|
logger.log(Level.INFO, "Texture Units: {0}", fragTextureUnits);
|
||||||
|
|
||||||
// Multiply vector count by 4 to get float count.
|
// Multiply vector count by 4 to get float count.
|
||||||
GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_UNIFORM_VECTORS, intBuf16);
|
GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_UNIFORM_VECTORS, intBuf16);
|
||||||
vertexUniforms = intBuf16.get(0) * 4;
|
vertexUniforms = intBuf16.get(0) * 4;
|
||||||
logger.log(Level.FINER, "Vertex Uniforms: {0}", vertexUniforms);
|
logger.log(Level.FINER, "Vertex Uniforms: {0}", vertexUniforms);
|
||||||
|
|
||||||
GLES20.glGetIntegerv(GLES20.GL_MAX_FRAGMENT_UNIFORM_VECTORS, intBuf16);
|
GLES20.glGetIntegerv(GLES20.GL_MAX_FRAGMENT_UNIFORM_VECTORS, intBuf16);
|
||||||
fragUniforms = intBuf16.get(0) * 4;
|
fragUniforms = intBuf16.get(0) * 4;
|
||||||
logger.log(Level.FINER, "Fragment Uniforms: {0}", fragUniforms);
|
logger.log(Level.FINER, "Fragment Uniforms: {0}", fragUniforms);
|
||||||
|
|
||||||
GLES20.glGetIntegerv(GLES20.GL_MAX_VARYING_VECTORS, intBuf16);
|
GLES20.glGetIntegerv(GLES20.GL_MAX_VARYING_VECTORS, intBuf16);
|
||||||
int varyingFloats = intBuf16.get(0) * 4;
|
int varyingFloats = intBuf16.get(0) * 4;
|
||||||
logger.log(Level.FINER, "Varying Floats: {0}", varyingFloats);
|
logger.log(Level.FINER, "Varying Floats: {0}", varyingFloats);
|
||||||
|
|
||||||
GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_ATTRIBS, intBuf16);
|
GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_ATTRIBS, intBuf16);
|
||||||
vertexAttribs = intBuf16.get(0);
|
vertexAttribs = intBuf16.get(0);
|
||||||
logger.log(Level.INFO, "Vertex Attributes: {0}", vertexAttribs);
|
logger.log(Level.INFO, "Vertex Attributes: {0}", vertexAttribs);
|
||||||
@ -209,15 +209,15 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
GLES20.glGetIntegerv(GLES20.GL_SUBPIXEL_BITS, intBuf16);
|
GLES20.glGetIntegerv(GLES20.GL_SUBPIXEL_BITS, intBuf16);
|
||||||
int subpixelBits = intBuf16.get(0);
|
int subpixelBits = intBuf16.get(0);
|
||||||
logger.log(Level.INFO, "Subpixel Bits: {0}", subpixelBits);
|
logger.log(Level.INFO, "Subpixel Bits: {0}", subpixelBits);
|
||||||
|
|
||||||
// GLES10.glGetIntegerv(GLES10.GL_MAX_ELEMENTS_VERTICES, intBuf16);
|
// GLES10.glGetIntegerv(GLES10.GL_MAX_ELEMENTS_VERTICES, intBuf16);
|
||||||
// maxVertCount = intBuf16.get(0);
|
// maxVertCount = intBuf16.get(0);
|
||||||
// logger.log(Level.FINER, "Preferred Batch Vertex Count: {0}", maxVertCount);
|
// logger.log(Level.FINER, "Preferred Batch Vertex Count: {0}", maxVertCount);
|
||||||
//
|
//
|
||||||
// GLES10.glGetIntegerv(GLES10.GL_MAX_ELEMENTS_INDICES, intBuf16);
|
// GLES10.glGetIntegerv(GLES10.GL_MAX_ELEMENTS_INDICES, intBuf16);
|
||||||
// maxTriCount = intBuf16.get(0);
|
// maxTriCount = intBuf16.get(0);
|
||||||
// logger.log(Level.FINER, "Preferred Batch Index Count: {0}", maxTriCount);
|
// logger.log(Level.FINER, "Preferred Batch Index Count: {0}", maxTriCount);
|
||||||
|
|
||||||
GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, intBuf16);
|
GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, intBuf16);
|
||||||
maxTexSize = intBuf16.get(0);
|
maxTexSize = intBuf16.get(0);
|
||||||
logger.log(Level.INFO, "Maximum Texture Resolution: {0}", maxTexSize);
|
logger.log(Level.INFO, "Maximum Texture Resolution: {0}", maxTexSize);
|
||||||
@ -233,23 +233,23 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
caps.add(Caps.FloatColorBuffer);
|
caps.add(Caps.FloatColorBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_depth_buffer_float){
|
if (ctxCaps.GL_ARB_depth_buffer_float){
|
||||||
caps.add(Caps.FloatDepthBuffer);
|
caps.add(Caps.FloatDepthBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_draw_instanced)
|
if (ctxCaps.GL_ARB_draw_instanced)
|
||||||
caps.add(Caps.MeshInstancing);
|
caps.add(Caps.MeshInstancing);
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_texture_buffer_object)
|
if (ctxCaps.GL_ARB_texture_buffer_object)
|
||||||
caps.add(Caps.TextureBuffer);
|
caps.add(Caps.TextureBuffer);
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_texture_float){
|
if (ctxCaps.GL_ARB_texture_float){
|
||||||
if (ctxCaps.GL_ARB_half_float_pixel){
|
if (ctxCaps.GL_ARB_half_float_pixel){
|
||||||
caps.add(Caps.FloatTexture);
|
caps.add(Caps.FloatTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_EXT_packed_float){
|
if (ctxCaps.GL_EXT_packed_float){
|
||||||
caps.add(Caps.PackedFloatColorBuffer);
|
caps.add(Caps.PackedFloatColorBuffer);
|
||||||
if (ctxCaps.GL_ARB_half_float_pixel){
|
if (ctxCaps.GL_ARB_half_float_pixel){
|
||||||
@ -258,32 +258,32 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
caps.add(Caps.PackedFloatTexture);
|
caps.add(Caps.PackedFloatTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_EXT_texture_array)
|
if (ctxCaps.GL_EXT_texture_array)
|
||||||
caps.add(Caps.TextureArray);
|
caps.add(Caps.TextureArray);
|
||||||
|
|
||||||
if (ctxCaps.GL_EXT_texture_shared_exponent)
|
if (ctxCaps.GL_EXT_texture_shared_exponent)
|
||||||
caps.add(Caps.SharedExponentTexture);
|
caps.add(Caps.SharedExponentTexture);
|
||||||
|
|
||||||
if (ctxCaps.GL_EXT_framebuffer_object){
|
if (ctxCaps.GL_EXT_framebuffer_object){
|
||||||
caps.add(Caps.FrameBuffer);
|
caps.add(Caps.FrameBuffer);
|
||||||
|
|
||||||
glGetInteger(GL_MAX_RENDERBUFFER_SIZE_EXT, intBuf16);
|
glGetInteger(GL_MAX_RENDERBUFFER_SIZE_EXT, intBuf16);
|
||||||
maxRBSize = intBuf16.get(0);
|
maxRBSize = intBuf16.get(0);
|
||||||
logger.log(Level.FINER, "FBO RB Max Size: {0}", maxRBSize);
|
logger.log(Level.FINER, "FBO RB Max Size: {0}", maxRBSize);
|
||||||
|
|
||||||
glGetInteger(GL_MAX_COLOR_ATTACHMENTS_EXT, intBuf16);
|
glGetInteger(GL_MAX_COLOR_ATTACHMENTS_EXT, intBuf16);
|
||||||
maxFBOAttachs = intBuf16.get(0);
|
maxFBOAttachs = intBuf16.get(0);
|
||||||
logger.log(Level.FINER, "FBO Max renderbuffers: {0}", maxFBOAttachs);
|
logger.log(Level.FINER, "FBO Max renderbuffers: {0}", maxFBOAttachs);
|
||||||
|
|
||||||
if (ctxCaps.GL_EXT_framebuffer_multisample){
|
if (ctxCaps.GL_EXT_framebuffer_multisample){
|
||||||
caps.add(Caps.FrameBufferMultisample);
|
caps.add(Caps.FrameBufferMultisample);
|
||||||
|
|
||||||
glGetInteger(GL_MAX_SAMPLES_EXT, intBuf16);
|
glGetInteger(GL_MAX_SAMPLES_EXT, intBuf16);
|
||||||
maxFBOSamples = intBuf16.get(0);
|
maxFBOSamples = intBuf16.get(0);
|
||||||
logger.log(Level.FINER, "FBO Max Samples: {0}", maxFBOSamples);
|
logger.log(Level.FINER, "FBO Max Samples: {0}", maxFBOSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_draw_buffers){
|
if (ctxCaps.GL_ARB_draw_buffers){
|
||||||
caps.add(Caps.FrameBufferMRT);
|
caps.add(Caps.FrameBufferMRT);
|
||||||
glGetInteger(ARBDrawBuffers.GL_MAX_DRAW_BUFFERS_ARB, intBuf16);
|
glGetInteger(ARBDrawBuffers.GL_MAX_DRAW_BUFFERS_ARB, intBuf16);
|
||||||
@ -291,7 +291,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
logger.log(Level.FINER, "FBO Max MRT renderbuffers: {0}", maxMRTFBOAttachs);
|
logger.log(Level.FINER, "FBO Max MRT renderbuffers: {0}", maxMRTFBOAttachs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_multisample){
|
if (ctxCaps.GL_ARB_multisample){
|
||||||
glGetInteger(ARBMultisample.GL_SAMPLE_BUFFERS_ARB, intBuf16);
|
glGetInteger(ARBMultisample.GL_SAMPLE_BUFFERS_ARB, intBuf16);
|
||||||
boolean available = intBuf16.get(0) != 0;
|
boolean available = intBuf16.get(0) != 0;
|
||||||
@ -314,13 +314,13 @@ 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);
|
||||||
|
|
||||||
useVBO = false;
|
useVBO = false;
|
||||||
|
|
||||||
// NOTE: SDK_INT is only available since 1.6,
|
// NOTE: SDK_INT is only available since 1.6,
|
||||||
// but for jME3 it doesn't matter since android versions 1.5 and below
|
// but for jME3 it doesn't matter since android versions 1.5 and below
|
||||||
// are not supported.
|
// are not supported.
|
||||||
if (Build.VERSION.SDK_INT >= 9){
|
if (Build.VERSION.SDK_INT >= 9){
|
||||||
@ -329,8 +329,8 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
} else {
|
} else {
|
||||||
useVBO = false;
|
useVBO = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.log(Level.INFO, "Caps: {0}", caps);
|
logger.log(Level.INFO, "Caps: {0}", caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -400,7 +400,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
|
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
|
||||||
context.depthTestEnabled = false;
|
context.depthTestEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.isDepthWrite() && !context.depthWriteEnabled) {
|
if (state.isDepthWrite() && !context.depthWriteEnabled) {
|
||||||
GLES20.glDepthMask(true);
|
GLES20.glDepthMask(true);
|
||||||
context.depthWriteEnabled = true;
|
context.depthWriteEnabled = true;
|
||||||
@ -594,7 +594,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
statistics.onShaderUse(shader, false);
|
statistics.onShaderUse(shader, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateUniform(Shader shader, Uniform uniform) {
|
protected void updateUniform(Shader shader, Uniform uniform) {
|
||||||
int shaderId = shader.getId();
|
int shaderId = shader.getId();
|
||||||
|
|
||||||
@ -752,7 +752,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
source.setId(id);
|
source.setId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!source.getLanguage().equals("GLSL100")) {
|
if (!source.getLanguage().equals("GLSL100")) {
|
||||||
throw new RendererException("This shader cannot run in OpenGL ES. "
|
throw new RendererException("This shader cannot run in OpenGL ES. "
|
||||||
+ "Only GLSL 1.0 shaders are supported.");
|
+ "Only GLSL 1.0 shaders are supported.");
|
||||||
@ -876,7 +876,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShader(Shader shader) {
|
public void setShader(Shader shader) {
|
||||||
if (shader == null) {
|
if (shader == null) {
|
||||||
throw new IllegalArgumentException("Shader cannot be null");
|
throw new IllegalArgumentException("Shader cannot be null");
|
||||||
@ -885,7 +885,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
updateShaderData(shader);
|
updateShaderData(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: might want to check if any of the
|
// NOTE: might want to check if any of the
|
||||||
// sources need an update?
|
// sources need an update?
|
||||||
|
|
||||||
assert shader.getId() > 0;
|
assert shader.getId() > 0;
|
||||||
@ -900,7 +900,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
logger.warning("Shader source is not uploaded to GPU, cannot delete.");
|
logger.warning("Shader source is not uploaded to GPU, cannot delete.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
source.clearUpdateNeeded();
|
source.clearUpdateNeeded();
|
||||||
GLES20.glDeleteShader(source.getId());
|
GLES20.glDeleteShader(source.getId());
|
||||||
source.resetObject();
|
source.resetObject();
|
||||||
@ -911,14 +911,14 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
logger.warning("Shader is not uploaded to GPU, cannot delete.");
|
logger.warning("Shader is not uploaded to GPU, cannot delete.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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());
|
||||||
deleteShaderSource(source);
|
deleteShaderSource(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLES20.glDeleteProgram(shader.getId());
|
GLES20.glDeleteProgram(shader.getId());
|
||||||
statistics.onDeleteShader();
|
statistics.onDeleteShader();
|
||||||
shader.resetObject();
|
shader.resetObject();
|
||||||
@ -942,18 +942,18 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
int dstW = 0;
|
int dstW = 0;
|
||||||
int dstH = 0;
|
int dstH = 0;
|
||||||
int prevFBO = context.boundFBO;
|
int prevFBO = context.boundFBO;
|
||||||
|
|
||||||
if (src != null && src.isUpdateNeeded())
|
if (src != null && src.isUpdateNeeded())
|
||||||
updateFrameBuffer(src);
|
updateFrameBuffer(src);
|
||||||
|
|
||||||
if (dst != null && dst.isUpdateNeeded())
|
if (dst != null && dst.isUpdateNeeded())
|
||||||
updateFrameBuffer(dst);
|
updateFrameBuffer(dst);
|
||||||
|
|
||||||
if (src == null){
|
if (src == null){
|
||||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
|
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
|
||||||
// srcW = viewWidth;
|
// srcW = viewWidth;
|
||||||
// srcH = viewHeight;
|
// srcH = viewHeight;
|
||||||
}else{
|
}else{
|
||||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src.getId());
|
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src.getId());
|
||||||
srcW = src.getWidth();
|
srcW = src.getWidth();
|
||||||
srcH = src.getHeight();
|
srcH = src.getHeight();
|
||||||
@ -971,7 +971,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
0, 0, dstW, dstH,
|
0, 0, dstW, dstH,
|
||||||
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
|
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
|
||||||
GL_NEAREST);
|
GL_NEAREST);
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFBO);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, prevFBO);
|
||||||
try {
|
try {
|
||||||
checkFrameBufferError();
|
checkFrameBufferError();
|
||||||
@ -1034,16 +1034,16 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
id = intBuf1.get(0);
|
id = intBuf1.get(0);
|
||||||
rb.setId(id);
|
rb.setId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.boundRB != id){
|
if (context.boundRB != id){
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, id);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, id);
|
||||||
context.boundRB = id;
|
context.boundRB = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fb.getWidth() > maxRBSize || fb.getHeight() > maxRBSize)
|
if (fb.getWidth() > maxRBSize || fb.getHeight() > maxRBSize)
|
||||||
throw new UnsupportedOperationException("Resolution "+fb.getWidth()+
|
throw new UnsupportedOperationException("Resolution "+fb.getWidth()+
|
||||||
":"+fb.getHeight()+" is not supported.");
|
":"+fb.getHeight()+" is not supported.");
|
||||||
|
|
||||||
if (fb.getSamples() > 0 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample){
|
if (fb.getSamples() > 0 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample){
|
||||||
int samples = fb.getSamples();
|
int samples = fb.getSamples();
|
||||||
if (maxFBOSamples < samples){
|
if (maxFBOSamples < samples){
|
||||||
@ -1075,7 +1075,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
}else if (attachmentSlot < 0 || attachmentSlot >= 16){
|
}else if (attachmentSlot < 0 || attachmentSlot >= 16){
|
||||||
throw new UnsupportedOperationException("Invalid FBO attachment slot: "+attachmentSlot);
|
throw new UnsupportedOperationException("Invalid FBO attachment slot: "+attachmentSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GL_COLOR_ATTACHMENT0_EXT + attachmentSlot;
|
return GL_COLOR_ATTACHMENT0_EXT + attachmentSlot;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -1089,7 +1089,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
Image image = tex.getImage();
|
Image image = tex.getImage();
|
||||||
if (image.isUpdateNeeded())
|
if (image.isUpdateNeeded())
|
||||||
updateTexImageData(image, tex.getType(), tex.getMinFilter().usesMipMapLevels());
|
updateTexImageData(image, tex.getType(), tex.getMinFilter().usesMipMapLevels());
|
||||||
|
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
|
||||||
convertAttachmentSlot(rb.getSlot()),
|
convertAttachmentSlot(rb.getSlot()),
|
||||||
convertTextureType(tex.getType()),
|
convertTextureType(tex.getType()),
|
||||||
@ -1133,41 +1133,41 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
id = intBuf1.get(0);
|
id = intBuf1.get(0);
|
||||||
fb.setId(id);
|
fb.setId(id);
|
||||||
objManager.registerForCleanup(fb);
|
objManager.registerForCleanup(fb);
|
||||||
|
|
||||||
statistics.onNewFrameBuffer();
|
statistics.onNewFrameBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.boundFBO != id){
|
if (context.boundFBO != id){
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id);
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer.RenderBuffer depthBuf = fb.getDepthBuffer();
|
FrameBuffer.RenderBuffer depthBuf = fb.getDepthBuffer();
|
||||||
if (depthBuf != null){
|
if (depthBuf != null){
|
||||||
updateFrameBufferAttachment(fb, depthBuf);
|
updateFrameBufferAttachment(fb, depthBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < fb.getNumColorBuffers(); i++){
|
for (int i = 0; i < fb.getNumColorBuffers(); i++){
|
||||||
FrameBuffer.RenderBuffer colorBuf = fb.getColorBuffer(i);
|
FrameBuffer.RenderBuffer colorBuf = fb.getColorBuffer(i);
|
||||||
updateFrameBufferAttachment(fb, colorBuf);
|
updateFrameBufferAttachment(fb, colorBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
fb.clearUpdateNeeded();
|
fb.clearUpdateNeeded();
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void setMainFrameBufferOverride(FrameBuffer fb){
|
public void setMainFrameBufferOverride(FrameBuffer fb){
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFrameBuffer(FrameBuffer fb) {
|
public void setFrameBuffer(FrameBuffer fb) {
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
public void setFrameBuffer(FrameBuffer fb) {
|
public void setFrameBuffer(FrameBuffer fb) {
|
||||||
if (lastFb == fb)
|
if (lastFb == fb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// generate mipmaps for last FB if needed
|
// generate mipmaps for last FB if needed
|
||||||
if (lastFb != null){
|
if (lastFb != null){
|
||||||
for (int i = 0; i < lastFb.getNumColorBuffers(); i++){
|
for (int i = 0; i < lastFb.getNumColorBuffers(); i++){
|
||||||
@ -1180,14 +1180,14 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (fb == null){
|
if (fb == null){
|
||||||
// unbind any fbos
|
// unbind any fbos
|
||||||
if (context.boundFBO != 0){
|
if (context.boundFBO != 0){
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||||
statistics.onFrameBufferUse(null, true);
|
statistics.onFrameBufferUse(null, true);
|
||||||
|
|
||||||
context.boundFBO = 0;
|
context.boundFBO = 0;
|
||||||
}
|
}
|
||||||
// select back buffer
|
// select back buffer
|
||||||
@ -1199,19 +1199,19 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
glReadBuffer(initialReadBuf);
|
glReadBuffer(initialReadBuf);
|
||||||
context.boundReadBuf = -1;
|
context.boundReadBuf = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastFb = null;
|
lastFb = null;
|
||||||
}else{
|
}else{
|
||||||
if (fb.isUpdateNeeded())
|
if (fb.isUpdateNeeded())
|
||||||
updateFrameBuffer(fb);
|
updateFrameBuffer(fb);
|
||||||
|
|
||||||
if (context.boundFBO != fb.getId()){
|
if (context.boundFBO != fb.getId()){
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb.getId());
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb.getId());
|
||||||
statistics.onFrameBufferUse(fb, true);
|
statistics.onFrameBufferUse(fb, true);
|
||||||
|
|
||||||
// update viewport to reflect framebuffer's resolution
|
// update viewport to reflect framebuffer's resolution
|
||||||
setViewPort(0, 0, fb.getWidth(), fb.getHeight());
|
setViewPort(0, 0, fb.getWidth(), fb.getHeight());
|
||||||
|
|
||||||
context.boundFBO = fb.getId();
|
context.boundFBO = fb.getId();
|
||||||
}else{
|
}else{
|
||||||
statistics.onFrameBufferUse(fb, false);
|
statistics.onFrameBufferUse(fb, false);
|
||||||
@ -1233,12 +1233,12 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
throw new UnsupportedOperationException("Framebuffer has more"
|
throw new UnsupportedOperationException("Framebuffer has more"
|
||||||
+ " targets than are supported"
|
+ " targets than are supported"
|
||||||
+ " on the system!");
|
+ " on the system!");
|
||||||
|
|
||||||
if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()){
|
if (context.boundDrawBuf != 100 + fb.getNumColorBuffers()){
|
||||||
intBuf16.clear();
|
intBuf16.clear();
|
||||||
for (int i = 0; i < fb.getNumColorBuffers(); i++)
|
for (int i = 0; i < fb.getNumColorBuffers(); i++)
|
||||||
intBuf16.put( GL_COLOR_ATTACHMENT0_EXT + i );
|
intBuf16.put( GL_COLOR_ATTACHMENT0_EXT + i );
|
||||||
|
|
||||||
intBuf16.flip();
|
intBuf16.flip();
|
||||||
glDrawBuffers(intBuf16);
|
glDrawBuffers(intBuf16);
|
||||||
context.boundDrawBuf = 100 + fb.getNumColorBuffers();
|
context.boundDrawBuf = 100 + fb.getNumColorBuffers();
|
||||||
@ -1252,12 +1252,12 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert fb.getId() >= 0;
|
assert fb.getId() >= 0;
|
||||||
assert context.boundFBO == fb.getId();
|
assert context.boundFBO == fb.getId();
|
||||||
lastFb = fb;
|
lastFb = fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
checkFrameBufferError();
|
checkFrameBufferError();
|
||||||
} catch (IllegalStateException ex){
|
} catch (IllegalStateException ex){
|
||||||
@ -1290,7 +1290,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
if (rb == null)
|
if (rb == null)
|
||||||
throw new IllegalArgumentException("Specified framebuffer" +
|
throw new IllegalArgumentException("Specified framebuffer" +
|
||||||
" does not have a colorbuffer");
|
" does not have a colorbuffer");
|
||||||
|
|
||||||
setFrameBuffer(fb);
|
setFrameBuffer(fb);
|
||||||
if (context.boundReadBuf != rb.getSlot()){
|
if (context.boundReadBuf != rb.getSlot()){
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
|
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + rb.getSlot());
|
||||||
@ -1299,7 +1299,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
}else{
|
}else{
|
||||||
setFrameBuffer(null);
|
setFrameBuffer(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
glReadPixels(vpX, vpY, vpW, vpH, GL_RGBA GL_BGRA, GL_UNSIGNED_BYTE, byteBuf);
|
glReadPixels(vpX, vpY, vpW, vpH, GL_RGBA GL_BGRA, GL_UNSIGNED_BYTE, byteBuf);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -1324,18 +1324,18 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||||
context.boundFBO = 0;
|
context.boundFBO = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fb.getDepthBuffer() != null){
|
if (fb.getDepthBuffer() != null){
|
||||||
deleteRenderBuffer(fb, fb.getDepthBuffer());
|
deleteRenderBuffer(fb, fb.getDepthBuffer());
|
||||||
}
|
}
|
||||||
if (fb.getColorBuffer() != null){
|
if (fb.getColorBuffer() != null){
|
||||||
deleteRenderBuffer(fb, fb.getColorBuffer());
|
deleteRenderBuffer(fb, fb.getColorBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
intBuf1.put(0, fb.getId());
|
intBuf1.put(0, fb.getId());
|
||||||
glDeleteFramebuffersEXT(intBuf1);
|
glDeleteFramebuffersEXT(intBuf1);
|
||||||
fb.resetObject();
|
fb.resetObject();
|
||||||
|
|
||||||
statistics.onDeleteFrameBuffer();
|
statistics.onDeleteFrameBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1417,16 +1417,16 @@ 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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (tex.getAnisotropicFilter() > 1){
|
if (tex.getAnisotropicFilter() > 1){
|
||||||
|
|
||||||
if (GLContext.getCapabilities().GL_EXT_texture_filter_anisotropic){
|
if (GLContext.getCapabilities().GL_EXT_texture_filter_anisotropic){
|
||||||
glTexParameterf(target,
|
glTexParameterf(target,
|
||||||
EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||||
tex.getAnisotropicFilter());
|
tex.getAnisotropicFilter());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// repeat modes
|
// repeat modes
|
||||||
@ -1490,7 +1490,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
GLES20.glBindTexture(target, texId);
|
GLES20.glBindTexture(target, texId);
|
||||||
context.boundTextures[0] = img;
|
context.boundTextures[0] = img;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean needMips = false;
|
boolean needMips = false;
|
||||||
if (img.isGeneratedMipmapsRequired()) {
|
if (img.isGeneratedMipmapsRequired()) {
|
||||||
needMips = true;
|
needMips = true;
|
||||||
@ -1507,13 +1507,13 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
throw new RendererException("Cannot upload texture " + img + ". The maximum supported texture resolution is " + maxTexSize);
|
throw new RendererException("Cannot upload texture " + img + ". The maximum supported texture resolution is " + maxTexSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target == GLES20.GL_TEXTURE_CUBE_MAP) {
|
if (target == GLES20.GL_TEXTURE_CUBE_MAP) {
|
||||||
// Upload a cube map / sky box
|
// Upload a cube map / sky box
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<AndroidImageInfo> bmps = (List<AndroidImageInfo>) img.getEfficentData();
|
List<AndroidImageInfo> bmps = (List<AndroidImageInfo>) img.getEfficentData();
|
||||||
if (bmps != null) {
|
if (bmps != null) {
|
||||||
// Native android bitmap
|
// Native android bitmap
|
||||||
if (bmps.size() != 6) {
|
if (bmps.size() != 6) {
|
||||||
throw new UnsupportedOperationException("Invalid texture: " + img
|
throw new UnsupportedOperationException("Invalid texture: " + img
|
||||||
+ "Cubemap textures must contain 6 data units.");
|
+ "Cubemap textures must contain 6 data units.");
|
||||||
@ -1752,7 +1752,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
// delete buffer
|
// delete buffer
|
||||||
intBuf1.put(0, bufId);
|
intBuf1.put(0, bufId);
|
||||||
intBuf1.position(0).limit(1);
|
intBuf1.position(0).limit(1);
|
||||||
|
|
||||||
GLES20.glDeleteBuffers(1, intBuf1);
|
GLES20.glDeleteBuffers(1, intBuf1);
|
||||||
vb.resetObject();
|
vb.resetObject();
|
||||||
}
|
}
|
||||||
@ -1824,7 +1824,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
context.boundArrayVBO = bufId;
|
context.boundArrayVBO = bufId;
|
||||||
}
|
}
|
||||||
|
|
||||||
vb.getData().clear();
|
vb.getData().rewind();
|
||||||
|
|
||||||
Android22Workaround.glVertexAttribPointer(loc,
|
Android22Workaround.glVertexAttribPointer(loc,
|
||||||
vb.getNumComponents(),
|
vb.getNumComponents(),
|
||||||
@ -1935,7 +1935,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
count);
|
count);
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
indexData.clear();
|
indexData.rewind();
|
||||||
GLES20.glDrawElements(
|
GLES20.glDrawElements(
|
||||||
convertElementMode(mesh.getMode()),
|
convertElementMode(mesh.getMode()),
|
||||||
indexBuf.getData().limit(),
|
indexBuf.getData().limit(),
|
||||||
@ -1980,7 +1980,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
id = temp.get(0);
|
id = temp.get(0);
|
||||||
mesh.setId(id);
|
mesh.setId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.boundVertexArray != id){
|
if (context.boundVertexArray != id){
|
||||||
// ARBVertexArrayObject.glBindVertexArray(id);
|
// ARBVertexArrayObject.glBindVertexArray(id);
|
||||||
GLES20.glBindVertexArray(id);
|
GLES20.glBindVertexArray(id);
|
||||||
@ -1992,9 +1992,9 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
updateBufferData(interleavedData);
|
updateBufferData(interleavedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (VertexBuffer vb : mesh.getBufferList().getArray()){
|
for (VertexBuffer vb : mesh.getBufferList().getArray()){
|
||||||
|
|
||||||
if (vb.getBufferType() == Type.InterleavedData
|
if (vb.getBufferType() == Type.InterleavedData
|
||||||
|| vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
|| vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
||||||
|| vb.getBufferType() == Type.Index) {
|
|| vb.getBufferType() == Type.Index) {
|
||||||
@ -2019,7 +2019,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
*/
|
*/
|
||||||
private void renderMeshVertexArray(Mesh mesh, int lod, int count) {
|
private void renderMeshVertexArray(Mesh mesh, int lod, int count) {
|
||||||
// IntMap<VertexBuffer> buffers = mesh.getBuffers();
|
// IntMap<VertexBuffer> buffers = mesh.getBuffers();
|
||||||
for (VertexBuffer vb : mesh.getBufferList().getArray()){
|
for (VertexBuffer vb : mesh.getBufferList().getArray()){
|
||||||
|
|
||||||
if (vb.getBufferType() == Type.InterleavedData
|
if (vb.getBufferType() == Type.InterleavedData
|
||||||
|| vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
|| vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
||||||
@ -2065,8 +2065,8 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
} else {
|
} else {
|
||||||
indices = mesh.getBuffer(Type.Index);// buffers.get(Type.Index.ordinal());
|
indices = mesh.getBuffer(Type.Index);// buffers.get(Type.Index.ordinal());
|
||||||
}
|
}
|
||||||
for (VertexBuffer vb : mesh.getBufferList().getArray()){
|
for (VertexBuffer vb : mesh.getBufferList().getArray()){
|
||||||
|
|
||||||
if (vb.getBufferType() == Type.InterleavedData
|
if (vb.getBufferType() == Type.InterleavedData
|
||||||
|| vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
|| vb.getUsage() == Usage.CpuOnly // ignore cpu-only buffers
|
||||||
|| vb.getBufferType() == Type.Index) {
|
|| vb.getBufferType() == Type.Index) {
|
||||||
@ -2131,7 +2131,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
int vertCount = mesh.getVertexCount();
|
int vertCount = mesh.getVertexCount();
|
||||||
Buffer indexData = indexBuf.getData();
|
Buffer indexData = indexBuf.getData();
|
||||||
indexData.clear();
|
indexData.rewind();
|
||||||
|
|
||||||
if (mesh.getMode() == Mode.Hybrid) {
|
if (mesh.getMode() == Mode.Hybrid) {
|
||||||
int[] modeStart = mesh.getModeStart();
|
int[] modeStart = mesh.getModeStart();
|
||||||
@ -2202,7 +2202,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
if ((attribs[loc] != vb) || vb.isUpdateNeeded()) {
|
if ((attribs[loc] != vb) || vb.isUpdateNeeded()) {
|
||||||
// NOTE: Use data from interleaved buffer if specified
|
// NOTE: Use data from interleaved buffer if specified
|
||||||
VertexBuffer avb = idb != null ? idb : vb;
|
VertexBuffer avb = idb != null ? idb : vb;
|
||||||
avb.getData().clear();
|
avb.getData().rewind();
|
||||||
avb.getData().position(vb.getOffset());
|
avb.getData().position(vb.getOffset());
|
||||||
|
|
||||||
// Upload attribute data
|
// Upload attribute data
|
||||||
|
Loading…
x
Reference in New Issue
Block a user