Android OpenGL change position - android

I want to change position of object in OpenGL,I found this class and i want to write function change.When program call change i want to change positon of object
This class create a square and texture over...And i want to change position in pixels...
public class Square {
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
-1.0f, -1.0f, 0.0f, // V1 - bottom left
-1.0f, 1.0f, 0.0f, // V2 - top left
1.0f, -1.0f, 0.0f, // V3 - bottom right
1.0f, 1.0f, 0.0f // V4 - top right
};
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
private FloatBuffer textureBuffer1; // buffer holding the texture coordinates
private float texture1[] = {
// Mapping coordinates for the vertices
2.0f, 1.0f, // top left (V2)
2.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
/** The texture pointer */
private int[] textures = new int[1];
public Square() {
// a float has 4 bytes so we allocate for each coordinate 4 bytes
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
// allocates the memory from the byte buffer
vertexBuffer = byteBuffer.asFloatBuffer();
// fill the vertexBuffer with the vertices
vertexBuffer.put(vertices);
// set the cursor position to the beginning of the buffer
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture1.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer1 = byteBuffer.asFloatBuffer();
textureBuffer1.put(texture1);
textureBuffer1.position(0);
}
/**
* Load the texture for the square
* #param gl
* #param context
*/
public void loadGLTexture(GL10 gl, Context context) {
// loading texture
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.a);
// generate one texture pointer
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// create nearest filtered texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Clean up
bitmap.recycle();
}
/** The draw method for the square with the GL context */
public void draw(GL10 gl) {
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}

OpenGL is a drawing API not a scene graph. In OpenGL there are no models, objects or scene. There are only points, lines and triangles, drawn to a pixel based framebuffer. What this means is, that every change in your scene must be complemented by a full redraw of the scene.
So if you want to move something on the screen, you change the value variable(s) controlling the position and do a full redraw.

Related

Android 'white box' textures OpenGL ES 1.0 on some devices

I have next problem.
I'm write some android app which uses opengl es 1.0
I'm using GLSurfaceView and custom Renderer. Here are methods of my custom renderer onDrawFrame, onSurfaceChanged, onSurfaceChanged:
#Override
public void onDrawFrame(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// clear Screen and Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
// Drawing
gl.glTranslatef(0f, 0f, -3.0f); // move 5 units INTO the screen
// is the same as moving the camera 5 units away
// gl.glScalef(0.5f, 0.5f, 0.5f); // scale the square to 50%
// otherwise it will be too large
square.draw(gl, mScrollable.getIndexA(), mScrollable.getIndexB(), mScrollable.getAlphaValue()); // Draw the triangle
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) { //Prevent A Divide By Zero By
height = 1; //Making Height Equal One
}
gl.glViewport(0, 0, mWidth, mHeight); //Reset The Current Viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Projection Matrix
gl.glLoadIdentity(); //Reset The Projection Matrix
//Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Load the texture for the square
square.loadGLTexture(gl, this.context);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping ( NEW )
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Black Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
And my Square class to render textures:
private int[] textures;
private GL10 mGl;
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
-1.0f, -1.8f, 0.0f, // V1 - bottom left
-1.0f, 1.3f, 0.0f, // V2 - top left
1.0f, -1.8f, 0.0f, // V3 - bottom right
1.0f, 1.3f, 0.0f // V4 - top right
};
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
private GlAnimationCache cacheHelper;
public void loadGLTexture(GL10 gl, Context context) {
// loading texture
mGl = gl;
gl.glGenTextures(mImageEntityList.size(), textures, 0);
cacheHelper = new GlAnimationCache(mContext, mImageEntityList, mGlRenderer, mGlSurfaceView);
cacheHelper.initCache(); //it init cache in background thread
}
public void removeTextureAt(int position){
mGl.glDeleteTextures(1, textures, position);
}
public void bindTextureAt(final Bitmap bitmap, int position){
// generate one texture poi, 0);
// ...and bind it to our array
mGl.glBindTexture(GL10.GL_TEXTURE_2D, textures[position]);
mGl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
mGl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// create nearest filtered texture
mGl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
mGl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
// gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
// gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLUtils.getInternalFormat(bitmap), bitmap, GLUtils.getType(bitmap), 0);
bitmap.recycle();
}
private int prevIndex = 0;
/** The draw method for the square with the GL context */
public void draw(GL10 gl, int indexA, int indexB, float alpha) {
// bind the previously generated texture
if(prevIndex != indexA){
cacheHelper.synchronizeCache(indexA);
prevIndex = indexA;
}
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[indexA]);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glColor4f(1, 1, 1, 1f);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[indexB]);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glColor4f(1, 1, 1, Math.abs(alpha));
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
So, the problem is next: On Samsung S5, Alcatel One Touch 4033D and Motorolla Droid Razr textures are rendered fine. But on Samsung Galaxy Nexus I see only 'white box'.
I have tried to change size of texture to power of 2(512 x 512) but it not helpes.
In Square class add function:
public boolean isNPOTSupported(GL10 gl) {
String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
return extensions.indexOf("GL_OES_texture_npot") != -1;
}
And when you Generate textures, add this:
final boolean isNPOTSupported = isNPOTSupported(gl);
if(isNPOTSupported) {
gl.glGenTextures(mImageEntityList.size(), textures, 0);
}else{
for(int i = 0; i < mImageEntityList.size(); i++){
gl.glGenTextures(1, textures, i);
}
}
Instead this:
gl.glGenTextures(mImageEntityList.size(), textures, 0);

android/openGL: fill a 2d viewport with a square

What I've managed to accomplish so far is:
Initialise the GLSurfaceView/Renderer
Draw a triangle on the screen
Render a square/rectangle on the screen
Add a bitmap texture to the screen
Ensure PNG transparency is honoured when rendering
Automatically scale the triangles so they show up correctly for all screen sizes
However, after fixing the scaled triangles, the background rectangle (with texture) no longer fills up the screen.
I've been stuck on this for a while now and absolutely baffled to the point I have thrown in the towel.
The main parts I'm unsure about is the use of glFrustumf() and gluLookAt().
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION); // set matrix to projection mode
gl.glLoadIdentity(); // reset the matrix to its default state
gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // apply the projection matrix
}
#Override
public void onDrawFrame(GL10 gl) {
// Clear the screen
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// Set GL_MODELVIEW transformation mode
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity(); // reset the matrix to its default state
// When using GL_MODELVIEW, you must set the camera view
GLU.gluLookAt(gl, 0, 0, -5f, 0f, 0f, 0f, 0.0f, 1.0f, 0.0f);
bg.draw(gl);
// ...
}
If anybody has a moment to take a look at the problem, I've uploaded the files to https://bitbucket.org/koonkii/test_opengl/src so you don't have to recreate the code by copy-pasting.
GLU.gluLookAt(gl, 0, 0, -5f, 0f, 0f, 0f, 0.0f, 1.0f, 0.0f);
Try to change -5f to 0, what you're saying here is displace the camera 5 units back, therefore unless you're doing an orthogonal projection (which I think you're not, try checking out this) what OpenGL is doing is scaling your background polygon according to your perspective view, and you see it as 'smaller'.
If you do an orthogonal projection, no matter how much you move your camera in the z axis, you will always see it the same size. This is useful for 2D OpenGL-based games, so do check out the link above.
EDIT: gluPerspective and glOrtho
gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
gluPerspective has a parameter called 'fovy', which is basically the 'Field of View in the Y axis'. The field of view expresses the amount of space the camera can see, basically 'expanding' or 'contracting' whatever vertices happen to be before it. A typical human eye has a 45ยบ FOV.
The zNear and zFar express the near and far frustum limits, the frustum being an invisible 'box' which determines which vertices are outside the viewing area.
Aspect determines the ratio between the width and height of the camera.
glOrtho is a special case of gluPerspective in the sense that the FOV is always 0.
gl.glOrthof(0.0f, (float) width, (float) height, 0.0f, 1.0f, -1.0f);
The first four parameters specify the size of the clipping plane (normally the size of the screen), the other two values specifiy the frustum near and far (which you don't need unless you want to hide objects by placing them 'far away'.
I hope this cleared it up a bit for you.
Alright, after a good nights sleep and applying RedOrav's advice regarding orthogonal projection, I did more browsing into it and got it working!
The code snippets given by RedOrav did actually work, however after switching to the orthogonal projection I was still drawing the squares and triangles as small as 0.15f in width. Barely be visible as it's less than 1 pixel wide!
After changing the background/square/triangle code to something more reasonable (30.0f), they showed up!
Played around with the code a bit more and got positioning working properly. I've submitted the code to bitbucket for those who want to check out a working copy of the project.
The reason why I needed G.getYPos() is because the bottom coordinate = 0, and top is screen height. Couldn't figure out a nicer way of inverting it without turning all the textures upside-down.
The important initialisation parts are:
Global helper
public class G {
public static float ratio;
public static int width, height;
/** The texture pointer */
public static int[] textures = new int[3];
final static int TEXTURE_DEFAULT = 0;
final static int TEXTURE_BG = 1;
final static int TEXTURE_ANDROID = 2;
final static int TEXTURE_TURTLE = 3;
/**
* Since (bottom = 0, top = height), we need to invert the values so they make sense logically.
*/
public static int getYPos(int top) {
return G.height - top;
}
}
Renderer class
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
this.loadGLTextures(gl);
gl.glClearColor(1.0f, 0.0f, 0.0f, 1.0f); //Red Background
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
// Save these for global use.
G.width = width;
G.height = height;
G.ratio = (float) width / height;
// Set up orthogonal viewport and make adjustments for screen ratio
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, 0, width, 0, height); // The parameters are weird but bottom = 0 so we need an inverter function G.
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
// Start setting up the constructs we need
bg = new Background();
squares = new ArrayList<Square>();
squares.add(new Square(width / 2, G.getYPos(0))); // middle/top of the screen
squares.add(new Square(width / 2, G.height /2)); // center of the screen
triangles = new ArrayList<Triangle>();
triangles.add(new Triangle(0, G.getYPos(0))); // top left
triangles.add(new Triangle(width, G.getYPos(height))); // bottom right
triangles.add(new Triangle(width /2, height /2)); // middle
}
#Override
public void onDrawFrame(GL10 gl) {
// Clear the screen
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
bg.draw(gl);
for (Square s : squares) {
s.draw(gl);
}
// Draw correctly scaled triangles
for (Triangle t : triangles) {
t.draw(gl);
}
try {
Thread.sleep(400);
}
catch (InterruptedException e) {
}
}
/**
* Loads the textures up.
*/
public void loadGLTextures(GL10 gl) {
int[] texture_map = new int[] { R.drawable.bg_game, R.drawable.ic_launcher };
Bitmap bitmap;
// generate one texture pointer, keep 0 as blank/default
gl.glGenTextures(texture_map.length, G.textures, 0);
for (int i = 0; i < texture_map.length; i++) {
// loading texture
bitmap = BitmapFactory.decodeResource(context.getResources(), texture_map[i]);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, G.textures[i +1]);
// create nearest filtered texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Clean up
bitmap.recycle();
}
}
Background class
p
ublic class Background {
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
-1.0f, -1.0f, 0.0f, // V1 - bottom left
-1.0f, 1.0f, 0.0f, // V2 - top left
1.0f, -1.0f, 0.0f, // V3 - bottom right
1.0f, 1.0f, 0.0f // V4 - top right
};
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
public Background() {
// Recalculate the vertices so they fit the screen
vertices[0] = 0; // v1 left
vertices[1] = G.height; // v1 bottom
vertices[3] = 0; // v2 left
vertices[4] = 0; // v2 top
vertices[6] = G.width; // v3 right
vertices[7] = G.height; // v3 bottom
vertices[9] = G.width; // v4 right
vertices[10] = 0; // v4 top
// a float has 4 bytes so we allocate for each coordinate 4 bytes
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
// allocates the memory from the byte buffer
vertexBuffer = byteBuffer.asFloatBuffer();
// fill the vertexBuffer with the vertices
vertexBuffer.put(vertices);
// set the cursor position to the beginning of the buffer
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
public void draw(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D); // Twig;
// Bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, G.textures[G.TEXTURE_BG]);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisable(GL10.GL_TEXTURE_2D); // twig;
}
}
Square class
Very similar to background except it has a position and applies alpha transparency.
public class Square {
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
-1.0f, -1.0f, 0.0f, // V1 - bottom left
-1.0f, 1.0f, 0.0f, // V2 - top left
1.0f, -1.0f, 0.0f, // V3 - bottom right
1.0f, 1.0f, 0.0f // V4 - top right
};
private FloatBuffer textureBuffer; // buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
public Square(float posX, float posY) {
float w = 30f;
float h = w;
vertices[0] = posX - w; // left
vertices[3] = posX - w;
vertices[6] = posX + w; // right
vertices[9] = posX + w;
vertices[1] = posY - h; // top
vertices[4] = posY + h;
vertices[7] = posY - h; // bottom
vertices[10] = posY + h;
// a float has 4 bytes so we allocate for each coordinate 4 bytes
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
// allocates the memory from the byte buffer
vertexBuffer = byteBuffer.asFloatBuffer();
// fill the vertexBuffer with the vertices
vertexBuffer.put(vertices);
// set the cursor position to the beginning of the buffer
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
/** The draw method for the square with the GL context */
public void draw(GL10 gl) {
// Enable alpha transparency
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
// bind the previously generated texture
gl.glEnable(GL10.GL_TEXTURE_2D); // Twig;
gl.glBindTexture(GL10.GL_TEXTURE_2D, G.textures[G.TEXTURE_ANDROID]);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// reset the colour for the square
gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Disable alpha transparency
gl.glDisable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ZERO);
gl.glDisable(GL10.GL_TEXTURE_2D); // twig;
}
}
Triangle class
public class Triangle {
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
-0.5f, -0.5f, 0.0f, // V1 - first vertex (x,y,z)
0.5f, -0.5f, 0.0f, // V2 - second vertex
0.0f, 0.5f, 0.0f // V3 - third vertex
};
public Triangle(float posX, float posY) {
int w = 30;
int h = w;
vertices[0] = posX - (w/2); // left
vertices[3] = posX + (w/2); // right
vertices[6] = posX; // middle
vertices[1] = posY - (h/2); // bottom
vertices[4] = posY - (h/2); // bottom
vertices[7] = posY + (h/2); // top
// a float has 4 bytes so we allocate for each coordinate 4 bytes
ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
vertexByteBuffer.order(ByteOrder.nativeOrder());
// allocates the memory from the byte buffer
vertexBuffer = vertexByteBuffer.asFloatBuffer();
// fill the vertexBuffer with the vertices
vertexBuffer.put(vertices);
// set the cursor position to the beginning of the buffer
vertexBuffer.position(0);
}
public void draw(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// set the colour for the triangle
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
// Reset the colour
gl.glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
Hope this helps anyone else having similar issues with starting OpenGL.

How to use vertex buffers in android and opengl es 1.1

I spend almost whole day trying to render simple polygon using opengl 1.1 and vertex buffers, but no luck. I searched and searched, but I haven't found much.
This is what i have so far:
public class Polygon {
int bufferId = 0;
private FloatBuffer vertexBuffer; // Buffer for vertex-array
private float[] vertices = { // Vertices for the square
-1.0f, -1.0f, 0.0f, // 0. left-bottom
1.0f, -1.0f, 0.0f, // 1. right-bottom
-1.0f, 1.0f, 0.0f, // 2. left-top
1.0f, 1.0f, 0.0f // 3. right-top
};
private ByteBuffer indexBuffer;
private byte[] indices = {0, 1, 2, 3}; // Indices to above vertices (in CCW)
// Constructor - Setup the vertex buffer
public Polygon() {
// Setup vertex array buffer. Vertices in float. A float has 4 bytes
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder()); // Use native byte order
vertexBuffer = vbb.asFloatBuffer(); // Convert from byte to float
vertexBuffer.put(vertices); // Copy data into buffer
vertexBuffer.position(0); // Rewind
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
int[] buffers = new int[1];
GLES11.glGenBuffers(1, buffers, 0);
bufferId = buffers[0];
GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, bufferId);
GLES11.glBufferData(GLES11.GL_ARRAY_BUFFER, vertices.length, vertexBuffer, GLES11.GL_STATIC_DRAW);
GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, 0);
}
// Render the shape
public void draw(GL10 gl) {
GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, bufferId);
GLES11.glEnableClientState(GL10.GL_VERTEX_ARRAY);
GLES11.glVertexPointer(3, GLES11.GL_FLOAT, 0, 0);
GLES11.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length);
GLES11.glDisableClientState(GL10.GL_VERTEX_ARRAY);
GLES11.glBindBuffer(GLES11.GL_ARRAY_BUFFER, 0);
}
}
It doesn't render anything and there is no relevant error in android logcat.
I ommited rest of the code. The problem is obviously in this class, since it works fine when I change draw method to this:
public void draw(GL10 gl) {
GLES11.glEnableClientState(GL10.GL_VERTEX_ARRAY);
GLES11.glVertexPointer(3, GLES11.GL_FLOAT, 0, vertexBuffer);
GLES11.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length);
GLES11.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
So, what am I doing wrong?
Don't look in the logCat for errors, you want to check for OpenGL errors with glGetError(), and check that the return value is zero (no error), or nonzero (error).
vertices.length is the wrong argument to glDrawArrays. You want to supply the number of vertices, not the number of floats. It should be vertices.length/3 (3 floats per vertex).
You're currently drawing way past your array into some garbage data, so I'm not sure what kind of consequences that could have.

Drawing text as textures on squares does not show anything

I'm new to OpenGL and I'm developing an Augmented-reality application for Android.
Until now, I was drawing white squares, perpendicular to the camera, pointing the user to the direction where a "Point of interest" would be.
Now, I'm trying to show some text into the squares.
I've read a lot and it seems that creating a texture with the text is the most direct and easiest approach, so I'm creating the textures as soon as I get data of the Points of interest and stick them to their squares. For that, I use bitmaps.
Let's see some code. Within my onDrawFrame method, I do something like this:
public void onDrawFrame(GL10 gl) {
// Get sensors matrix
...
//Clear Screen And Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Load remapped matrix
gl.glMatrixMode(GL10.GL_MODELVIEW);
// List of Points of interest (modified when some data is downloaded)
synchronized (poiList) {
if(mNewData){ // True if new data has been dowloaded)
if(textures != null) // Delete old textures
gl.glDeleteTextures(textures.length, textures, 0);
textures = loadGLTexture(gl, soapPoiList.getPoiList());
mNewData = false;
}
int i = 0;
// Iterate the list
for (PointOfInterest c : poiList) {
gl.glLoadIdentity();
gl.glLoadMatrixf(remappedRotationMatrix, 0);
// Get bearing
...
// Place polygon in the right place
gl.glRotatef(-bearing, 0, 0, 1);
gl.glTranslatef(0, ICONS_SIZE_RATIO, 0);
// Actually draws the polygon with text
c.draw(gl, textures[i]);
i++;
}
}
}
Where loadGLTextures is:
protected int[] loadGLTexture(GL10 gl, List<PointOfInterest> l){
int res[] = new int[l.size()];
gl.glGenTextures(res.length, res, 0);
int i = 0;
for(PointOfInterest p : l) {
Bitmap bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.RGB_565);
bitmap.eraseColor(Color.BLACK);
Canvas canvas = new Canvas(bitmap);
Paint textPaint = new Paint();
textPaint.setTextSize(35);
textPaint.setFakeBoldText(true);
textPaint.setAntiAlias(true);
textPaint.setARGB(255, 255, 255, 255);
// Draw the text centered
canvas.drawText(Float.toString(p.getDinstanceToOrigin()) + " m.", 10,35, textPaint);
// Bind the texture to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, res[i]);
// Create Nearest Filtered Texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
i++;
}
return res;
}
It basically creates a bitmap for each Point of Interest, and generate a texture with it. The texture will be applied over a white square later, as it is shown in this class:
public class PointOfInterest {
// MEMBERS ----------------------------------------------------------------
....
....
// OpenGL necessary variables
/** The buffer holding the vertices */
private FloatBuffer vertexBuffer;
/** The initial vertex definition */
private float vertices[] = {
-1.0f, 0.0f, -1.0f, //Bottom Left V1
-1.0f, 0.0f, 1.0f, //Top Left V2
1.0f, 0.0f, -1.0f, //Bottom Right V3
1.0f, 0.0f, 1.0f, //Top Right V4
};
private FloatBuffer textureBuffer;
private float texture[] = {
0.0f, 0.0f, // V1
1.0f, 0.0f, // V3
0.0f, 1.0f, // V2
1.0f, 1.0f // V4
};
// CONSTRUCTORS -----------------------------------------------------------
public PointOfInterest(Location originLocation){
currentLocation = originLocation;
mPoiLocation = new Location(LocationManager.GPS_PROVIDER);
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
// PUBLIC METHODS ---------------------------------------------------------
public void draw(GL10 gl, int textureId){
// Bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// set the colour for the square
//gl.glColor4f(0.0f, 0.1f, 0.0f, 0.5f);
//Set the face rotation
gl.glFrontFace(GL10.GL_CW);
//Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
//Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
....
....
}
I have tried to map the texture as it is taught here and here with no success. I really don't know what to do to get some letters drawn on the squares and am really lost here... Maybe the text is being drawn on the other face of the square, maybe the textures are not being generated... I don't know.
Any kind of help would be very appreciated.
Okay, I had forgotten to enable texture mapping. You can do that within any method that uses the GL10 object. I prefer to do it within the draw method of my objects, so any other object is not affected by the texture. It's as simple as this (just changed 2 lines, the ones that say NEW!!):
public void draw(GL10 gl, int textureId){
gl.glEnable(GL10.GL_TEXTURE_2D); //NEW !!! Enable Texture Mapping
// Bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// set the colour for the square
//gl.glColor4f(0.0f, 0.1f, 0.0f, 0.5f);
//Set the face rotation
gl.glFrontFace(GL10.GL_CW);
//Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
//Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisable(GL10.GL_TEXTURE_2D); ////NEW !!! Disable texture mapping
}

mapping a texture on a square (Android)

Im new to openGL, and im trying to map an texture to a square. I followed NeHe's tutorial on texture mapping here:
http://insanitydesign.com/wp/wp-content/uploads/lesson06.zip
Right now i see my image...but its not mapping correctly. Heres the original image:
http://ge.tt/2FzsdIx
...and heres what im seeing.
http://ge.tt/6y3cdIu
I used the vertices and texture arrays from this great iphone tutorial (link below) so im hoping they have been mapped correctly. Below is the link to my code in Square.java, thanks!
public class Square {
// Our vertices.
private float vertices[] = {
-1.0f, 1.0f, 0.0f, // 0, Top Left
-1.0f, -1.0f, 0.0f, // 1, Bottom Left
1.0f, -1.0f, 0.0f, // 2, Bottom Right
1.0f, 1.0f, 0.0f, // 3, Top Right
};
// The order we like to connect them.
private short[] indices = { 0, 1, 2, 0, 2, 3 };
// Our vertex buffer.
private FloatBuffer vertexBuffer;
// Our index buffer.
private ShortBuffer indexBuffer;
/** The buffer holding the texture coordinates */
private FloatBuffer textureBuffer;
//the texture pointer, holds the texture name which is actually a number.
private int[] textures = new int[1];
public Square() {
// a float is 4 bytes, therefore we multiply the number if
// vertices with 4.
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
// short is 2 bytes, therefore we multiply the number if
// vertices with 2.
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
//plot our texture
float textCoords[]={
//Mapping coordinates for the vertices
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f
};
ByteBuffer tbb = ByteBuffer.allocateDirect(textCoords.length * 4); tbb.order(ByteOrder.nativeOrder());
textureBuffer = tbb.asFloatBuffer(); textureBuffer.put(textCoords);
textureBuffer.position(0);
}
//load our texture(s)
static void loadTexture(GL10 gl, Context context, int resource) {
Bitmap bmp = BitmapFactory.decodeResource(context.getResources(),resource);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterx(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
bmp.recycle();
}
/**
* This function draws our square on screen.
* #param gl
*/
public void draw(GL10 gl) {
//use our textures
gl.glEnable(GL10.GL_TEXTURE_2D); // workaround bug 3623
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Counter-clockwise winding.
gl.glFrontFace(GL10.GL_CCW); // OpenGL docs
// Enable face culling.
gl.glEnable(GL10.GL_CULL_FACE); // OpenGL docs
// What faces to remove with the face culling.
gl.glCullFace(GL10.GL_BACK); // OpenGL docs
// Enabled the vertices buffer for writing and to be used during
// rendering.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// OpenGL docs.
// Specifies the location and data format of an array of vertex
// coordinates to use when rendering.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, // OpenGL docs
vertexBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,// OpenGL docs
GL10.GL_UNSIGNED_SHORT, indexBuffer);
// Disable the vertices buffer.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // OpenGL docs
// Disable face culling.
gl.glDisable(GL10.GL_CULL_FACE); // OpenGL docs
}
}
iPhone tutorial:
http://www.iphonemobilephones.com/opengl-es-from-the-ground-up-part-6-textures-and-texture-mapping.html
You can draw faster using a triangle fan, in the following order in your indices, faster.
01
32
Then you don't need to use drawElements or indices, you can just feed it to drawArrays and only need 4 elements.
Your bug is that the , the tex coords are wrong
tl is 0,0
bl is 0,1
br is 1,1
tr is 1,0
You have
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f
So your UV is wrong.
Normally the rendering of a square in OpenGL looks something like this
gl.glLoadIdentity();
gl.glBindTexture(GL.GL_TEXTURE_2D,0);
gl.glBegin(GL_QUADS)
glVertex(x,y,z);
glTexcoord2f(s,t);
glVertex(-x,y,z);
glTexcoord2f(-s,t);
glVertex(-x,-y,z);
glTexcoord2f(-s,-t);
glVertex(x,-y,z);
glTexcoord2f(s,-t);
gl.glEnd();
I don't see anything like that, but I have never done GLES on Android before so I may be too old.
see https://github.com/ChrisLundquist/Asteroids/blob/master/src/ScenePanel.java#L277

Categories

Resources