I have a renderer that is an attempt to draw dots as a textured square. Nothing knocks, and I have other objects that are drawn perfectly, but these squares are not displayed, I believe that this has something to do with the data passed to the shader program in my drawTexturedPoint () function.
I have a FloatBuffer buffer geometry that contains vertex positions. 6 vertices with exactly the same vertex coordinates, one for each corner of two triangles. There are several points in this buffer.
The shader program takes these vertices and manipulates them in the correct position based on the point (or square) size passed to the shader.
protected String getPointVertexShader() { // Define a simple shader program for our points. final String pointVertexShader = "uniform vec2 u_pointSize; + "uniform mat4 u_MVPMatrix; \n" + "attribute vec4 a_Position; \n" + "attribute vec2 a_TexCoordinate; \n" + "varying vec2 v_TexCoordinate; \n" // Passed into the fragment shader. + "void main() \n" + "{ \n" + " v_TexCoordinate = a_TexCoordinate; \n" // Pass through the texture coordinate. + " gl_Position = u_MVPMatrix * a_Position; \n" // gl_Position is a special variable used to store the final position. + " gl_Position += vec4(gl_Position.w * u_pointSize * (a_TexCoordinate - vec2(0.5,0.5)), 0, 0);\n" + "} \n"; return pointVertexShader; } protected String getPointFragmentShader() { final String pointFragmentShader = "precision mediump float; \n" + "uniform sampler2D u_Texture; \n" // The input texture. + "varying vec2 v_TexCoordinate;\n" // Interpolated texture coordinate per fragment. + "void main() \n" // The entry point for our fragment shader. + "{ \n" + " gl_FragColor = (texture2D(u_Texture, v_TexCoordinate));\n" // Pass the color directly through the pipeline. + "} \n"; return pointFragmentShader; }
Note that u_pointSize is vec2 in the normalized coordinates of the device; the value should be the size in pixels divided by the size of the viewport in pixels.
Below is a function in which it transfers data to a shader and makes a draw.
private void drawTexturedPoint(final FloatBuffer geometryBuffer) { //GeometryBuffer holds all the points in one buffer. GLES20.glUseProgram(mPointsProgramHandle); mPointSizeHandle = GLES20.glGetAttribLocation(mPointsProgramHandle, "u_pointSize"); mPointMVPMatrixHandle = GLES20.glGetUniformLocation(mPointsProgramHandle, "u_MVPMatrix"); mTextureUniformHandle = GLES20.glGetUniformLocation(mPointsProgramHandle, "u_Texture"); mPointPositionHandle = GLES20.glGetAttribLocation(mPointsProgramHandle, "a_Position"); mTextureCoordinateHandle = GLES20.glGetAttribLocation(mPointsProgramHandle, "a_TexCoordinate"); // Pass in the texture coordinate information mPointSize.position(0); GLES20.glVertexAttribPointer(mPointSizeHandle, mVec2DataSize, GLES20.GL_FLOAT, false, 0, mPointSize); GLES20.glEnableVertexAttribArray(mPointSizeHandle); // Pass in the position information geometryBuffer.position(0); GLES20.glVertexAttribPointer(mPointPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, mPositionFloatStrideBytes, geometryBuffer); GLES20.glEnableVertexAttribArray(mPointPositionHandle); // Pass in the texture coordinate information mSquareTextureCoordinates.position(0); GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mVec2DataSize, GLES20.GL_FLOAT, false, 0, mSquareTextureCoordinates); GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle); GLES20.glUniformMatrix4fv(mPointMVPMatrixHandle, 1, false, mMVPMatrix, 0); // Draw the cube. GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, geometryBuffer.capacity()/mPositionDataSize); }
Here are a few other relevant variables used in the drawing function.
private final int mBytesPerFloat = 4; private final int mPositionOffset = 0; private final int mPositionDataSize = 3; private final int mPositionFloatStrideBytes = mPositionDataSize * mBytesPerFloat; private FloatBuffer mPointSize; private final int mVec2DataSize = 2;
// Data coordinate texture.
final float[] squareTextureCoordinateData = {
This is how I set the square size (now hardcoded).
float psize = 25f/480f; mPointSize.position(0); mPointSize.put(psize); mPointSize.put(psize); mPointSize.flip();
Be very grateful for your help!
[EDIT] @ user2359247 ok I understand what you mean, I will keep it in shape, so I changed: mPointSizeHandle = GLES20.glGetUniformLocation (mPointsProgramHandle, "u_pointSize");
Not quite sure how to pass the buffer, however, I have not come across this before.
Another friendly question: do you understand what I'm trying to achieve, I only ask, how am I interested in whether the correct data is in my mPointSize buffer? This solution for rendering points in the form of textured squares came from someone else, so I'm trying to put this together.
Therefore, I don’t understand how to set the variable size of a point or what function to use to transfer it to a shader:
u_pointSize is vec2 in the normalized coordinates of the device; The value should be the size in pixels divided by the size of the viewport in pixels.
Trial replacement:
mPointSize.position(0); GLES20.glVertexAttribPointer(mPointSizeHandle, mVec2DataSize, GLES20.GL_FLOAT, false, 0, mPointSize); //Error code gets sent back after this line. GLES20.glEnableVertexAttribArray(mPointSizeHandle);
from
GLES20.glUniform2fv(mPointSizeHandle, 1, mPointSize);
this is the surface at the moment: 
should be more like this layout: 