android OpenGL-Es gluProject results not accurate? - android

I want to overlay an icon on top of 3D models in my game. I'm using gluProject to get the screen coordinates of the centre point of the models, and then using that data to draw icons on a custom view:
In my renderer class:
private void projectScreenCoords(GLSurfaceView view, GraphicsEntity ge, GL10 gl){
MatrixGrabber matrixGrabber = new MatrixGrabber();
matrixGrabber.getCurrentModelView(gl);
float[] modelMat = matrixGrabber.mModelView;
matrixGrabber.getCurrentProjection(gl);
float[] projMat = matrixGrabber.mProjection;
gl.glMatrixMode(GL10.GL_MODELVIEW);
// view port
int[] viewport = new int[]{view.getTop(),view.getLeft(),view.getWidth(),view.getHeight()};
float[] vector = new float[4];
GLU.gluProject(ge.getTransform().tx, ge.getTransform().ty, ge.getTransform().tz, modelMat, 0, projMat, 0, viewport, 0, vector, 0);
ge.setScreenCoords(vector[0], viewport[3] - vector[1]);
}
and my custom view:
protected void onDraw (Canvas canvas){
Vector<GraphicsEntity> scene = renderer.getForegroundScene();
for(int i = 0;i<scene.size();i++){
GraphicsEntity ge = scene.get(i);
float[] xy = ge.getScreenCoords();
if(xy[0]>-1 && xy[1]>-1){
canvas.drawBitmap(bitmap, xy[0]-bitmapWidth/2, xy[1]-bitmapHeight/2, null);
}
invalidate();
}
}
and where I set my projection matrix:
protected void setProjectionMatrix(GL10 gl){
float ratio = (float) viewportWidth / viewportHeight;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio*zoom, ratio*zoom, -1*zoom, 1*zoom, nearPlane, farPlane);
}
However, the further from the centre of the screen, the further off the centre of the model the icon is drawn:
Clearly, if it was just the viewport size that was incorrect (due to the bars at the top/bottom) then the icons would be off just in the y-axis, but they are off in the x-axis as well. What am I missing / doing wrong? Also I haven't used the 3rd value returned by gluProject, but this always has a value of 0.7 so I'm not quite sure how it would be used if at all?
Using SDK version 7, I've tested this on multiple devices (ZTE Blade running android 2.1 and Kindle Fire running 2.3.4) with the same results. viewportWidth/Height and view.getWidth/Height() are the same, and view.getTop/Left() returns 0. The MatrixGrabber code works for gluUnProject, so I'm reasonably confident that isn't the problem
EDIT: here is the rest of my GL-related drawing code:
In renderer:
// camera variables
protected float FOV = 60.0f;
protected float nearPlane = 3;
protected float farPlane = 7;
protected float eyeX = 0;
protected float eyeY = 0;
protected float eyeZ = 0;
protected float centreX = 0;
protected float centreY = 0;
protected float centreZ = ((farPlane - nearPlane) / 2) + nearPlane;
protected float upX = 0;
protected float upY = 1;
protected float upZ = 0;
protected float viewportWidth;
protected float viewportHeight;
// user camera control variables
protected float zoom = 1;
protected float rotatedX = 0;
protected float rotatedY = 0;
protected boolean zoomed = true;
protected TrackingTransform tracking;
protected void setWorldTransform(GL10 gl){
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
// transforms the centre position to 0,0,0
gl.glTranslatef(-centreX, -centreY, -centreZ);
}
protected void setModelRotation(GL10 gl, GraphicsEntity ge){
if(ge.isTrackerball()){
gl.glRotatef(rotatedX, 1.0f, 0, 0);
gl.glRotatef(rotatedY, 0, -1.0f, 0);
if(tracking!=null){
synchronized(tracking){
tracking.transform(gl);
}
}
} else if(ge.isBackground()){
gl.glTranslatef(centreX, centreY, centreZ);
gl.glRotatef(rotatedX, 1.0f, 0, 0);
gl.glRotatef(rotatedY, 0, -1.0f, 0);
if(ge.isSkybox()==true){
ge.getTransform().sx = nearPlane + 1.0f;
ge.getTransform().sy = nearPlane + 1.0f;
ge.getTransform().sz = nearPlane + 1.0f;
ge.getTransform().tx = 0;
ge.getTransform().ty = 0;
ge.getTransform().tz = 0;
}
}
}
protected void setModelViewMatrix(GL10 gl){
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
// not used:
//GLU.gluLookAt(gl, eyeX, eyeY, eyeZ, centreX, centreY, centreZ, upX, upY, upZ);
}
#Override
public void onDrawFrame(GL10 gl) {
// Set up various things before drawing
gl.glFrontFace(GL10.GL_CW);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glCullFace(GL10.GL_FRONT);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL10.GL_DEPTH_TEST);
// change projection matrix
float oldzoom = zoom;
zoom = 1.0f;
setProjectionMatrix(gl);
zoom = oldzoom;
// set global world transform (also changes to modelview)
setWorldTransform(gl);
// loop through and draw background models
for(int i = 0;i<backgroundGraphicsEntities.size();i++){
GraphicsEntity ge = backgroundGraphicsEntities.get(i);
SimpleTransform t = ge.getTransform();
int modelIndex = ge.getModelIndex();
if(modelIndex>=0){
gl.glPushMatrix();
setModelRotation(gl, ge);
t.transform(gl);
if(ge.isSprite() && gl11flag){
Sprite s = sprites.get(modelIndex);
s.draw((GL11) gl, ge);
} else {
Model m = models.get(modelIndex);
if(m!=null){
m.draw(gl);
}
}
gl.glPopMatrix();
}
if(i==0 && ge.isSkybox()){
// if skybox, reset depth bit
gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);
}
}
gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);
// change projection matrix (if zoomed)
setProjectionMatrix(gl);
// change back to modelview
gl.glMatrixMode(GL10.GL_MODELVIEW);
// loop through and draw models
for(int i = 0;i<graphicsEntities.size();i++){
GraphicsEntity ge = graphicsEntities.get(i);
SimpleTransform t = ge.getTransform();
int modelIndex = ge.getModelIndex();
if(modelIndex>=0){
gl.glPushMatrix();
setModelRotation(gl, ge);
t.transform(gl);
if(ge.isSprite() && gl11flag){
Sprite s = sprites.get(modelIndex);
s.draw((GL11) gl, ge);
} else {
Model m = models.get(modelIndex);
if(m!=null){
m.draw(gl);
}
if(projectScreenCoords){
projectScreenCoords(glSurfaceView, ge, gl);
}
}
gl.glPopMatrix();
}
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
viewportWidth = width;
viewportHeight = height;
gl.glViewport(0, 0, width, height);
setProjectionMatrix(gl);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
if(gl instanceof GL11){
gl11flag = true;
}
gl.glClearColor(0, 0, 0, 1);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthMask(true);
//gl.glClearDepthf(1.0f);
gl.glDepthFunc(GL10.GL_LEQUAL);
//gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
setProjectionMatrix(gl);
}
and then in SimpleTransform (i.e. what gets called when ge.getTransform().transform(gl) is called):
public void transform(GL10 gl) {
gl.glTranslatef(tx, ty, tz);
gl.glRotatef(rz, 0, 0, 1);
gl.glRotatef(ry, 0, 1, 0);
gl.glRotatef(rx, 1, 0, 0);
gl.glScalef(sx, sy, sz);
}
and for TrackingTransform:
#Override
public void transform(GL10 gl) {
gl.glTranslatef(-tx, -ty, -tz);
}
and finally in model.draw():
public void draw(GL10 gl){
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// Pass the vertex buffer in
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertices);
int textureID = material.getTexture().getTextureID();
if(textureID>=0){
// Enable Textures
gl.glEnable(GL10.GL_TEXTURE_2D);
// Get specific texture.
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
// Use UV coordinates.
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Pass in texture coordinates
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureCoordinates);
}
// Pass in vertex normals
gl.glNormalPointer(GL10.GL_FLOAT, 0, normals);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glDrawElements(GL10.GL_TRIANGLES, numindices,GL10.GL_UNSIGNED_SHORT, indices);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
if(textureID>=0){
// Disable buffers
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}

The problem wasn't in the gluProject code at all. In fact, it was to do with the translations done before calling gluProject:
In onDrawFrame:
Model m = models.get(modelIndex);
if(m!=null){
m.draw(gl);
gl.glTranslatef(-tracking.getTransform().tx, -tracking.getTransform().ty, -tracking.getTransform().tz);
if(tickcount % projectFrequency == 0 ){
projectScreenCoords(glSurfaceView, ge, gl);
}
}

Related

Cast remote display android Nullpointer

When we click on change color button nullpointer exception in CubeRender class.
java.lang.NullPointerException: Attempt to invoke virtual method 'void CubeRenderer.changeColor()' on a null object reference
java class
public class CubeRenderer implements GLSurfaceView.Renderer {
private static final String TAG = "CubeRenderer";
private static final float ANGLE_INCREMENT = 1.2f;
private static final boolean CALCULATE_FPS = false;
private Cube mCube;
private float mAngle;
private boolean mChangeColor;
private long mLastTime;
private long mFpsCounter;
protected final float[] mMMatrix = new float[16];
protected final float[] mMVMatrix = new float[16];
protected final float[] mMVPMatrix = new float[16];
protected final float[] mProjectionMatrix = new float[16];
protected final float[] mViewMatrix = new float[16];
protected final float[] mRotationMatrix = new float[16];
public void onDrawFrame(GL10 unused) {
if (CALCULATE_FPS) {
long currentTime = SystemClock.uptimeMillis();
if (mLastTime == 0) {
mLastTime = currentTime;
} else {
mFpsCounter++;
long diffTime = currentTime - mLastTime;
if (diffTime >= 1000) {
Log.d(TAG, "fps=" + mFpsCounter);
mFpsCounter = 0;
mLastTime = currentTime;
}
}
}
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Set the camera position
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -10, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// Configure matrices for first cube
Matrix.setIdentityM(mMMatrix, 0);
Matrix.translateM(mMMatrix, 0, 0.0f, -0.5f, -1.5f);
Matrix.setRotateM(mRotationMatrix, 0, 2 * mAngle, 0.0f, 1.0f, 1.0f);
Matrix.multiplyMM(mMMatrix, 0, mRotationMatrix, 0, mMMatrix, 0);
Matrix.multiplyMM(mMVMatrix, 0, mViewMatrix, 0, mMMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0);
mCube.draw(mMVPMatrix, mChangeColor);
// Configure matrices for second cube
Matrix.setIdentityM(mMMatrix, 0);
Matrix.translateM(mMMatrix, 0, 0.0f, 2.0f, 0.0f);
Matrix.setRotateM(mRotationMatrix, 0, -mAngle, 0.0f, 1.0f, 1.0f);
Matrix.multiplyMM(mMMatrix, 0, mRotationMatrix, 0, mMMatrix, 0);
Matrix.multiplyMM(mMVMatrix, 0, mViewMatrix, 0, mMMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0);
mCube.draw(mMVPMatrix, mChangeColor);
mAngle += ANGLE_INCREMENT;
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
float ratio = (float) width / height;
GLES20.glViewport(0, 0, width, height);
// Configure perspective with field of view
float fov = 30.0f;
float near = 1.0f;
float far = 100.0f;
float top = (float) Math.tan(fov * Math.PI / 360.0f) * near;
float bottom = -top;
float left = ratio * bottom;
float right = ratio * top;
Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
}
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
// Set background color
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Depth handling
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
// Set anti-aliasing
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
// Important to initialize the graphics on the GL thread
mCube = new Cube();
}
/**
* Utility method to allow the user to change the cube color.
*/
public void changeColor() {
mChangeColor = !mChangeColor;
}
}
Accessing CubeRenderer class method mCubeRenderer.changeColor() exact place where null pointer exception need to handle
public class PresentationService extends CastRemoteDisplayLocalService {
private static final String TAG = "PresentationService";
// First screen
private CastPresentation mPresentation;
private MediaPlayer mMediaPlayer;
private CubeRenderer mCubeRenderer;
#Override
public void onCreate() {
super.onCreate();
// Audio
mMediaPlayer = MediaPlayer.create(this, R.raw.sound);
mMediaPlayer.setVolume((float) 0.1, (float) 0.1);
mMediaPlayer.setLooping(true);
}
#Override
public void onCreatePresentation(Display display) {
createPresentation(display);
}
#Override
public void onDismissPresentation() {
dismissPresentation();
}
private void dismissPresentation() {
if (mPresentation != null) {
mMediaPlayer.stop();
mPresentation.dismiss();
mPresentation = null;
}
}
private void createPresentation(Display display) {
dismissPresentation();
mPresentation = new TVPresentation(this, display);
try {
mPresentation.show();
mMediaPlayer.start();
} catch (WindowManager.InvalidDisplayException ex) {
Log.e(TAG, "Unable to show presentation, display was removed.", ex);
dismissPresentation();
}
}
/**
* Utility method to allow the user to change the cube color.
*/
public void changeColor() {
mCubeRenderer.changeColor();
}
}
Problem solved mCubeRenderer= new CubeRenderer(); need to add this line in PresentationService class

3D Bar graph using OpenGLES in android

I am creating a bar graph in android using opengl
from an activity I'm calling the renderer and from the renderer I'm calling a cube(im using cubes for showing the bars)
Here is my renderer code:
public class BarRenderer implements Renderer {
int[] vals;
private float translatex, translatez, scaly;
public BarRenderer(boolean useTranslucentBackground, int[] vals) {
mTranslucentBackground = useTranslucentBackground;
this.vals = vals;
for (int i = 0; i < this.vals.length; i++) {
mcube[i] = new Cube();
}
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
translatex = 0.5f;
scaly = 0.8f;
for (int i = 0; i < vals.length; i++) {
gl.glTranslatef((-1.0f + (translatex * i)), 0.0f, translatez);
gl.glRotatef(mAngle, 0.0f, 1.0f, 0.0f);
gl.glScalef(0.4f, scaly * vals[i], 0.6f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
mcube[i].draw(gl);
}
mTransY = .075f;
mAngle = -60.0f;
translatez = -7.0f;
Log.i("Draw", "called");
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
float aspectRatio;
float zNear = .1f;
float zFar = 1000;
float fieldOfView = 80.0f / 57.3f;
float size;
gl.glEnable(GL10.GL_NORMALIZE);
aspectRatio = (float) width / (float) height;
gl.glMatrixMode(GL10.GL_PROJECTION);
size = zNear * (float) (Math.tan((double) (fieldOfView / 2.0f)));
gl.glFrustumf(-size, size, -size / aspectRatio, size / aspectRatio,
zNear, zFar);
gl.glMatrixMode(GL10.GL_MODELVIEW);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
if (mTranslucentBackground) {
gl.glClearColor(0, 0, 0, 0);
} else {
gl.glClearColor(1, 1, 1, 1);
}
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_POINT_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
}
private boolean mTranslucentBackground;
private Cube[] mcube = new Cube[4];
private float mTransY;
private float mAngle;
}
but unfortunately it is giving the bar graph like this:
anyone will understand this is not exactly like a bar graph
but please point out my faults here, where am i doing wrong:
1>the bar heights are 4 1 2 1 but they r not accurately of their sizes
2>the space between the bars are supposed to be .5f apart but they start with a big gap but reduce repeatedly after every bar
3>how to start them from one base plane
EDIT:
4> can I animate the growth of this bars?how to do that
My cube code:
public class Cube {
private ByteBuffer mTfan1;
private ByteBuffer mTfan2;
private int bar;
public Cube(int i) {
this.bar = i;
float vertices[] = {
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f,1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f
};
byte maxColor = (byte) 255;
byte colors[][] =
{
{maxColor,maxColor, 0,maxColor},
{0, maxColor,maxColor,maxColor},
{0, 0, 0,maxColor},
{maxColor, 0,maxColor,maxColor},
{maxColor, 0, 0,maxColor},
{0, maxColor, 0,maxColor},
{0, 0,maxColor,maxColor},
{0, 0, 0,maxColor}
};
byte tfan1[] =
{
1,0,3,
1,3,2,
1,2,6,
1,6,5,
1,5,4,
1,4,0
};
byte tfan2[] =
{
7,4,5,
7,5,6,
7,6,2,
7,2,3,
7,3,0,
7,0,4
};
byte indices[] =
{ 0, 3, 1, 0, 2, 3 };
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
mFVertexBuffer = vbb.asFloatBuffer();
mFVertexBuffer.put(vertices);
mFVertexBuffer.position(0);
mColorBuffer = ByteBuffer.allocateDirect(colors.length);
mColorBuffer.put(colors[bar]);
mColorBuffer.position(0);
mTfan1 = ByteBuffer.allocateDirect(tfan1.length);
mTfan1.put(tfan1);
mTfan1.position(0);
mTfan2 = ByteBuffer.allocateDirect(tfan2.length);
mTfan2.put(tfan2);
mTfan2.position(0);
}
public void draw(GL10 gl)
{
gl.glVertexPointer(3, GL11.GL_FLOAT, 0, mFVertexBuffer);
gl.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 0, mColorBuffer);
gl.glDrawElements( gl.GL_TRIANGLE_FAN, 6 * 3, gl.GL_UNSIGNED_BYTE, mTfan1);
gl.glDrawElements( gl.GL_TRIANGLE_FAN, 6 * 3, gl.GL_UNSIGNED_BYTE, mTfan2);
}
private FloatBuffer mFVertexBuffer;
private ByteBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
}
i think something has to be done in the draw method but what??how to animate here?
please help
thanks
2 Before glTranslate and rotate calls you should use glPushMatrix and after that glPopMatrix functions, or call glTranslate without increment. Because glTranslate multiply existing projection matrix on new matrix from glTranslate parameters
3
gl.glPushMatrix() ;
gl.glTranslate(0,y,0);
mcube[i].draw(gl);
gl.glPopMatrix();
with y= - Barheight/2 in your case or change vertex coordinates of your bars
I have done creating the 3d bar graph though I have some other issues right now
but I believe some one might be helpful with this code.
Myrenderer class:
public class BarRenderer implements GLSurfaceView.Renderer {
int[] vals;
private float translatex, scaly;
// For controlling cube's z-position, x and y angles and speeds (NEW)
float angleX = 0; // (NEW)
float angleY = 0; // (NEW)
float speedX = 0; // (NEW)
float speedY = 0; // (NEW)
float translatez;
public BarRenderer(Context context, boolean useTranslucentBackground,
int[] vals) {
mTranslucentBackground = useTranslucentBackground;
mfloor = new Cube(0);
mwall = new Cube(0);
this.vals = vals;
for (int i = 0; i < this.vals.length; i++) {
mcube[i] = new Cube(i);
}
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
translatex = 2.0f;
scaly = 0.8f;
for (int i = 0; i < vals.length; i++) {
gl.glPushMatrix();
mTransY = -5 + (scaly * vals[i]);
gl.glTranslatef((-3.0f + (translatex * i)), mTransY, translatez);
gl.glRotatef(mAngleX, 1.0f, 0.0f, 0.0f);
gl.glRotatef(mAngleY, 0.0f, 1.0f, 0.0f);
gl.glScalef(0.4f, scaly * vals[i], 0.4f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
mcube[i].draw(gl);
gl.glPopMatrix();
}
mTransY = .075f;
// mAngleX = -90.0f;
// mAngleY = -0.01f;
mAngleX += speedX;
mAngleY += speedY;
translatez = -6.0f;
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
float aspectRatio;
float zNear = .1f;
float zFar = 1000;
float fieldOfView = 80.0f / 57.3f;
float size;
gl.glEnable(GL10.GL_NORMALIZE);
aspectRatio = (float) width / (float) height;
gl.glMatrixMode(GL10.GL_PROJECTION);
size = zNear * (float) (Math.tan((double) (fieldOfView / 2.0f)));
gl.glFrustumf(-size, size, -size / aspectRatio, size / aspectRatio,
zNear, zFar);
gl.glMatrixMode(GL10.GL_MODELVIEW);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
if (mTranslucentBackground) {
gl.glClearColor(0, 0, 0, 0);
} else {
gl.glClearColor(1, 1, 1, 1);
}
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_POINT_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
}
private boolean mTranslucentBackground;
private Cube[] mcube = new Cube[4];
private Cube mfloor, mwall;
private float mTransY;
private float mAngleX,mAngleY;
}
and myGLsurfaceview class:
public class MyBarGLSurfaceView extends GLSurfaceView {
BarRenderer renderer; // Custom GL Renderer
// For touch event
private final float TOUCH_SCALE_FACTOR = 180.0f / 320.0f;
private float previousX;
private float previousY;
public MyBarGLSurfaceView(Context context,
boolean useTranslucentBackground, int[] vals) {
super(context);
renderer = new BarRenderer(context, useTranslucentBackground, vals);
this.setRenderer(renderer);
// Request focus, otherwise key/button won't react
this.requestFocus();
this.setFocusableInTouchMode(true);
}
// Handler for key event
#Override
public boolean onKeyUp(int keyCode, KeyEvent evt) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_LEFT: // Decrease Y-rotational speed
renderer.speedY -= 01.1f;
break;
case KeyEvent.KEYCODE_DPAD_RIGHT: // Increase Y-rotational speed
renderer.speedY += 01.1f;
break;
case KeyEvent.KEYCODE_DPAD_UP: // Decrease X-rotational speed
renderer.speedX -= 01.1f;
break;
case KeyEvent.KEYCODE_DPAD_DOWN: // Increase X-rotational speed
renderer.speedX += 01.1f;
break;
case KeyEvent.KEYCODE_A: // Zoom out (decrease z)
renderer.translatez -= 0.2f;
break;
case KeyEvent.KEYCODE_Z: // Zoom in (increase z)
renderer.translatez += 0.2f;
break;
}
return true; // Event handled
}
// Handler for touch event
#Override
public boolean onTouchEvent(final MotionEvent evt) {
float currentX = evt.getX();
float currentY = evt.getY();
float deltaX, deltaY;
switch (evt.getAction()) {
case MotionEvent.ACTION_MOVE:
// Modify rotational angles according to movement
deltaX = currentX - previousX;
deltaY = currentY - previousY;
renderer.angleX += deltaY * TOUCH_SCALE_FACTOR;
renderer.angleY += deltaX * TOUCH_SCALE_FACTOR;
}
// Save current x, y
previousX = currentX;
previousY = currentY;
return true; // Event handled
}
}
though it is done still I would like if anyone can please answer me
1> how to make this bar graphs to grow animatedly, right now when this bar graph activity starts the bar graph appears but i want the bar graph to grow animatedly not just show it
2> how to create a base and a background wall to the bar graph like this link http://www.fusioncharts.com/demos/gallery/#column-and-bar
3> and I was trying to rotate or move the bar graph as per user touch movements i tried the code like another example, you will see that code too and that is why i created this glsurfaceview class of my own, but for some reason it is not working, don't know where and what i have missed, if anyone have any idea please point it out to me
thanks

Rotation issue in 3D Model in OpenGl

I want to rotate the object z axis so I am using the below code but its not rotating at particular position its rotation just go back and appear come near. I think there is wrong with the values in GLU.gluLookAt(gl, 0, 0, 10, 0, 0, 0, 0, 1, 0);. Please help me to set the correct values of these So that rotation works well.
gl.glTranslatef(mOrigin.x, mOrigin.y, mOrigin.z);
gl.glRotatef(mRotate.x, 1f, 0f, 0f);
gl.glRotatef(mRotate.y, 0f, 1f, 0f);
gl.glRotatef(mRotate.z, 0f, 0f, 1f);
private class Renderer implements GLSurfaceView.Renderer {
public Renderer() {
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
getHolder().setFormat(PixelFormat.TRANSLUCENT);
setZOrderOnTop(true);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f,0.0f,0.0f, 0.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
}
public void onSurfaceChanged(GL10 gl, int w, int h) {
mViewWidth = (float)w;
mViewHeight = (float)h;
gl.glViewport(0,0,w,h);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45, mViewWidth/mViewHeight, 0.1f, 100f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glPushMatrix();
gl.glDisable(GL10.GL_DITHER);
GLU.gluLookAt(gl, 0, 0, 10, 0, 0, 0, 0, 1, 0);
//draw_model
gl.glPushMatrix();
if(mOrigin != null && mRotate != null) {
gl.glTranslatef(mOrigin.x, mOrigin.y, mOrigin.z);
gl.glRotatef(mRotate.x, 1f, 0f, 0f);
gl.glRotatef(mRotate.y, 0f, 1f, 0f);
gl.glRotatef(mRotate.z, 0f, 0f, 1f);
}
if(mModel != null) {
mModel.draw(gl, mContext);
if(!RendererView.textureFileName.equals(""))
mModel.bindTextures(mContext, gl);
}
gl.glPopMatrix();
gl.glPopMatrix();
if(isPictureTake) {
w = getWidth();
h = getHeight();
b = new int[w*(y+h)];
bt = new int[w*h];
IntBuffer ib = IntBuffer.wrap(b);
ib.position(0);
gl.glReadPixels(0, 0, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
createBitmapFromGLSurface(mContext);
isPictureTake = false;
}
}
}
ObjLoader.java
package com.amplimesh.models;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.StringTokenizer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
import com.amplimesh.renderer.RendererView;
import com.amplimesh.util.Point3;
/**
* Object Loader and draw the texture and object.
* #author Ajay
*/
public class ObjModel {
/**
* It fill the texture into the mesh
* #param context
* #param gl
*/
public void bindTextures(Context context, GL10 gl) {
Bitmap bitmap;
try {
InputStream is = context.getAssets().open("textures/"+RendererView.textureFileName);
bitmap = BitmapFactory.decodeStream(is);
if(bitmap != null) {
// generate one texture pointer
gl.glGenTextures(1, mTextures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextures[0]);
// 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);
//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, bitmap, 0);
// Clean up
bitmap.recycle();
}
} catch (java.io.IOException e) {
return;
}
}
/**
* It draw the object.
* #param gl
*/
public void draw(GL10 gl, Context mContext) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
for (Model model : mModels) {
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, model.v);
if (model.vt != null && mTextures != null) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextures[0]);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, model.vt);
}
if (model.vn != null) {
gl.glNormalPointer(GL10.GL_FLOAT, 0, model.vn);
}
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, model.v_size);
}
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
/**
* It Load the object from stream.
* #param is
* #param texture_name
* #return
* #throws IOException
*/
public static ObjModel loadFromStream(InputStream is, String texture_name) throws IOException {
ObjModel obj = ObjLoader.loadFromStream(is);
return obj;
}
private Model mModels[];
private int mTextures[] = new int[1];;
/**
* It read the the obj file.
* #author Ajay
*/
private static class ObjLoader {
public static ObjModel loadFromStream(InputStream is) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
ObjModel obj = new ObjModel();
ArrayList<Point3> v = new ArrayList<Point3>();
ArrayList<Point3> vt = new ArrayList<Point3>();
ArrayList<Point3> vn = new ArrayList<Point3>();
ArrayList<Face> f = new ArrayList<Face>();
ArrayList<Model> o = new ArrayList<Model>();
boolean o_pending=false;
while(reader.ready()) {
String line = reader.readLine();
if (line == null)
break;
StringTokenizer tok = new StringTokenizer(line);
String cmd = tok.nextToken();
if (cmd.equals("o")) {
if (o_pending) {
Model model = new Model();
model.fill(f, vt.size() > 0, vn.size() > 0);
o.add(model);
}
else {
o_pending=true;
}
}
else
if (cmd.equals("v")) {
v.add(read_point(tok));
}
else
if (cmd.equals("vn")) {
vn.add(read_point(tok));
}
else
if (cmd.equals("vt")) {
vt.add(read_point(tok));
}
else
if (cmd.equals("f")) {
if (tok.countTokens() != 3)
continue;
Face face = new Face(3);
while (tok.hasMoreTokens()) {
StringTokenizer face_tok = new StringTokenizer(tok.nextToken(), "/");
int v_idx = -1;
int vt_idx = -1;
int vn_idx = -1;
v_idx = Integer.parseInt(face_tok.nextToken());
if (face_tok.hasMoreTokens()) vt_idx = Integer.parseInt(face_tok.nextToken());
if (face_tok.hasMoreTokens()) vn_idx = Integer.parseInt(face_tok.nextToken());
//Log.v("objmodel", "face: "+v_idx+"/"+vt_idx+"/"+vn_idx);
face.addVertex(
v.get(v_idx-1),
vt_idx == -1 ? null : vt.get(vt_idx-1),
vn_idx == -1 ? null : vn.get(vn_idx-1)
);
}
f.add(face);
}
}
if (o_pending) {
Model model = new Model();
model.fill(f, vt.size() > 0, vn.size() > 0);
o.add(model);
}
obj.mModels = new Model[o.size()];
o.toArray(obj.mModels);
return obj;
}
private static Point3 read_point(StringTokenizer tok) {
Point3 ret = new Point3();
if (tok.hasMoreTokens()) {
ret.x = Float.parseFloat(tok.nextToken());
if (tok.hasMoreTokens()) {
ret.y = Float.parseFloat(tok.nextToken());
if (tok.hasMoreTokens()) {
ret.z = Float.parseFloat(tok.nextToken());
}
}
}
return ret;
}
}
private static class Face {
Point3 v[];
Point3 vt[];
Point3 vn[];
int size;
int count;
public Face(int size) {
this.size = size;
this.count = 0;
this.v = new Point3[size];
this.vt = new Point3[size];
this.vn = new Point3[size];
}
public boolean addVertex(Point3 v, Point3 vt, Point3 vn) {
if (count >= size)
return false;
this.v[count] = v;
this.vt[count] = vt;
this.vn[count] = vn;
count++;
return true;
}
public void pushOnto(FloatBuffer v_buffer, FloatBuffer vt_buffer, FloatBuffer vn_buffer) {
int i;
for (i=0; i<size; i++) {
v_buffer.put(v[i].x); v_buffer.put(v[i].y); v_buffer.put(v[i].z);
if (vt_buffer != null && vt[i] != null) {
vt_buffer.put(vt[i].x); vt_buffer.put(vt[i].y);
}
if (vn_buffer != null && vn[i] != null) {
vn_buffer.put(vn[i].x); vn_buffer.put(vn[i].y); vn_buffer.put(vn[i].z);
}
}
}
}
/**
* It hold the vertex buffer, vertex normal and texture.
* #author Ajay
*/
private static class Model {
public FloatBuffer v;
public FloatBuffer vt;
public FloatBuffer vn;
public int v_size;
public void fill(ArrayList<Face> faces, boolean has_tex, boolean has_normals) {
int f_len = faces.size();
this.v_size = f_len * 3;
ByteBuffer tBuf = ByteBuffer.allocateDirect(this.v_size*3 * 4);
tBuf.order(ByteOrder.nativeOrder());
this.v = tBuf.asFloatBuffer();
if (has_tex) {
ByteBuffer vtBuf = ByteBuffer.allocateDirect(this.v_size*3 * 4);
vtBuf.order(ByteOrder.nativeOrder());
this.vt = vtBuf.asFloatBuffer();
}
if (has_normals) {
ByteBuffer vnBuf = ByteBuffer.allocateDirect(this.v_size*3 * 4);
vnBuf.order(ByteOrder.nativeOrder());
this.vn = vnBuf.asFloatBuffer();
}
int i;
for (i=0; i < f_len; i++) {
Face face = faces.get(i);
face.pushOnto(this.v, this.vt, this.vn);
}
this.v.rewind();
if (this.vt != null)
this.vt.rewind();
if (this.vn != null)
this.vn.rewind();
}
}
}
To rotate an object at a specific position around an axis, you first need to translate the object's center to the origin. In your example, you have an object at (mOrigin) which may be relative to another translation (your camera's position).
Instead of translating your object to its final position and then rotating, you need to translate it to (0,0,0), rotate and then translate to the final position.
In the simplest case this would be:
gl.glRotatef (mRotate.x, 1f, 0f, 0f);
gl.glRotatef (mRotate.y, 0f, 1f, 0f);
gl.glRotatef (mRotate.z, 0f, 0f, 1f);
gl.glTranslatef (mOrigin.x, mOrigin.y, mOrigin.z);
In the more complicated case, where your object is relative to the camera, you would have to do something like this:
gl.glTranslatef (-Camera.x, -Camera.y, -Camera.z);
gl.glRotatef (mRotate.x, 1f, 0f, 0f);
gl.glRotatef (mRotate.y, 0f, 1f, 0f);
gl.glRotatef (mRotate.z, 0f, 0f, 1f);
gl.glTranslatef (Camera.x + mOrigin.x, Camera.y + mOrigin.y, Camera.z + mOrigin.z);
The rotation component of the Glulookat seems fine so I dont see any problem there that may cause issues.
First, from the link you provided, it seems to me that you want to rotate about the Y axis although you mentioned the rotation about the Z axis this can give different results. https://www.dropbox.com/s/ozt7beo4gz5q293/demo2__A.avi
Second, what are the values you are using within the m_Rotate vector? are they in degrees or radians?
third, are you pushing or popping the matrix stack? if so how? or are you feeding your own matrix data into the OpenGL?
also have you made sure to call glLoadIdentity() to set the view matrix back to identity matrix during your draw calls?
TBH there can be many areas that may cause issue. To narrow down the possible problem area, do the followings in your draw function;
stop using GluLookAt.
remove all push and pop calls,
firstly make sure to call
glLoadIdentity();
translate your camera behind the object (in your GLuLookAt this is set to 0,0,10).
glTranslatef(0.0f,0.0f,-10.0f);
then do simple rotation around the Z axis by;
glRotatef(mRotate.z, 0.0f, 0.0f, 1.0f);
EDIT: you call onDrawFrame to draw things on the scene as far as I can tell. . and in this call where you need to do these changes to figure out where your problem is.
instead of this;
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glPushMatrix();
gl.glDisable(GL10.GL_DITHER);
GLU.gluLookAt(gl, 0, 0, 10, 0, 0, 0, 0, 1, 0);
//draw_model
gl.glPushMatrix();
if(mOrigin != null && mRotate != null) {
gl.glTranslatef(mOrigin.x, mOrigin.y, mOrigin.z);
gl.glRotatef(mRotate.x, 1f, 0f, 0f);
gl.glRotatef(mRotate.y, 0f, 1f, 0f);
gl.glRotatef(mRotate.z, 0f, 0f, 1f);
}
...
gl.glPopMatrix();
gl.glPopMatrix();
}
try something simpler like this.
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glDisable(GL10.GL_DITHER);
gl.glMatrixMode(GL10.GL_MODELVIEW); //making sure OpenGL currently in model view
gl.glLoadIdentity(); //clear the model view matrix to identity matrix
gl.glTranslatef(0.0f, 0.0f, -10.0f); //move 10 unit backwards so as if camera moves backwards.
gl.glRotatef(90.0f,0.0f,0.0f,1.0f) //rotate 90 degree around the z axis.
//draw_model
...
//gl.glPopMatrix();
//gl.glPopMatrix();
}
by doing so your possible problematic area reduced alot. and you can start figuring out the problem. if the above code works, then possible errors reduced alot.
it could be that;
you setting the matrix mode other then model view somewhere else and not setting it back in your draw call,
you are not clearing the identity matrix in your draw call.
your origin and rotation values are not correctly done.
BTW: Im not an expert in java but in c++ and objective c, we can not do 1f to set a value to float. we must use 1.0f otherwise compiler will complain.

OpenGL ES 1.0 Android simple vertice drawing

I 'm trying to draw some triangles but for some reason I 'm only getting the background.
What do I miss?
Here is my code. It has 2 buffers that are created when onDrawFrame is called for the first time which load vertex and triangle data from an ArrayList or ArrayList I 've created by loading an .OBJ file.
public FloatBuffer fb = null; // To be loaded once in the first draw
public ShortBuffer ib = null;
#Override
public void onDrawFrame(GL10 gl)
{
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_LINE_SMOOTH);
gl.glEnable(GL10.GL_POINT_SMOOTH);
// Clear white
gl.glClearColor(1,0,0,1);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Look At
gl.glPushMatrix();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, -4, 0, 0, 0, 0,1.0f,0);
try
{
gl.glColor4f(1.0f,1.0f,0,1.0f);
int nv = SomeVertexArray.size();
int nt = SomeTriangleArray.size();
if (fb == null)
{
int TotalFBByteSize = 4*3*nv;
fb = ByteBuffer.allocateDirect(TotalFBByteSize).order(ByteOrder.nativeOrder()).asFloatBuffer();
fb.clear();
for(int i = 0 ; i < SomeVertexArray.size() ; i++)
{
VERTEX v = SomeVertexArray.get(i);
fb.put(v.x);
fb.put(v.y);
fb.put(v.z);
}
}
if (ib == null)
{
int TotalTRByteSize = 4*3*nt;
ib = ByteBuffer.allocateDirect(TotalTRByteSize).order(ByteOrder.nativeOrder()).asShortBuffer();
ib.clear();
for(int i = 0 ; i < nt ; i++)
{
TRIANGLE v = SomeTriangleArray.get(i);
ib.put((short)v.i1);
ib.put((short)v.i2);
ib.put((short)v.i3);
}
}
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,fb);
gl.glDrawElements(GL10.GL_TRIANGLES, nt*3, GL10.GL_UNSIGNED_SHORT,ib);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
catch(Throwable ex)
{
ex.printStackTrace();
}
gl.glPopMatrix();
gl.glFlush();
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity(); //reset projection matrix
GLU.gluPerspective(gl,54.0f, (float)width/(float)height, 1.0f, 1000.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //set modelview matrix
gl.glLoadIdentity(); //reset modelview matrix
}
The problem was solved by using fb.put(float[]) instead of fb.put(float), i.e. by passing the entire vertice/triangle array to the direct buffer at once, and not within the loop.
I am not sure why, but it worked.

Android OpenGL ES add object on touch

I am building a small Android application which will add a cube on user's touch. The z depth is always -10, screen is always in landscape mode. This question seems to be asked many times, but I cannot get it running, forgive me as I am newbie to opengl.
I am quite confused about the screen coordinate/window coordinate/object coordinate to use with the gluUnproject. As I understand, screen is when user touch and we get x and y from motion even. Window coordinate is when we load the identity, and object coordinate is when we transform the identity matrix to get object's coordinate. Is that right?
And here is my code, the matrix stacking is from android api sample. Please point out what I am doing wrong.
The drawing part:
public void draw(GL10 gl) {
for (GLObject glObject : list) {
if (glObject != null) {
gl.glLoadIdentity();
glObject.draw(gl);
}
}
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
if (isTouching) {
boolean addObject = false;
for (GLObject glObject : list) {
addObject = glObject.checkTouch(gl, x, y);
}
if (!addObject) {
i++;
Log.d("i", i + "");
addGLObject(gl);
}
isTouching = false;
}
}
Here is the code for adding object
private void getMatrix(GL10 gl, int mode, float[] mat) {
GLView.matrixTrackingGL.glMatrixMode(mode);
GLView.matrixTrackingGL.getMatrix(mat, 0);
}
public void addGLObject(GL10 gl) {
float[] XY = getWorldCoordinate(gl, x, y);
if (XY != null) {
// XY[0] = (float) (x - Main.SCREEN_WIDTH / 2) / 10;
//
// XY[1] = (float) (Main.SCREEN_HEIGHT / 2 - y) / 10;
GLObject glObject = new GLObject(colors, XY[0], XY[1]);
Log.d("Object position", "X: " + XY[0] + " Y: " + XY[1]);
list.add(glObject);
}
}
private float[] getWorldCoordinate(GL10 gl, int x, int y) {
float[] modelMatrix = new float[16];
float[] projMatrix = new float[16];
int[] viewport = {0, 0, Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT};
getMatrix(gl, GL10.GL_MODELVIEW, modelMatrix);
getMatrix(gl, GL10.GL_PROJECTION, projMatrix);
float[] output = new float[4];
GLU.gluUnProject(x, viewport[1] + viewport[3] - y, -10, modelMatrix, 0, projMatrix, 0, viewport, 0, output, 0);
return new float[] {output[0]/output[3], output[1]/output[3]};
}
public class GLObject {
private float[] vertices = { 1.000000f, 1.000000f, -1.000000f, 1.000000f,
-1.000000f, -1.000000f, -1.000000f, -1.000000f, -1.000000f,
-1.000000f, 1.000000f, -1.000000f, 1.000000f, 1.000000f, 1.000000f,
1.000000f, -1.000001f, 1.000000f, -1.000000f, -1.000000f,
1.000000f, -1.000000f, 1.000000f, 1.000000f, };
private short[] faces = { 0, 1, 2, 0, 2, 3, 4, 7, 6, 4, 6, 5, 0, 4, 5, 0,
5, 1, 1, 5, 6, 1, 6, 2, 2, 6, 7, 2, 7, 3, 4, 0, 3, 4, 3, 7 };
private float[] colors;
private float[] rot = { 0.0f, 0.0f, 0.0f };
private Float positionX, positionY;
private int alpha = 0;
// Our vertex buffer.
private FloatBuffer vertexBuffer;
// Our index buffer.
private ShortBuffer faceBuffer;
public GLObject() {
init();
}
public GLObject(float[] colors, float x, float y) {
this.colors = colors.clone();
this.positionX = x;
this.positionY = y;
if (positionX.intValue() % 2 == 0) {
rot[0] = 1.0f;
} else {
if (positionY.intValue() % 2 == 0) {
rot[1] = 1.0f;
} else {
rot[2] = 1.0f;
}
}
init();
}
private void init() {
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
ByteBuffer ibb = ByteBuffer.allocateDirect(faces.length * 2);
ibb.order(ByteOrder.nativeOrder());
faceBuffer = ibb.asShortBuffer();
faceBuffer.put(faces);
faceBuffer.position(0);
}
public boolean checkTouch(GL10 gl, int x, int y) {
boolean isTouched = false;
ByteBuffer pixels = ByteBuffer.allocate(4);
gl.glReadPixels(x, Main.SCREEN_HEIGHT - y, 1, 1, GL10.GL_RGBA,
GL10.GL_UNSIGNED_BYTE, pixels);
Log.d("COLOR",
pixels.get(0) + " " + pixels.get(1) + " " + pixels.get(2) + " "
+ pixels.get(3));
// isTouched always false to test always add object to screen
return isTouched;
}
public void draw(GL10 gl) {
// 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.
// Enable color
gl.glColor4f(colors[0], colors[1], colors[2], 1.0f);
// Specifies the location and data format of an array of vertex
// coordinates to use when rendering.
gl.glPushMatrix();
gl.glTranslatef(positionX, positionY, -10);
// rotate
alpha += 1;
gl.glRotatef(alpha, rot[0], rot[1], rot[2]);
// draw
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, // OpenGL docs
vertexBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, faces.length,// OpenGL docs
GL10.GL_UNSIGNED_SHORT, faceBuffer);
gl.glPopMatrix();
// Disable the vertices buffer.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // OpenGL docs
// Disable face culling.
gl.glDisable(GL10.GL_CULL_FACE); // OpenGL docs
}
}
onDraw:
public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub
// Clears the screen and depth buffer.
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | // OpenGL docs.
GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_PROJECTION);
// Reset the projection matrix
gl.glLoadIdentity();
GLU.gluPerspective(gl, 90.0f, Main.SCREEN_WIDTH/Main.SCREEN_HEIGHT, 3.0f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 4.0f, 2.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
// draw object
glObjectManager.draw(gl);
}
It has nothing to do with landscape mode, the problem is that you are translating your cube by -10 on the z axis. Try putting values of -100 and all the cubes will be at the center. Then try putting 0 for the z value (x, y, 0). The cubes will be much further out from the center of the screen and closer to where you expect them to be.
Look at http://tle.tafevc.com.au/toolbox/file/9495cce8-17b5-a8a5-d9b3-47c0c142d88d/1/sketches_and_drawings_lo.zip/3204a_20_reading_drawings/images/brick_perspective.jpg for an example of perspective projection. When the cube is at z=0, that is what is in the image. But when z=-10, it is closer to the center of the screen (the X) and smaller, because it follows the blue lines out to the horizon.

Categories

Resources