OpenGL ES 2.0 crash (glGetUniformLocation: glError 1281) - android

I am creating an application which will read stl files and display them with OpenGL ES 2.0. I have had success displaying triangles which are hard coded and added to my triangle list in the onSurfaceCreated() method. The problem I am having is when I try to populate my list of triangle objects from the stl file and draw them. Best I can tell, the coordinates of the vertices are all valid and in the proper format. I always get the subject error. I am having trouble debugging this problem and don't know what to do. Below is a section of code from my triangle class where the problem occurs. Specifically the error is on the line of code
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
MyRenderer.checkGlError("glGetUniformLocation");
public void draw(float[] mvpMatrix) {
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// Enable a handle to the facet vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the facet
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
MyRenderer.checkGlError("glGetUniformLocation");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
MyRenderer.checkGlError("glUniformMatrix4fv");
// Draw the facet
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
//If edge mode
//GLES20.glUniform4fv(mColorHandle, 1, edgeColor, 0);
//GLES20.glLineWidth(2.0f);
//GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, vertexCount);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
Any ideas on how to debug a situation like this? Also, I am somewhat unclear as to the best way to add/remove objects that are to be drawn during program execution. Is my idea of keeping a list of the objects and looping through them in onDraw ok?

Same here, when I try to create my drawing objects outside the OpenGL thread, I get the same error. Solution -> objects should be created in the OpenGL thread.

I was just having the exact same problem working with displaying stl files. I'm guessing you're having the same problem I had, which is you are in the wrong thread when you are trying to create your new triangles. You've got to make sure your calls to OpenGL methods are on the right thread. I'm pretty new to this stuff myself. I basically just changed my program to queue up the STL that I have to add, and then, within the onDraw method, I instantiate the new stuff.

In my case I had forgotten to init the shaders.
Loading vertex and fragment shaders solved the problem.
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
with:
public static int loadShader(int type, String shaderCode){
// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}

Related

After disabling Vertex Attribute Array how glDrawArrays() works?

I have started learning Opengl ES 2.0 for android. I am working with code segment taken from the following site:
http://www.learnopengles.com/android-lesson-two-ambient-and-diffuse-lighting/
Here is a light point with 4 numbers:
private final float[] mLightPosInModelSpace = new float[] {0.0f, 0.0f, 0.0f, 1.0f};
This lightpoint is in model space. The following function is used to draw the point with disabled Vertex Attribute Array.
private void drawLight()
{
final int pointMVPMatrixHandle = GLES20.glGetUniformLocation(mPointProgramHandle, "u_MVPMatrix");
final int pointPositionHandle = GLES20.glGetAttribLocation(mPointProgramHandle, "a_Position");
// Pass in the position.
GLES20.glVertexAttrib3f(pointPositionHandle, mLightPosInModelSpace[0], mLightPosInModelSpace[1], mLightPosInModelSpace[2]);
// Since we are not using a buffer object, disable vertex arrays for this attribute.
GLES20.glDisableVertexAttribArray(pointPositionHandle);
// Pass in the transformation matrix.
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mLightModelMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(pointMVPMatrixHandle, 1, false, mMVPMatrix, 0);
// Draw the point.
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 1);
}
I read the documentation from here: https://www.khronos.org/opengles/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml
and see that after enabling vertex Attribute Array glDrawArrays() get points from that enabled array. But my question is from where glDrawArrays() get the points? In this example and it works fine taking the point from mLightPosInModelSpace . Thanks in advance.
See Section 2.7 of the OpenGL ES 2.0 spec, "Current Vertex State":
Current generic attribute values define generic attributes for a vertex when a
vertex array defining that data is not enabled, as described in section 2.8.
A current
value may be changed at any time by issuing one of the commands
void VertexAttrib{1234}{f}( uint index, T values );
void VertexAttrib{1234}{f}v( uint index, T values );
to load the given value(s) into the current generic attribute for slot index, whose
components are named x, y, z, and w.
Then on pg 21, the spec explains how they're pulled:
If
an array corresponding to a generic attribute required by a vertex shader is not enabled,
then the corresponding element is taken from the current generic attribute
state (see section 2.7).

OpenGL ES 2 on Android: how to use VBOs

this question is similar to something I asked here Android OpenGL ES 2: Introduction to VBOs
however I tried multiple aproaches since then and I still haven't succeeded, so I think posting another question where I offer aditional details would be a better aproach.
I am new to OpenGL ES 2 on Android (I have never worked with another OpenGL, I just need to draw something for an app I am developing for Android) and I would very much like to understand how to use VBOs. I tried to modify this OpenGL ES 2 for Android tutorial to use VBOs when drawing the triangle. I tried to use this step by step guide and this tutorial but I still don't understand everything, I am rather new to all of these things. My app currently crashes on start. Here's what I have:
public class Triangle {
private final String vertexShaderCode =
// This matrix member variable provides a hook to manipulate
// the coordinates of the objects that use this vertex shader
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
// the matrix must be included as a modifier of gl_Position
// Note that the uMVPMatrix factor *must be first* in order
// for the matrix multiplication product to be correct.
" gl_Position = uMVPMatrix * vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
private final FloatBuffer vertexBuffer;
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
private int mMVPMatrixHandle;
private final int buffer[] = new int[1];
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
static float triangleCoords[] = {
// in counterclockwise order:
0.0f, 0.622008459f, 0.0f, // top
-0.5f, -0.311004243f, 0.0f, // bottom left
0.5f, -0.311004243f, 0.0f // bottom right
};
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 0.0f };
/**
* Sets up the drawing object data for use in an OpenGL ES context.
*/
public Triangle() {
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
// (number of coordinate values * 4 bytes per float)
triangleCoords.length * 4);
// use the device hardware's native byte order
bb.order(ByteOrder.nativeOrder());
// create a floating point buffer from the ByteBuffer
vertexBuffer = bb.asFloatBuffer();
// add the coordinates to the FloatBuffer
vertexBuffer.put(triangleCoords);
// set the buffer to read the first coordinate
vertexBuffer.position(0);
// First, generate as many buffers as we need.
// This will give us the OpenGL handles for these buffers.
GLES20.glGenBuffers(1, buffer, 0);
// prepare shaders and OpenGL program
int vertexShader = MyGLRenderer.loadShader(
GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = MyGLRenderer.loadShader(
GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mProgram); // create OpenGL program executables
}
/**
* Encapsulates the OpenGL ES instructions for drawing this shape.
*
* #param mvpMatrix - The Model View Project matrix in which to draw
* this shape.
*/
public void draw(float[] mvpMatrix) {
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
MyGLRenderer.checkGlError("glGetUniformLocation");
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
//these I don't fully understand
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffer[0]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,vertexBuffer.capacity() * 4,vertexBuffer,GLES20.GL_STATIC_DRAW);
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(
mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, 0);
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
MyGLRenderer.checkGlError("glUniformMatrix4fv");
// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
// //is this still necesary? or do i have to use glDeleteBuffers?
// GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
}
when I put 0 instead of vertexBuffer inside glVertexAttribPointer() I get an error saying I don't provide the necesarry parameter: expected parameter: ptr: java.nio.Buffer; actual arguments: 0(int)
The transition to the VBO can be a bit strange due to the data pointer usage.
From a quick inspection your main issue is in
GLES20.glVertexAttribPointer(
mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
as this should be
GLES20.glVertexAttribPointer(
mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, 0);
So about this buffers: A VBO is a custom buffer on the GPU generally used and optimised to store the vertex data directly to the GPU. The performance you gain by doing so is that the vertex data do not need to be copied to the GPU on every draw call.
These buffers are still custom and on generating them all you need to set is their size. I see you are using factor *4 on the vertex count assuming a float value has a size of 4 bytes, this is not the best idea since that might not always be true. If possible always try to use some form of "sizeOf". Anyway your buffer is created correctly and data are sent to it.
After the data are sent to the VBO you should keep them there until you need them. That means you generally create a single VBO per unique object (a square for instance) and then just hold its ID. Whenever you wish to draw it you just simply bind the buffer and draw as you did. In other words the buffer should never be created in the draw method. What you did there is a memory leak as well since you are responsible for releasing the buffer by calling delete once the buffer is no longer needed.
So about your pointer issue on glVertexAttribPointer: There are 2 ways to use this method. Without the VBO the last parameter is the pointer to the data on your CPU. With the VBO you need to set that as a relative pointer inside the VBO. That means when VBO is bound the beginning of the buffer would be NULL (0), you might even need to typecast that value. For other positions in the buffer you need to manually calculate them.
And the code you posted specifically:
// First, generate as many buffers as we need.
// This will give us the OpenGL handles for these buffers.
final int buffer[] = new int[1];
GLES20.glGenBuffers(1, buffer, 0);
//these I don't fully understand
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffer[0]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,vertexBuffer.capacity() * 4,vertexBuffer,GLES20.GL_STATIC_DRAW);
This all goes into some load time and have a reference to the buffer[] beside that you should add GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); what this call does is unbind the buffer. This is not something you NEED to do but it is best that you do so you have no confusion what buffer is bound if any.
Before the glVertexAttribPointer is called you need to bind your buffer. Then set the last parameter as described above.
After you are done using this buffer (done drawing) you should (again not necessary) unbind the buffer.

Opengl Es 2.0 - Displaying multiple textures

So I'm able to display 1 texture at a time but I have a problem with displaying more textures. The render function is called for every texture separately (tex_nr), not sure if that's a good approach. Here's the rendering code:
private void Render(float[] m, int tex_nr) {
// Set our shaderprogram to image shader
GLES20.glUseProgram(riGraphicTools.sp_Image);
// clear Screen and Depth Buffer, we have set the clear color as black.
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// get handle to vertex shader's vPosition member
int mPositionHandle = GLES20.glGetAttribLocation(riGraphicTools.sp_SolidColor, "vPosition");
// Enable generic vertex attribute array
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, 3,
GLES20.GL_FLOAT, false,
0, vertexBuffer);
// Get handle to texture coordinates location
int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image,
"a_texCoord" );
// Enable generic vertex attribute array
GLES20.glEnableVertexAttribArray ( mTexCoordLoc );
// Prepare the texturecoordinates
GLES20.glVertexAttribPointer ( mTexCoordLoc, 2, GLES20.GL_FLOAT,
false,
0, uvBuffer);
// Get handle to shape's transformation matrix
int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.sp_Image,
"uMVPMatrix");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);
// Get handle to textures locations
int mSamplerLoc = GLES20.glGetUniformLocation (riGraphicTools.sp_Image,
"s_texture" );
// Set the sampler texture unit to where we have saved the texture.
GLES20.glUniform1i ( mSamplerLoc, tex_nr);
// Draw the triangle
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTexCoordLoc);
}
And here the loading textures code:
texturenames = new int[GameObject.spritePaths.size()];
GLES20.glGenTextures(GameObject.spritePaths.size(), texturenames, 0);
for(int i = 0; i < GameObject.spritePaths.size(); i++)
{
// Retrieve our image from resources.
int id = mContext.getResources().getIdentifier(GameObject.spritePaths.get(i), null, mContext.getPackageName());
// Temporary create a bitmap
Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(), id);
// Bind texture to texturename
GLES20.glActiveTexture(GLES20.GL_TEXTURE0+i);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texturenames[i]);
// Set filtering
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
// Load the bitmap into the bound texture.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
// We are done using the bitmap so we should recycle it.
bmp.recycle();
}
As a result of this code, only the last loaded texture is displayed and I have no idea why the former ones do not show up. I would be very grateful for any clues!
edit:
Actually, I have just found out that I can display all of the textures that I loaded but only 1 at a time. So I guess that the problem isn't connected with loading? It looks as if each consecutive Render call(my function) prevented the drawing in the previous call...
You have a call to glClear() in your Render() method:
// clear Screen and Depth Buffer, we have set the clear color as black.
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
This does pretty much what the name suggests, and what's also captured in your comment: It clears all rendering that has been done so far. So if you call the Render() method multiple times, only the rendering from the last call will be visible.
If you want to invoke Render() multiple times for the same frame, you will need to take it out of Render(), and call it only once at the start of rendering the frame.
There's another thing in your code that looks slightly suspicious:
int mPositionHandle = GLES20.glGetAttribLocation(riGraphicTools.sp_SolidColor, "vPosition");
....
int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "a_texCoord");
Unless sp_SolidColor and sp_Image have the same value, you're querying attribute locations from two different shader programs. Since sp_Image is the program you are using, you should pass it in as the first parameter for both these calls.

What is the proper way to enable and disable GLES20 atributes?

Firsty what am I creating: 2d tile based rpg game.
What I am currently doing I will post here, and comment some spots that I am not sure if I am using them correctly.
In GlSurfaceViewRenderer:
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//I enable some attributes
//Don't know if its needed in GLES20, there isnt GL20.GL_PERSPECTIVE_CORRECTION_HINT attribute at all
GLES20.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
//next I don't really know if I need them all:
GLES20.glClearColor(0, 0, 0, 1);
GLES20.glClearDepthf(1.0f);
GLES20.glDisable(GLES20.GL_CULL_FACE);// No culling of back faces
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
GLES20.glDisable(GLES20.GL_DITHER);
GLES20.glDisable(GL10.GL_LIGHTING);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// for transperent pixels
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
//Load shaders: (1 vertex and fragment shader I hope is enouph)
iProgId = Utils.LoadProgram(vertexShaderCode, fragmentShaderCode);
GLES20.glUseProgram(iProgId);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(iProgId, "vPosition");
// get handle to textures shader's a_TexCoordinate member
mTextureCoordinateHandle = GLES20.glGetAttribLocation(iProgId, "a_TexCoordinate");
// get handle to transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(iProgId, "uMVPMatrix");
//Now in here not sure: some people enable arrays in every draw frame, I do it once:
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Enable a handle to the texture vertices
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
Matrix.frustumM(mProjMatrix, 0, ratio, -ratio, 1, -1, 1, 10000);
//.... and other
}
#Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//set camera position
Matrix.setLookAtM(...);
Matrix.multiplyMM(...);
//begin drawing:
for(Sprite spr : Sprite_list){
spr.draw(){
//whats happening in draw:
//First setting the location of the sprite:
Matrix.setIdentityM(...x & y...);
Matrix.translateM(...);
Matrix.setIdentityM(...);
Matrix.multiplyMM(...);
//Some developers enables vertex attrib arrays here and then disables at the end of this drawing method. But I enable it in on surface created and don't disable it, maybe it's faster this way, not sure.
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(GLRenderer.mPositionHandle, DIMENSION, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(GLRenderer.mTextureCoordinateHandle, DIMENSION, GLES20.GL_FLOAT, false, vertexStride, textureBuffer);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textID);
GLES20.glUniformMatrix4fv(GLRenderer.mMVPMatrixHandle, 1, false, GLRenderer.mMVPMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
}
}
And everything works, for now, but I really not sure if I am doing any mistakes here, can someone elaborate?
The code itself does not necessarily do anything incorrect from what I can see.
Apart from GLES20.glDisable(GL10.GL_LIGHTING); as it's not a feature available in ES2.
Although the code is very limited to what it will be able to do. Reason is that you're uploading most of the rendering states in surfaceCreated, not when you actually might need them/change renderstates.
For example:
//Now in here not sure: some people enable arrays in every draw frame, I do it once:
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Enable a handle to the texture vertices
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
It's perfectly fine to just enable the attribute arrays at one place, however if you would like to utilize a different shader program for a particular piece of geometry in your scene, this would become quite problematic.
Consider this, if you would want to change program, you need to potentially Enable/Disable the particular attributes for that program. You would also need to bind the program (glUseProgram)
Therefore as you referenced yourself in the code comment, that others normally enable/disable these during rendering is for that specific reason.
However it's not just for attribute streams but also all types of renderstates like changing program, enabling Cullmode, blending and so forth.
Now one shouldn't go crazy and just upload and change all of these before every draw call, as changing states are expensive.
One will try to batch all the draw calls that will use the same type of renderstates and resources such as textures/programs and so forth together to minimize number of renderstates changes.
So in your renderloop you would then render the sorted scene of renderable objects, then upload any renderstate that might need to change or been invalidated.

OpenGL ES Android Bitmap Texture not showing

I'm trying to draw a square and add a texture to it. I'm just starting with OpenGL and I'm following this tutorial http://blog.uncle.se/2012/02/opengl-es-tutorial-for-android-part-vi-textures/.
Here is the code for my squares draw procedure:
public void draw(float[] mvpMatrix) {
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the square
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
/** now trying to add the texture */
Bitmap bitmap = BitmapFactory.decodeResource(chamRenderer.context.getResources(),
R.drawable.ic_launcher);
// Create an int array with the number of textures we want,
// in this case 1.
int[] textures = new int[1];
// Tell OpenGL to generate textures.
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
// Scale up if the texture if smaller.
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_LINEAR);
// scale linearly when image smalled than texture
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_LINEAR);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
Renderer.checkGlError("glGetUniformLocation");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
Renderer.checkGlError("glUniformMatrix4fv");
// Draw the square
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
The blue colour display fine but theirs no hope with the texture, no errors, just nothing their. Like I said I'm very now to OpenGL. Thanks :)
If I am reading this right it is displaying the blue and white squares (that looks like tiles) but not the texture? The texture is the image stored in bitmap variable. You do not do anything after creating the bitmap. It looks like you have not finished the tutorial yet; the code is that they use to render it is not in your code. Look under the part that says UV mapping and look at that code and make sure you include that code.

Categories

Resources