I have reports from my users about issues with rendering of half-floats data on certain devices with Mali GPUs (Huawei Honor 9 and Samsung Galaxy S10+ w/ Mali G71 and G76 respectively).
It results in garbled rendering on these devices while works correctly on Adreno and PowerVR GPUs.
I've double checked code and it seems to be correct:
...
if (model.hasHalfFloats()) {
GLES20.glVertexAttribPointer(shaderOutline.getRm_Vertex(), 3, GLES20.GL_FLOAT, false, 18, 0);
GLES20.glVertexAttribPointer(shaderOutline.getRm_Normal(), 3, getGL_HALF_FLOAT(), false, 18, 12);
} else {
GLES20.glVertexAttribPointer(shaderOutline.getRm_Vertex(), 3, GLES20.GL_FLOAT, false, 24, 0);
GLES20.glVertexAttribPointer(shaderOutline.getRm_Normal(), 3, GLES20.GL_FLOAT, false, 24, 12);
}
...
/**
* Returns either OES extension for GL 16-bit floats (if used in ES 2.0) or ES 3.0 constant.
*/
protected int getGL_HALF_FLOAT() {
if(isES3()) {
return GLES30.GL_HALF_FLOAT;
} else {
return GL_HALF_FLOAT_OES;
}
}
Code seems to correctly detect OpenGL ES 3 and use GLES30.GL_HALF_FLOAT value in getGL_HALF_FLOAT().
Sample shader code:
vertexShaderCode = "attribute vec4 rm_Vertex;\r\n" +
"attribute mediump vec3 rm_Normal;\r\n" +
"uniform mat4 view_proj_matrix;\r\n" +
"uniform float uThickness1;\r\n" +
"void main( void )\r\n" +
"{\r\n" +
" vec4 pos = vec4(rm_Vertex.xyz, 1.0);\r\n" +
" float dist = (view_proj_matrix * pos).w;\r\n" +
" vec4 normal = vec4(rm_Normal, 0.0);\r\n" +
" pos += normal * uThickness1 * dist;\r\n" +
" gl_Position = view_proj_matrix * pos;\r\n" +
"}";
fragmentShaderCode = "precision mediump float;\r\n" +
"uniform vec4 uColor;\r\n" +
"void main( void )\r\n" +
"{\r\n" +
" gl_FragColor = uColor;\r\n" +
"}";
I think you have an alignment problem. From this snippet (and your vertex shader):
GLES20.glVertexAttribPointer(shaderOutline.getRm_Normal(), 3, getGL_HALF_FLOAT(), false, 18, 12);
I can infer that you're attempting a vertex structure like so:
float fPos[3];
half fNormal[3];
You have come up with a vertex stride of 18 which has presumably been arrived at by adding up the individual sizes of the elements (3*sizeof(float))+(3*sizeof(half)) = 12 + 6 = 18.
However, the stride should be 20 because otherwise your vertices are misaligned. The 4-byte floats must start on a 4-byte boundary, but that is not the case.
From the GLES3 spec:
Clients must align data elements consistently with the requirements of the client platform, with an additional base-level requirement that an offset within a buffer to a datum comprising N basic machine units be a multiple of N
Related
I'm trying to implement 3d Lighting on a model using OpenGL ES. I followed this guide https://arm-software.github.io/opengl-es-sdk-for-android/lighting.html, but I cannot figure out why I keep getting this error : Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16.
Both coordinates and norms are Float array of size 9 which are later cast to floatBuffers. When I just want to draw shape everything works (therefore vertexBuffer is probably ok), but when I try to use norms everything breaks down.
I would really appreciate any help with this problem.
Buffers creation:
private var vertexBuffer: FloatBuffer =
ByteBuffer.allocateDirect(triangleCoordinates.size * 4).run {
order(ByteOrder.nativeOrder())
asFloatBuffer().apply {
put(triangleCoordinates)
position(0)
}
}
private var normalsBuffer: FloatBuffer =
ByteBuffer.allocateDirect(normals.size * 4).run {
order(ByteOrder.nativeOrder())
asFloatBuffer().apply {
put(normals)
position(0)
}
}
vertex Shader Code
private val vertexShaderCode =
"attribute vec4 vertexPosition;\n" +
"attribute vec3 vertexColour;\n" +
"attribute vec3 vertexNormal;\n" +
"varying vec3 fragColour;\n" +
"uniform mat4 modelView;\n" +
"void main(){\n" +
/* [Setup scene vectors.] */
" vec3 transformedVertexNormal = normalize((modelView * vec4(vertexNormal, 0.0)).xyz);" +
" vec3 inverseLightDirection = normalize(vec3(0.0, 1.0, 1.0));\n" +
" fragColour = vec3(0.0);\n" +
/* [Setup scene vectors.] */
"\n" +
/* [Calculate the diffuse component.] */
" vec3 diffuseLightIntensity = vec3(1.0, 1.0, 1.0);\n" +
" vec3 vertexDiffuseReflectionConstant = vertexColour;\n" +
" float normalDotLight = max(0.0, dot(transformedVertexNormal, inverseLightDirection));\n" +
" fragColour += normalDotLight * vertexDiffuseReflectionConstant * diffuseLightIntensity;\n" +
" /* Make sure the fragment colour is between 0 and 1. */" +
" clamp(fragColour, 0.0, 1.0);\n" +
"\n" +
" gl_Position = modelView * vertexPosition;\n" +
"}\n";```
Fragment shader:
private val fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vertexColour;" +
"void main() {" +
" gl_FragColor = vertexColour;" +
"}"
Drawing code:
fun draw(mvpMatrix: FloatArray) {
positionHandle = glGetAttribLocation(program, "vertexPosition")
vertexNormalLocation = glGetAttribLocation(program, "vertexNormal")
mColorHandle = glGetUniformLocation(program, "vertexColour").also { colorHandle ->
glUniform4fv(colorHandle, 1, color, 0)
}
vPMatrixHandle = glGetUniformLocation(program, "modelView")
glUniformMatrix4fv(vPMatrixHandle, 1, false, mvpMatrix, 0)
glUseProgram(program)
glVertexAttribPointer(
positionHandle,
3,
GLES20.GL_FLOAT,
false,
vertexStride,
vertexBuffer
)
glVertexAttribPointer(
vertexNormalLocation,
3,
GL_FLOAT,
false,
0,
normalsBuffer
)
glEnableVertexAttribArray(positionHandle)
glEnableVertexAttribArray(vertexNormalLocation)
glDrawArrays(GL_TRIANGLES, 0, vertexCount)
glDisableVertexAttribArray(positionHandle)
}
Error mgs:
2021-09-19 13:41:59.783 19419-19472/com.example.druggame E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glVertexAttribPointer:637 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2021-09-19 13:41:59.783 19419-19472/com.example.druggame E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glEnableVertexAttribArray:1028 GL error 0x501
Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
4294967295 is hexadecimal ffffffff respectively -1. glGetAttribLocation returns this value if an attribute resource does not exist in the liked program. You get this value, because one of the attribute is not an active program resource.
If an attribute is not used (directly or indirectly), it is optimized by the shader compiler or linker and is not given an attribute index.
In your case the attributes have no attribute indes, because the vertex shader output fragColour is not an input to the fragment shader. Use fragColour in the fragment shader:
precision mediump float;
varying vec3 fragColour;
void main()
{
gl_FragColor = vec4(fragColour, 1.0);
}
UPDATED
I'm trying to draw texture with openGL ES3 and used instanced drawing for my drawing application. This is my vertex shader
#version 300 es
precision highp float;
uniform mat3 u_Matrix;
in vec2 Position;
in vec2 TexPosition;
struct Data {
vec2 pos;
vec2 scale;
uint color;
float rotation;
};
layout(std140) uniform InstanceData {
Data data[256];
};
out vec4 v_Color;
out vec2 v_TexPosition;
void main() {
vec2 endPos = Position * data[gl_InstanceID].scale;
if (data[gl_InstanceID].rotation != 0.0) {
float cos = cos(data[gl_InstanceID].rotation);
float sin = sin(data[gl_InstanceID].rotation);
endPos = vec2(endPos.x * cos - endPos.y * sin, endPos.x * sin +
endPos.y * cos) + data[gl_InstanceID].pos;
} else {
endPos = endPos + data[gl_InstanceID].pos;
}
uint fColor = data[gl_InstanceID].color;
v_Color.r = float((fColor & 0x00FF0000U) >> 16) / 255.0;
v_Color.g = float((fColor & 0x0000FF00U) >> 8) / 255.0;
v_Color.b = float(fColor & 0x000000FFU) / 255.0;
v_Color.a = float((fColor & 0xFF000000U) >> 24) / 255.0;
v_TexPosition = TexPosition;
gl_Position = vec4(u_Matrix * vec3(endPos, 1.0), 1.0);
}
and this is my fragment_shader
#version 300 es
precision highp float;
in vec2 v_TexPosition;
in vec4 v_Color;
uniform sampler2D u_Texture2D;
out vec4 fragColor;
void main() {
vec4 color = texture(u_Texture2D, v_TexPosition);
fragColor = vec4(v_Color.rgb, color.a * v_Color.a);
}
When I created the program, attached shaders and try to link to program, the app is freezes on line glLinkProgram. Shaders and program have normal id.
This work normal on some devices (sony xperia Z -android 5.0, smasung s7 edge android 7, nexus 5x - android 7, nexus 6p - android 7) but this doesn't work on other part of devices(motX- android 5.1, smasung s5 android 6.0). All devices have android version greater then 5.0, and in code I checked for opengl ES3 supporting.
Is there some reason for this? Is it from device(how to check it)? or did I did something wrong?
I'm passed data to instanceBuffer with this way :
instanceBuffer.putFloat(posX);
instanceBuffer.putFloat(posY);
instanceBuffer.putFloat(scaleX);
instanceBuffer.putFloat(scaleY);
instanceBuffer.putInt(colorARGB);
instanceBuffer.putFloat((float) Math.toRadians(rotate));
instanceBuffer.position(instanceBuffer.position() + 8);
used +8 offsets because struct data read elements with vec4 size (16byte)
When I write my struct only with one vec4 :
struct Data {
vec4 posAndScale;
};
and pass data:
instanceBuffer.putFloat(posX);
instanceBuffer.putFloat(posY);
instanceBuffer.putFloat(scaleX);
instanceBuffer.putFloat(scaleY);
This works on all devices,
But when I added one more vec4 :
struct Data {
vec4 posAndScale;
vec4 color;
};
and pass data
instanceBuffer.putFloat(posX);
instanceBuffer.putFloat(posY);
instanceBuffer.putFloat(scaleX);
instanceBuffer.putFloat(scaleY);
instanceBuffer.putFloat(color.r);
instanceBuffer.putFloat(color.g);
instanceBuffer.putFloat(color.b);
instanceBuffer.putFloat(color.a);
app not freezes but nothing happened when I try to draw. It's seems like on some devices std140 work with different way or like data not passed to shader when wrote struct with 2 vec4-s
Ok I found some solution. This work normally since opengl es versionl 3.1. I think 3.0 version doesn't support struct data which contains float or int element.
I experienced the same issue. The Nexus 7 (2013) was freezing when I called gllinkprogram(). I found that this only happened when I had 'if statements' in my shader. I was able to change both of my 'if statements' into 'conditional operators' and it worked.
E.g. (cond)? cond1:cond2
I'm new to OpenGL and today I was trying to compile some shader programs for GPGPU usage of OpenGL in android OS.
I have two questions:
1) I only want to program fragment shader, Is it necessary to program the vertex shader too?
2) I face some Errors while compiling my shader source code.
My source code is defined as :
final String src = "#version 310 es\n" +
"uniform sampler2D texUnit;\n" +
"uniform int sequence;\n" +
"void main(void)\n" +
"{\n" +
"const vec3 DotValue = {0.299f , 0.587f , 0.114f};\n" +
"vec2 texCoord = gl_TexCoord[0].xy;\n" +
"vec4 CurrentPixelData = texture2D(texUnit, texCoord);\n" +
"float temp = CurrentPixelData.x * DotValue.x + CurrentPixelData.y * DotValue.y + CurrentPixelData.z * DotValue.z;\n" +
"vec4 result = {temp,temp,temp,CurrentPixelData.w};\n" +
"gl_FragColor = result;\n" +
"}\n";
and the code for creating the shader is:
int fragment = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fragment,src);
GLES20.glCompileShader(fragment);
int[] compiled = new int[1];
GLES20.glGetShaderiv(fragment, GLES20.GL_COMPILE_STATUS, compiled, 0); //compile[0] != 0 : compiled successfully
if (compiled[0] == 0) {
Log.e(TAG, "Could not compile shader: ");
Log.e(TAG, GLES20.glGetShaderInfoLog(fragment));
GLES20.glDeleteShader(fragment);
fragment = 0;
} else {
Log.i(TAG, "Compiled shader with source length " + src.length());
}
But when i try to debug my application, there are several errors about shader compilation in the logcat:
0:6: L0001: Expected token ';', found '{'
0:7: L0002: Undeclared variable 'gl_TexCoord'
0:8: L0002: No matching function for call to 'texture2D'
0:9: L0002: Undeclared variable 'CurrentPixelData'
0:10: L0001: Expected token ';', found '{'
0:11: L0002: Undeclared variable 'gl_FragColor'
Can anyone help me what is wrong with my code?
Thanks in advance.
You do need both a vertex shader and a fragment shader.
The syntax errors are already highlighted by the shader compilation log you captured. Providing some more detail on them:
You need to use constructor syntax to initialize vectors:
const vec3 DotValue = vec3(0.299 , 0.587, 0.114);
gl_TexCoord is not a built-in variable. You may have seen it in code samples for desktop OpenGL, where it used to exist. But it's deprecated even there, and never was present in OpenGL ES. You need to pass the texture coordinates into the shader yourself.
texture2D() is not a built-in function. The function for sampling a 2D texture used to be named like this in older GLSL version, but is now overloaded for various sampler types under the name texture():
vec4 CurrentPixelData = texture(texUnit, texCoord);
Looks like just a follow-up error from the previous one.
Same as error 1:
vec4 result = vec4(temp, temp, temp, CurrentPixelData.w);
gl_FragColor used to be a built-in variable in older GLSL versions, but is now deprecated and removed. You need to define your own variable with the qualifier out to define the variable(s) used as shader outputs.
You must write a vertex shader. gl_Position must be assigned values to create triangles and then pixels (fragments).
If you're using texture mapping, you need to assign a varying variable with the texture coordinate assigned to the vertex.
Later, these coordinates are interpolated for each fragment.
The most basic vertex shader would be:
const char* simpleVertexShader=
"attribute vec4 position;"
"attribute vec4 inputTextureCoordinate;
"varying vec2 textureCoordinate;"
"void main(){"
"gl_Position = position;"
"textureCoordinate = inputTextureCoordinate.xy;"
"}";
In you're fragment shader you have syntax error in vec3 and vec4 init.
It should be done like this:
"const vec3 DotValue = vec3(0.299 , 0.587 , 0.114);\n"
and
"vec4 result = vec4(temp,temp,temp,CurrentPixelData.w);\n"
Notice the float literals don't need the 'f' postfix in glsl.
Your fixed code:
final String src = "#version 310 es\n" +
"precision highp float;"
"uniform sampler2D texUnit;\n" +
"varying vec2 textureCoordinate" +
"void main(void)\n" +
"{\n" +
"const vec3 DotValue = vec3(0.299 , 0.587 , 0.114);\n" +
"vec2 texCoord = textureCoordinate;\n" +
"vec4 CurrentPixelData = texture2D(texUnit, texCoord);\n" +
"float temp = CurrentPixelData.x * DotValue.x + CurrentPixelData.y * DotValue.y + CurrentPixelData.z * DotValue.z;\n" +
"vec4 result = vec4(temp,temp,temp,CurrentPixelData.w);\n" +
"gl_FragColor = result;\n" +
"}\n";
It would be a lot easier for you if you start with a good openGL tutorial.
Good Luck!
I am learning about OpenGL ES and in particular, compute shaders in OpenGL ES 3.1, specifically, in Android 5.0.1.
I have 3 shaders defined (compute, vertex, and fragment) and attached to two different programs, one for the compute shader and one for the vertex and fragment shaders.
I have no problem when I only use the vertex and fragment shaders but now that I added the compute shader I get the following error:
02-11 20:02:10.375 13243-13264/com.example.daan.daggl2 I/VERSION﹕ OpenGL ES 3.1 NVIDIA 349.00
02-11 20:02:10.472 13243-13264/com.example.daan.daggl2 A/libc﹕ Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 13264 (GLThread 9847)
I'm trying to figure out what I'm missing but I'm new to this topic and I'm not sure where to begin looking for the problem.
The object's constructor is:
public Triangle() {
buffers = new int[1];
GLES31.glGenBuffers(1, buffers, 0);
gVBO = buffers[0];
// set up the vertex and fragment shaders
int vertexShader = MyGLRenderer.loadShader(
GLES31.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = MyGLRenderer.loadShader(
GLES31.GL_FRAGMENT_SHADER, fragmentShaderCode);
program = GLES31.glCreateProgram();
GLES31.glAttachShader(program, vertexShader);
GLES31.glAttachShader(program, fragmentShader);
GLES31.glLinkProgram(program);
checkGLError("LinkProgram/program");
// set up the compute shader
int computeShader = MyGLRenderer.loadShader(
GLES31.GL_COMPUTE_SHADER, computeShaderCode);
computeProgram = GLES31.glCreateProgram();
GLES31.glAttachShader(computeProgram, computeShader);
GLES31.glLinkProgram(computeProgram);
checkGLError("LinkProgram/computeProgram");
}
The draw function:
public void draw(float[] mvpMatrix, float[] color) {
GLES31.glUseProgram(computeProgram);
checkGLError("UseProgram/computeProgram");
int radiusId = GLES31.glGetUniformLocation(
computeProgram, "radius");
indexBufferBinding = 0;
GLES31.glUniform1f(radiusId, (float) radius);
GLES31.glBindBufferBase(
GLES31.GL_SHADER_STORAGE_BUFFER, indexBufferBinding, gVBO);
checkGLError("glBindBuffer/gVBO");
GLES31.glDispatchCompute(2, 2, 1);
GLES31.glBindBufferBase(
GLES31.GL_SHADER_STORAGE_BUFFER, indexBufferBinding, 0);
// See note 1 below
//GLES31.glMemoryBarrier(
// GLES31.GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
GLES31.glMemoryBarrier(
GLES31.GL_SHADER_STORAGE_BARRIER_BIT);
checkGLError("glMemoryBarrier/1");
GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, gVBO);
checkGLError("glBindBuffer/gVBO");
GLES31.glUseProgram(program);
int posId = GLES31.glGetAttribLocation(
program, "a_v4Position");
int fillId = GLES31.glGetAttribLocation(
program, "a_v4FillColor");
int mvpMatrixId = GLES31.glGetUniformLocation(
program, "mvp_matrix");
GLES31.glEnableVertexAttribArray(posId);
GLES31.glEnableVertexAttribArray(fillId);
GLES31.glUniformMatrix4fv(mvpMatrixId, 1, false, mvpMatrix, 0);
// See note 2 below
GLES31.glDrawArrays(GLES31.GL_POINTS, 0, 3);
}
For reference, the shaders are at the end of the post.
Notes:
I can't find GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT in the Android documentation. Shouldn't it be there? The documentation mentions it.
The draw call crashes the application. Up until before glDrawArrays() everything seems fine.
Any ideas on what to look for are appreciated.
Vertex Shader:
private final String vertexShaderCode =
"uniform mat4 mvp_matrix;" +
"attribute vec4 a_v4Position;" +
"attribute vec4 a_v4FillColor;" +
"varying vec4 v_v4FillColor;" +
"void main(void) {" +
" v_v4FillColor = a_v4FillColor;" +
" gl_Position = mvp_matrix * a_v4Position;" +
"}";
Fragment Shader:
private final String fragmentShaderCode =
"precision mediump float;" +
"varying vec4 v_v4FillColor;" +
"void main(void) {" +
" gl_FragColor = v_v4FillColor;" +
"}";
Compute Shader:
private final String computeShaderCode =
"#version 310 es" +
"\n" +
"uniform float radius;" +
"struct Vector3f { float x; float y; float z; float w; };" +
"struct AttribData { Vector3f v; Vector3f c; };" +
"layout(std140, binding = 0) buffer destBuffer { AttribData data[]; } outBuffer;" +
"layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;" +
"void main() {" +
" ivec2 storePos = ivec2(gl_GlobalInvocationID.xy);" +
" uint gWidth = gl_WorkGroupSize.x * gl_NumWorkGroups.x;" +
" uint gHeigth = gl_WorkGroupSize.y * gl_NumWorkGroups.y;" +
" uint gSize = uint(gWidth) * uint(gHeigth);" +
" uint offset = uint(storePos.y)*gWidth + uint(storePos.x);" +
" float alpha = 2.0 * 3.1159265359 * (float(offset) / float(gSize));" +
" outBuffer.data[offset].v.x = float(sin(alpha)) * float(radius);" +
" outBuffer.data[offset].v.y = float(cos(alpha)) * float(radius);" +
" outBuffer.data[offset].v.z = 0.0;" +
" outBuffer.data[offset].v.w = 1.0;" +
" outBuffer.data[offset].c.x = float(storePos.x) / float(gWidth);" +
" outBuffer.data[offset].c.y = 0.0;" +
" outBuffer.data[offset].c.z = 1.0;" +
" outBuffer.data[offset].c.w = 1.0;" +
"}";
Yes, GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT is missing in the Android Java bindings. There's a tradition of the Java OpenGL bindings in Android being incomplete. There are still things missing from the 3.0 bindings as well.
In this case, since it's just an enum value, you can easily work around it by defining the value itself. The C/C++ definition is:
#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
So in Java, you can add a definition like this to your code:
static final int GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT = 0x00000001;
As for the crash, I'm not totally sure. I notice that there's no glVertexAttribPointer() calls in the posted code. If they are indeed not in your code, that would certainly be a problem.
I am making a game which I develop on the Nexus 4, it runs fine and no problems. I tested it on Sony's Xperia U and (for this problem) it runs fine as well.
The problem however is on the desire S (with the same code)
When I start the actual gameplay I have this background texture that should be rendered but for a second or so it takes the wrong texture. See the effect:
Image of Issue swap:
The left picture is what goes wrong, the right picture is how it should be (not exactly the same time but it is for the visualisation of my problem).
It takes the texture that is assigned to GLES20.GL_TEXTURE4 where it should have taken GLES20.GL_TEXTURE0.
Before I go to the code, something same happens during gameplay, whenever particles are rendered my text (also textures) are swapped with different textures. The moment my particles are gone, the text is rendered correctly again.
Image of Issue swap:
In this example it seems to take the texture that holds my background but it is random, because i do remember seeing only characters as well but then with black backgrounds and no transparency. The particles and the text engine use the same ShaderProgram, the background however does not, but for completeness, my shader:
public static final String vertexShaderCodeTC =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"attribute vec4 a_Color;" +
"attribute vec2 a_texCoord;" +
"varying vec4 v_Color;" +
"varying vec2 v_texCoord;" +
"void main() {" +
" gl_Position = uMVPMatrix * vPosition;" +
" v_texCoord = a_texCoord;" +
" v_Color = a_Color;" +
"}";
public static final String fragmentShaderCodeTC =
"precision mediump float;" +
"varying vec4 v_Color;" +
"varying vec2 v_texCoord;" +
"uniform sampler2D s_texture;" +
"void main() {" +
" gl_FragColor = texture2D( s_texture, v_texCoord ) * v_Color;" +
" gl_FragColor.rgb *= v_Color.a;" +
"}";
Now here is my rendering code:
int mPositionHandle = GLES20.glGetAttribLocation(riGraphicTools.ShaderProgram, "vPosition");
riGlobal.checkGlError("glGetAttribLocation | vposition |");
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
riGlobal.checkGlError("glEnableVertexAttribArray");
// Prepare the background coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, 3,
GLES20.GL_FLOAT, false,
0, vertexBuffer);
riGlobal.checkGlError("glVertexAttribPointer");
int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.ShaderProgram, "a_texCoord" );
riGlobal.checkGlError("glGetAttribLocation | a_texCoord");
// Prepare the texturecoordinates
GLES20.glVertexAttribPointer ( mTexCoordLoc, 2, GLES20.GL_FLOAT,
false,
0, textureBuffer);
riGlobal.checkGlError("glVertexAttribPointer");
GLES20.glEnableVertexAttribArray ( mPositionHandle );
riGlobal.checkGlError("glEnableVertexAttribArray");
GLES20.glEnableVertexAttribArray ( mTexCoordLoc );
riGlobal.checkGlError("glEnableVertexAttribArray");
// get handle to shape's transformation matrix
int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.ShaderProgram, "uMVPMatrix");
riGlobal.checkGlError("glGetUniformLocation");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);
riGlobal.checkGlError("glUniformMatrix4fv");
int mSamplerLoc = GLES20.glGetUniformLocation (riGraphicTools.ShaderProgram, "s_texture" );
riGlobal.checkGlError("glGetUniformLocation");
// Set the sampler texture unit to 0
GLES20.glUniform1i ( mSamplerLoc, riGlobal.get().getThemeStateOne());
riGlobal.checkGlError("glUniform1i");
// Draw the triangle
GLES20.glDrawElements(GLES20.GL_TRIANGLES, GameBackground.indices.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
riGlobal.checkGlError("glDrawElements");
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
riGlobal.checkGlError("glDisableVertexAttribArray");
GLES20.glDisableVertexAttribArray(mTexCoordLoc);
riGlobal.checkGlError("glDisableVertexAttribArray");
When I debug, my themestate function return the correct texture value so it should render my background (as it does on all other devices) but somehow it does not on the Desire S.
This is probably not all the code you need but I do not know exactly what you need and posting my whole app seems somewhat overkill, so please ask and I will explain etc.
I have tested this on multiple devices as stated so it really seems a Desire S only, or some config/setting that just affects the Desire S but I can't seem to find out what, does anybody has any idea or suggestion how to get it rendering correctly again?
P.S. The logic i see is that when I render my red blocks (effect) at start (and end for that matter) it swaps the background texture somehow, as soon as I do not render any triangles with that red block texture anymore, the background renders correctly again. The same i see with particles, rendering them messes up the text. The strange thing here though is that the particle texture is on the same texture as my background, so during gameplay without particles it already draws from that texture.
Also, it only happens on those two places/instances in all parts of my game/menus/parts/etc.
Fixed this problem, it was a bug in the driver software of the GPU, the textureunit id was only taking once, more info: http://androidblog.reindustries.com/hack-bad-gpu-fix-not-using-correct-texture-opengl/