Android OpenGL ES - Draw 3D then 2D - where is the fault - android

I found different Stackoverflow-Questons, but I don't see what I'm doing wrong in my code, because the 2D "_floorhelper" texture doesn't show up on the screen. I would like to used it as a HUD element:
Trying to use Ortho for drawing 2D
https://stackoverflow.com/questions/9406753/android-opengl-gluortho2d-keep-original-shape-of-an-object
Android - Draw 3D then 2D with openGL ES
this is my setup:
public void gameSetup(GameActivity activity, GL10 gl) {
_floorhelper = new Mesh( gl, 4, false, true, false );
_floorhelper.texCoord(1, 1);
_floorhelper.vertex(-1, 0, 1 );
_floorhelper.texCoord(1, 0);
_floorhelper.vertex(1, 0, 1 );
_floorhelper.texCoord(0, 0);
_floorhelper.vertex(1, 0, -1 );
_floorhelper.texCoord(0, 1);
_floorhelper.vertex(-1, 0, -1);
try {
InputStream is = getResources().openRawResource(getResources().getIdentifier("levels", "raw", getPackageName()));
levelBitmap = BitmapFactory.decodeStream(is);
levelTexture = new Texture(gl, levelBitmap, TextureFilter.Linear, TextureFilter.Linear, TextureWrap.ClampToEdge, TextureWrap.ClampToEdge);
}
catch(Exception ex){
System.out.print(ex.getMessage());
}
setTractFloor(gl);
float[] lightColor = { 1, 1, 1, 1 };
float[] ambientLightColor = { 0.0f, 0.0f, 0.0f, 1 };
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambientLightColor, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightColor, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, lightColor, 0);
}
public void gameLoop(GameActivity activity, GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glViewport(0, 0, activity.getViewportWidth(), activity.getViewportHeight());
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable( GL10.GL_CULL_FACE );
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
float aspectRatio = (float) activity.getViewportWidth() / activity.getViewportHeight();
GLU.gluPerspective(gl, 67, aspectRatio, 1, 100);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, _scaleFactor, 5.0f, _scaleFactor, 0.0f, 0.0f, 0.0f, 0, 1, 0);
gl.glEnable(GL10.GL_LIGHTING);
gl.glEnable(GL10.GL_LIGHT0);
float[] direction = { 1.5f, 0.5f, 0, 0 };
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, direction, 0);
gl.glEnable(GL10.GL_COLOR_MATERIAL);
// rotation
gl.glRotatef(135, 0, 1, 0);
gl.glEnable(GL10.GL_LINE_SMOOTH);
gl.glBlendFunc(GL10.GL_SRC_ALPHA_SATURATE, GL10.GL_ONE);
gl.glHint(GL10.GL_LINE_SMOOTH_HINT, GL10.GL_NICEST); // no visible diff
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glColor4f(1, 1, 1, 1);
// translation
gl.glTranslatef(-_oldTouchY, 0, _oldTouchX);
// render
currentTractFloor.render();
// Draw 2D ontop of 3D - floorhelper
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, 0.0f, (float) activity.getViewportWidth(), 0.0f, (float)activity.getViewportHeight());
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glDisable(GL10.GL_COLOR_MATERIAL);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
levelTexture.bind();
_floorhelper.render(PrimitiveType.TriangleFan);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glPopMatrix();
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPopMatrix();
}
After the Answer of Stefan Hanke I found the solution.
I've defined the vertices in the mesh wrong. So I always saw just the side of the mesh....
Thanks to Stefan Hanke.
//* Solution Code
public void gameSetup(GameActivity activity, GL10 gl) {
_floorhelper = new Mesh(gl, 4, false, true, false);
_floorhelper.texCoord(0, 1);
_floorhelper.vertex(50, 50, 0);
_floorhelper.texCoord(1, 1);
_floorhelper.vertex(1000, 50, 0);
_floorhelper.texCoord(1, 0);
_floorhelper.vertex(1000, 1000, 0);
_floorhelper.texCoord(0, 0);
_floorhelper.vertex(50, 1000, 0);
try {
InputStream is = getResources().openRawResource(getResources().getIdentifier("levels", "raw", getPackageName()));
levelBitmap = BitmapFactory.decodeStream(is);
levelTexture = new Texture(gl, levelBitmap, TextureFilter.Linear, TextureFilter.Linear, TextureWrap.ClampToEdge, TextureWrap.ClampToEdge);
}
catch(Exception ex){
System.out.print(ex.getMessage());
}
setTractFloor(gl);
float[] lightColor = { 1, 1, 1, 1 };
float[] ambientLightColor = { 0.0f, 0.0f, 0.0f, 1 };
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambientLightColor, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightColor, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, lightColor, 0);
}
public void gameLoop(GameActivity activity, GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glViewport(0, 0, activity.getViewportWidth(), activity.getViewportHeight());
gl.glClearColor(0.18f, 0.68f, 1.0f, 1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_CULL_FACE );
setPerspective(activity, gl);
GLU.gluLookAt(gl, getScaleFactor(), 5.0f, getScaleFactor(), 0.0f, 0.0f, 0.0f, 0, 1, 0);
gl.glEnable(GL10.GL_LIGHTING);
gl.glEnable(GL10.GL_LIGHT0);
float[] direction = { 1.5f, 0.5f, 0, 0 };
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, direction, 0);
gl.glEnable(GL10.GL_COLOR_MATERIAL);
// rotation
gl.glRotatef(135, 0, 1, 0);
gl.glEnable(GL10.GL_LINE_SMOOTH);
gl.glBlendFunc(GL10.GL_SRC_ALPHA_SATURATE, GL10.GL_ONE);
gl.glHint(GL10.GL_LINE_SMOOTH_HINT, GL10.GL_NICEST); // no visible diff
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glColor4f(1, 1, 1, 1);
// translation
gl.glTranslatef(-_oldTouchY, 0, _oldTouchX);
// render
currentTractFloor.render();
// levels
setOrtho2D(activity, gl);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
levelTexture.bind();
_floorhelper.render(PrimitiveType.TriangleFan);
gl.glPopMatrix();
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPopMatrix();
}
private void setPerspective(GameActivity activity, GL10 gl) {
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
float aspectRatio = (float) activity.getViewportWidth() / activity.getViewportHeight();
GLU.gluPerspective(gl, 67, aspectRatio, 1, 100);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
private void setOrtho2D(GameActivity activity, GL10 gl) {
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
// set ortho view
gl.glOrthof(0.0f,(float) activity.getViewportWidth(), 0.0f, (float)activity.getViewportHeight(), -1.0f, 1.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glPushMatrix();
gl.glLoadIdentity();
}

Looks like the matrix setup is incorrect. The meshes vertices all have y=0. With no ModelView matrix whatsoever, you will look at the front edge of the whole mesh. If you remove the second matrix setup from the code -- as you did in your comment to Vincents post -- , the ModelView will be a concoction of the previous gl* calls.

It could be that you didn't define the normals of the vertices of your Mesh.

Related

glRotatef not updating

I want to rotate a Quad along 360 degrees with the code below). I am varying "input" on another procedure (Range = 0 to 1).
Despite "input" changing correctly, I can not seem to update rotation of a quad on screen - It remains stuck at the first angle, e.g. 180 if input is 0.5.
#Override
public void onDrawFrame(GL10 gl) {
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, 0, width, height, 0);
gl.glClearColor(0.f, 0.f, 0.f, 1f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glColor4f(1f, 1f, 1f, 1f);
gl.glPushMatrix();
gl.glTranslatef(width/2, height/2, 0.0f);
gl.glRotatef(360 * input, 0.0f, 0.0f, 1.0f);
gl.glPopMatrix();
bgQuad.setX(0);
bgQuad.setY(0);
bgQuad.draw(gl);
}
Any suggestions?
move popMatrix to after bgQuad.draw(gl);:
#Override
public void onDrawFrame(GL10 gl) {
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, 0, width, height, 0);
gl.glClearColor(0.f, 0.f, 0.f, 1f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glColor4f(1f, 1f, 1f, 1f);
gl.glPushMatrix();
gl.glTranslatef(width/2, height/2, 0.0f);
gl.glRotatef(360 * input, 0.0f, 0.0f, 1.0f);
bgQuad.setX(0);
bgQuad.setY(0);
bgQuad.draw(gl);
gl.glPopMatrix();
}
glPopMatrix resets the matrix back to the most recent saved matrix and throws away the current matrix.

Object not draw properly in openGl Es

I am drawing the 3D object but its not drawing correctly. Original 3D file does not have diagonally but When I am drawing then its showing the diagonal. Please help me to why its drawing the diagonal.
See this link : http://i.stack.imgur.com/Q4plC.png
Code
public void draw(GL10 gl) {
//gl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawArrays(3, 0, v.size()/3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
model.loadGLTexture(gl, context);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glShadeModel(GL10.GL_SMOOTH);
}
/**
* Here we do our drawing
*/
public void onDrawFrame(GL10 gl) {
//Clear Screen And Depth Buffer
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, 0); //Move down 1.2 Unit And Into The Screen 6.0
gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f); //X
gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f); //Y
model.draw(gl); //Draw the square
xrot += xspeed;
yrot += yspeed;
}
/**
* If the surface changes, reset the view
*/
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, width, height); //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, width/height, 0.1f, 500.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
}
Thanks in advance.
Check the exact order of the vertices in vertexBuffer.
If the order jumped over the diagonal way on the rectangle, it will draw the diagonal line.

Why does OpenGL run on some phones but not on others?

I have the following code for my Renderer:
package hello.project;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
public class HelloOpenGLES10Renderer implements Renderer {
private Square square;
private Square2 square2;
private Square3 square3;
private SquareAccesories squareAcc;
private SquareEyes squareEyes;
private SquareLips squareLips;
private SquarePants squarePants;
private SquareShoes squareShoes;
private Context context;
//public static int w,h;
/** Constructor to set the handed over context */
public HelloOpenGLES10Renderer(Context context) {
this.square = new Square();
this.square2 = new Square2();
this.square3 = new Square3();
this.squareAcc = new SquareAccesories();
this.squareEyes = new SquareEyes();
this.squareLips = new SquareLips();
this.squarePants = new SquarePants();
this.squareShoes = new SquareShoes();
this.context=context;
}
public void onDrawFrame(GL10 gl) {
if (Project.ifDraw){
Square.loadGLTexture(gl, this.context,Square.getSex());
Square2.loadGLTexture(gl, this.context,Square2.getHair());
Square3.loadGLTexture(gl, this.context,Square3.getDress());
SquareAccesories.loadGLTexture(gl, this.context,SquareAccesories.getAcc());
SquareEyes.loadGLTexture(gl, this.context,SquareEyes.getEyes());
SquareLips.loadGLTexture(gl, this.context,SquareLips.getLips());
SquarePants.loadGLTexture(gl, this.context,SquarePants.getPants());
SquareShoes.loadGLTexture(gl, this.context,SquareShoes.getShoes());
Project.ifDraw=false;
}
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
//GLU.gluPerspective(gl, 45.0f, (float)w / (float)h, 0.1f, 100.0f);
GLU.gluLookAt(gl, 0, 1, 5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
gl.glColor4f(1.0f, 1.0f, 1.0f, 2.0f);
square.draw(gl);
square2.draw(gl);
square3.draw(gl);
squareEyes.draw(gl);
squareAcc.draw(gl);
squareLips.draw(gl);
squareShoes.draw(gl);
squarePants.draw(gl);
/*// clear Screen and Depth Buffer
Square.loadGLTexture(gl, this.context,Square.getSex());
Square2.loadGLTexture(gl, this.context,Square2.getHair());
gl.glColor4f(1.0f, 1.0f, 1.0f, 2.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
// GLU.gluLookAt(gl, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// Drawing
gl.glTranslatef(0.0f, 0.0f, -5.0f); // move 5 units INTO the screen
square.draw(gl);
square2.draw(gl);*/
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) { //Prevent A Divide By Zero By
height = 1; //Making Height Equal One
}
//w=width;
//h=height;
//Square.loadGLTexture(gl, this.context,Square.getSex());
//Square2.loadGLTexture(gl, this.context,Square2.getHair());
gl.glViewport(0, 0, width, height); //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 Mode lview Matrix
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Load the texture for the square
gl.glEnable(GL10.GL_BLEND);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_FLAT); //Enable Smooth Shading
//gl.glEnable(GL10.GL_ALPHA_TEST);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
//gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
//Square.loadGLTexture(gl, this.context,Square.getSex());
//Square2.loadGLTexture(gl, this.context,Square2.getHair());
//Square3.loadGLTexture(gl, this.context,Square3.getDress());
//SquareAccesories.loadGLTexture(gl, this.context,SquareAccesories.getAcc());
//SquareEyes.loadGLTexture(gl, this.context,SquareEyes.getEyes());
//SquareLips.loadGLTexture(gl, this.context,SquareLips.getLips());
//SquarePants.loadGLTexture(gl, this.context,SquarePants.getPants());
//SquareShoes.loadGLTexture(gl, this.context,SquareShoes.getShoes());
//gl.glAlphaFunc(GL10.GL_GREATER, 0.5f);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //Black Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glDepthFunc(GL10.GL_NEVER); //The Type Of Depth Testing To Do
//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
}
On the emulator, it works perfect. I used an Xperia Play for debugging, and also tried it on an HTC xplorer and Galaxy Nexus, and it worked.
2day i tried it on a Samsung Galaxy and an HTC phone but the SurfaceView did not show nothing, it was blank, any ideeas why this could happen?
Made the pictures dimensions powers of 2 and know it works

Android OpenGL-ES gradient background

I would like to have a gradient background in OpenGL
I found these two links, but I cannot reproduce it:
OpenGL gradient fill on iPhone looks striped
OpenGL gradient banding on Android
I tried the following of the first link:
// Begin Render
//IntBuffer redBits = null, greenBits = null, blueBits = null;
//gl.glGetIntegerv (GL10.GL_RED_BITS, redBits); // ==> 8
//gl.glGetIntegerv (GL10.GL_GREEN_BITS, greenBits); // ==> 8
//gl.glGetIntegerv (GL10.GL_BLUE_BITS, blueBits); // ==> 8
gl.glDisable(GL10.GL_BLEND);
gl.glDisable(GL10.GL_DITHER);
gl.glDisable(GL10.GL_FOG);
gl.glDisable(GL10.GL_LIGHTING);
gl.glDisable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
float[] vertices = {
0, 0,
320, 0,
0, 480,
320, 480,
};
FloatBuffer vertsBuffer = makeFloatBuffer(vertices);
int[] colors = {
255, 255, 255, 255,
255, 255, 255, 255,
200, 200, 200, 255,
200, 200, 200, 255,
};
IntBuffer colorBuffer = makeIntBuffer(colors);
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertsBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glColorPointer(4, GL10.GL_UNSIGNED_BYTE, 0, colorBuffer);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
// End Render
protected static FloatBuffer makeFloatBuffer(float[] arr) {
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
protected static IntBuffer makeIntBuffer(int[] arr) {
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
bb.order(ByteOrder.nativeOrder());
IntBuffer ib = bb.asIntBuffer();
ib.put(arr);
ib.position(0);
return ib;
}
But it just shows a rectangle in the right upper corner. But I don't know if the
glGetIntegerv
would have an effect? Any ideas/links how to make it run?
SOLUTION
// set orthographic perspective
setOrtho2D(activity, gl);
gl.glDisable(GL10.GL_BLEND);
//gl.glDisable(GL10.GL_DITHER);
gl.glDisable(GL10.GL_FOG);
gl.glDisable(GL10.GL_LIGHTING);
gl.glDisable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
float[] vertices = {
0, 0,
_winWidth, 0,
0, _winHeight,
_winWidth, _winHeight
};
FloatBuffer vertsBuffer = makeFloatBuffer(vertices);
float[] colors = {
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
0.2f, 0.2f, 0.2f, 1.0f,
0.2f, 0.2f, 0.2f, 1.0f
};
FloatBuffer colorBuffer = makeFloatBuffer(colors);
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertsBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
I forgot to comment in the perspective line again. I also changed the vertices layed order from "U" shape to the "Z" shape (as commented from Nick).
Now it looks like how I want it:
This is a problem:
int[] colors;
....
gl.glColorPointer(4, GL10.GL_UNSIGNED_BYTE, 0, colorBuffer);
You are using signed four-byte integers for your color channels, and then telling opengl that they are unsigned one-byte integers. You should be using a buffer full of unsigned bytes.
It would be easier however, to just use floats instead:
float[] colors = {
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f,
};
float vertices[] = {
0, 0,
800, 0,
0, 480,
480, 800,
};
FloatBuffer colorBuffer = makeFloatBuffer(colors);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);

Section own objects by touch in OpenGL

I've got a few planes on my OpenGlSurfaceView. Now I want to detect whether a plane is touched. I found a few topics on stackoverflow and in other forums, but I don't know how to deal with them. Maybe anyone could help me.
My planes are all of that structure:
public SimplePlane() {
float textureCoordinates[] = {
0.0f, 1.0f, //
1.0f, 1.0f, //
0.0f, 0.0f, //
1.0f, 0.0f, //
};
short[] indices = new short[] {
0, 1,
2, 1,
3, 2 };
float[] vertices = new float[] {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f };
setIndices(indices);
setVertices(vertices);
setTextureCoordinates(textureCoordinates);
}
I've got an own class for all my Meshes, so SimplePlane extends Mesh. Here you can see the draw method in the Mesh class:
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glCullFace(GL10.GL_BACK);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, verticesBuffer);
gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);
if (colorBuffer != null) {
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
}
if (mShouldLoadTexture) {
loadGLTexture(gl);
mShouldLoadTexture = false;
}
if (mTextureId != -1 && mTextureBuffer != null) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);
}
gl.glRotatef(rx, 1, 0, 0);
gl.glRotatef(ry, 0, 1, 0);
gl.glRotatef(rz, 0, 0, 1);
gl.glTranslatef(x, y, z);
gl.glDrawElements(GL10.GL_TRIANGLES, numOfIndices,
GL10.GL_UNSIGNED_SHORT, indicesBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
if (mTextureId != -1 && mTextureBuffer != null) {
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
gl.glDisable(GL10.GL_CULL_FACE);
}
And that the onDrawFrame Method of my Renderer:
public void onDrawFrame(GL10 gl) {
gl.glClearColor(_red, _green, _blue, 0.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
GLU.gluLookAt(gl, 0,0,0, 0,0,0, 0,0,0);
gl.glLoadIdentity();
gl.glRotatef(_ry, 0f, 1f, 0f);
root.draw(gl); // a group of meshes
}
But now I don't know how I can start to detect a touch of my plane. I read much about color picking or ray picking, but I don't know where I should start in my code to implement it.
First get the point where the user touched on screen using myGLSurfaceView.setOnTouchListener(new MyOnTouchListener()) (where myOnTouchListener implements OnTouchListener).
Then you need to get the MatrixGrabber, MatrixStack, MatrixTracking classes from the API demo's (C:\android-sdk\samples\android-7\ApiDemos\src\com\example\android\apis\graphics\spritetext).
Next, to use the MatrixGrabber, first attach it as a wrapper to your GLSurfaceView:
public class GraphicsEngine extends Activity {
protected GLSurfaceView mGLView;
protected GraphicsRenderer graphicsRenderer;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.graphics);
graphicsRenderer = new GraphicsRenderer(this);
mGLView = (GLSurfaceView) findViewById(R.id.graphics_glsurfaceview1);
// ------
// THIS BIT HERE
mGLView.setGLWrapper(new GLSurfaceView.GLWrapper() {
public GL wrap(GL gl) {
return new MatrixTrackingGL(gl);
}});
// ------
mGLView.setEGLConfigChooser(true);
mGLView.setRenderer(graphicsRenderer);
}
Then you can get the matrices needed for GLU.gluUnProject(). This last method gives you a 3D point on the near-plane (i.e. z = near-plane) where the user touched. You can create a ray using it and the camera 'eye' point, and then detect which objects in your 3D world the ray intersected to get which objects the user picked*:
MatrixGrabber matrixGrabber = new MatrixGrabber();
matrixGrabber.getCurrentModelView(gl);
matrixGrabber.getCurrentProjection(gl);
float[] vector = new float[4];
// x and y come from the x/y you get from the OnTouchListener.
// OpenGL works from the bottom left corner, so flip the y
GLU.gluUnProject(x, mGLView.getHeight()-y, 0.9f, matrixGrabber.mModelView, 0, matrixGrabber.mProjection, 0, new int[]{mGLView.getTop(),mGLView.getLeft(),mGLView.getWidth(),mGLView.getHeight()}, 0, vector, 0);
Vector3f pickPosition = new Vector3f();
if(vector[3]!=0){
pickPosition.x = vector[0] / vector[3];
pickPosition.y = vector[1] / vector[3];
pickPosition.z = vector[2] / vector[3];
}
*This last code snippet I'm not 100% certain works, but the real solution will look something like it
Edit: updated the last code snippet

Categories

Resources