Android OpenGl moving camera and drawing objects - java

I'm creating an app, which should draw objects in constant place on the scene, but when i move my phone around, camera should change view and i should see all object around (when i do full rotation with phone).
When i use gl.glMultMatrixf(rotationMatrix, 0) in my onDrawFrame method and then draw object its working perfect (rotation matrix is obtained from SensorManager)
#Override
public void onDrawFrame(GL10 gl) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glMultMatrixf(rotationMatrix, 0);
gl.glTranslatef(0f, 0f, -10f);
//draw object
pyramid.draw(gl);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
But when i try to use:
GLU.gluLookAt( gl, 0.0f, 0.0f, 0.0f, x, y, z, 0.0f, 1.0f, 0.0f );
gl.glPushMatrix();
//draw object
pyramid.draw(gl);
my object is all time in the same place on screen and follow camera movement. What I'm doing wrong in second example ?

I think you are unclear on what glulookat() actually does. You are asking for a matrix representing glulookat(currentrotationmatrix, mylocation.x, mylocation.y, mylocation.z, whereImlooking.x, whereImlooking.y, whereImlooking.z, upvector.x, upvector.y, upvector.z)
So with that code you are telling opengl to rotate everything, (assuming that code is still present) and then you are saying "I am at origin (0.0, 0.0, 0.0) and looking at xyz" (not sure what xyz is in your case. or what effect you are trying to achieve.)

Related

How make camera?

How i make camera in my lwjgl 3D java application?
I try use glRotate and glTranslatef, but this move only objects, and i need move scene.
Same i try use
glLoadMatrixf(new float[]{
50, 50, 50, 50,
50, 50, 50, 50,
-75, 50, 50, 50,
100, 100, 100, 100
});
But I don’t quite understand how it works, and i see white screen
What solotion i can use for my task?
In OpenGL there is no camera. To "move the camera", you have to move the objects in the opposite direction instead. For example, instead of moving the camera forward, you would move the objects backward.
If you want to make your first view matrix, then start with gluLookAt.
With this handy Legacy OpenGL utility function, you can define a view matrix by a position (eye), a target point (target) and an up vector (up):
(See also Java Code Examples for org.lwjgl.util.glu.GLU.gluLookAt())
GLU.gluLookAt(eye.x, eye.y, eye.z, target.x, target.y, target.z, up.x, up.y, up.z);
The view space is the local system which is defined by the point of view onto the scene.
The position of the view, the line of sight and the upwards direction of the view, define a coordinate system relative to the world coordinate system. The objects of a scene have to be drawn in relation to the view coordinate system, to be "seen" from the viewing position. The inverse matrix of the view coordinate system is named the view matrix. This matrix transforms from world coordinates to view coordinates.
Additionally you well need either an Orthographic or Perspective projection matrix.
The former matrix can be defined by glOrtho
(See also Java Code Examples for org.lwjgl.opengl.GL11.glOrtho())
GL11.glOrtho(0, width, height, 0, 1, -1);
and the later by gluPerspective
(See also Java Code Examples for org.lwjgl.util.glu.GLU.gluPerspective())
GLU.gluPerspective(45.0f, wRatio, (float) near, (float) far);
The projection matrix describes the mapping from 3D points of a scene, to 2D points of the viewport. The projection matrix transforms from view space to the clip space. The coordinates in the clip space are transformed to the normalized device coordinates (NDC) in the range (-1, -1, -1) to (1, 1, 1) by dividing with the w component of the clip coordinates.
In legacy OpenGL there exist different current matrices. The projection matrix should be set to the current GL_PROJECTION matrix and the view matrix to the current GL_MODELVIEW matrix. See glMatrixMode.
e.g.:
float width = ...; // width of the window
float height = ...; // height of the window
Vector3f eye = ...; // camera position
Vector3f target = ...; // camera target
Vector3f up = ...; // camera up vector
float ratio = 1.0f * width / height;
GL11.glViewport(0, 0, (int) w, (int) h);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluPerspective(45.0f, ratio , 0.1f, 100.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GLU.gluLookAt(eye.x, eye.y, eye.z, target.x, target.y, target.z, up.x, up.y, up.z);
Instead of GLU.gluPerspective, a perspective projection matrix can be set as follows:
float width = ...; // width of the window
float height = ...; // height of the window
float fov_y = 45.0f; // filed of view in degrees (y axis)
float n = 0.1f; // near plane
float f = 100.0f; // far plane
float a = width / height;
float ta = Math.tan(Math.radians(fov_y) / 2.0f);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
glLoadMatrixf(new float[]{
1.0f/(ta*a), 0.0f, 0.0f, 0.0f,
0.0f, 1.0f/ta, 0.0f, 0.0f,
0.0f, 0.0f, -(f+n)/(f-n), -1.0f,
0.0f, 0.0f, -2.0f*f*n/(f-n), 0.0f
});
Instead of using a GLU.gluLookAt a view matrix can be set by glTranslate and glRoatate:
float distance = 10.0f; // distance to object
float pitch = 0.0f; // pitch in degrees
float yaw = 0.0f; // yaw in degrees
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glRotatef(yaw, 0.0f, 1.0f, 0.0f);
GL11.glRotatef(pitch, 1.0f, 0.0f, 0.0f);
GL11.glTranslatef(0.0f, 0.0f, -distance);

My Engine flickers when I try to render 2D and 3D

I am working with LWJGL to make a game. It's very basic. Before even implementing any sort of gpu rendering, or fancy model loaders, I wanted to make sure I could at least render 2D and 3D at the same time; My game has a gui while you walk around. Or at least, it is supposed to. Here is my initialization code; The flickering does not happen when I only render 3D.
public void clearGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();
}
public void init3D() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective((float) 68, Engine.size[0] / Engine.size[1], 0.3f, 1000);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
}
public void render3D(Camera c) {
init3D();
clearGL();
//Do translations here
glTranslatef(0f, -5f, 0f);
glColor3f(0, 1, 0);
glBegin(GL_QUADS);
glVertex3f(-50f, 0f, -50f);
glColor3f(0, 0, 1);
glVertex3f(50f, 0f, -50f);
glColor3f(1, 0, 0);
glVertex3f(50f, 0f, 50f);
glColor3f(0, 1, 1);
glVertex3f(-50f, 0f, 50f);
glEnd();
}
public void init2D() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, Engine.size[0], 0, Engine.size[1], -1, 1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glLoadIdentity();
}
public void render2D() {
init2D();
glBegin(GL_QUADS);
glVertex2f(0f, 50f);
glVertex2f(50f, 50f);
glVertex2f(50f, 0f);
glVertex2f(0f, 0f);
glPopMatrix();
}
I can tell its rendering at all because I am drawing a quad to represent the floor in JBullet. For some reason it is above the cameras head, but when I translate the camera up towards it it get's further away, which is why I translated the Camera to -5. That's another problem, for another day.
You should really consider disabling the depth test when you "switch" from 3D to 2D if you are going to draw at Z=0 (middle of your depth range). Half of the visible space in your 3D scene will potentially obstruct your 2D drawing if you do not do this. Alternatively, you could replace your glVertex2f (...) calls with glVertex3f (x,y, -1.0) to bring everything in 2D to the very front of the depth range.
But the really weird thing about all of this is the end of your render2D (...) function: You never call glEnd (...) and you pop a matrix that you appear never to have pushed. That is two sources of mismatched weirdness, either one of them could be causing your problem.

Android OpenGL ES ortho strange aspect ratio

I'm quite new to OpenGL ES and I'm trying to draw some textured quads. I want to keep it 2D so I decided to use orthographic projection. What I really want is to draw a plane that takes the same relative amount of screen space on every device regardless the screen resolution.
The problem I encounter is the setup of the orthographic projection. The aspect ratio just isn't correct. A square is drawn as a rectangle in the height. This is my code so far:
The Renderer:
// automatically looped by android
public void onDrawFrame(GL10 gl) {
// clear screen and buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Draw elements
for (GameObject object : level.getGameObjects()) {
gl.glScalef(0.2f, 0.2f, 0.0f);
object.draw(gl);
gl.glLoadIdentity();
}
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glOrthof(0f, 480f, 0f, 800f, -1f, 1f);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Load all textures
for (GameObject object : level.getGameObjects()) {
object.bindTexture(gl);
}
// Initialize game canvas
gl.glEnable(GL10.GL_TEXTURE_2D); // Enable Texture Mapping
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black background
// enable texture transparency
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
}
The draw method is exactly the same as in this tutorial: http://obviam.net/index.php/texture-mapping-opengl-android-displaying-images-using-opengl-and-squares/
Kind regards,
Daan
Why are you hardcoding the width and height to glOrthof? Shouldn't you use the passed in width and height?
gl.glOrthof(0f, width, 0f, height, -1f, 1f);
I have found the answer to my problem. First of all I was hardcoding the width and height wich wasn't a good option. To have a fixed with on all screen resolutions i now calculate the aspect ratio and for the height I use the with multiplied by the aspect ratio.
Another problem was the fact that I hadn't reset the projection matrix prior to setting the glortho. I have changed all this and it solved the problem:
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0f, 320, 0f, 320*aspect, -1f, 1f);
}
I hope this will be helpfull for somebody.
Kind regards,
Daan
Looks like you've solved it. Can you provide details on how you calculated the aspect variable (a division of height and width perhaps?) Just as an FYI, the height and width values passed in to the onSurfaceChanged() event are indeed dynamic. For instance, they are reversed when you flip the screen orientation.
I'm relatively new to this as well, but in my desktop gl experience, it's important to factor these in when a window size changes.

Setting Up ViewPort for OpenGL ES - Android

I have an OpenGL ES object which I am trying to draw. The object has fairly large vertice values with the x and y co-ordinates lying between -30,000 and +30,000. The z values are between 2000 and -2000.
Can anybody advise me how I should be setting up my viewport ? I am using the following code :
public void onSurfaceChanged(GL10 gl, int width, int height) {
//Define the view frustrum
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
float ratio = (float)width/height;
GLU.gluPerspective(gl, 45.0f, ratio, 1, 100f);
}
public void onDrawFrame (GL10 gl) {
// Clear the screen to black.
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
//Position the model.
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, 0.0f);
//gl.glScalef(0.000015f,0.000015f,0.000015f);
This compiles ok, but I cannot see my object at all.
Thank you.
You probably can't see it because your camera's inside the object. Maybe try first scaling it by 0.001 to get it down to about 60 units across, translate it by -50 in the z direction (to get it to the middle of your z range), and see if it shows up then.
Alternatively you could just make your z-range a lot bigger, and translate it by some -50,000 units in the z direction to move the object back from the camera. You'll have to adjust znear/zfar then to be much larger.

Problem texture mapping a quad in OpenGL with Ortho2D

The following code produces the image that follows. The image I am using for the background is 640 x 480, as is the displayMode. The texture background is a .bmp and is loaded with the Slick texture loader. I am confuse to why it is not filling the Quad and why it is reflected.
EDIT: The background of my OpenGL scene is pink, the black you see is from the Quad created. The background image is the green block with a 2px light blue border with "test" plastered on it.
private void renderBackground(){
float w = displayMode.getHeight()/2;
float h = displayMode.getWidth()/2;
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();
GL11.glLoadIdentity();
GLU.gluOrtho2D(-w, w, -h, h);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glDisable(GL11.GL_DEPTH_TEST);
if(useTextures)background.bind();
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0.0f, 0.0f);
GL11.glVertex2f(-w,-h);
GL11.glTexCoord2f(1.0f, 0.0f);
GL11.glVertex2f(w,-h);
GL11.glTexCoord2f(1.0f, 1.0f);
GL11.glVertex2f(w, h);
GL11.glTexCoord2f(0.0f, 1.0f);
GL11.glVertex2f(-w, h);
GL11.glEnd();
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPopMatrix();
}
Now when I add GL11.glTranslatef(20.0f, 20.0f, 0.0f); you will notice that the pink appears, which is the colour created int my "initGL" method:
GL11.glClearColor(1.0f, 0.75f, 0.796f, 0.0f);
My GL_PROJECTION contains the following before pushing it, my GL_MODELVIEW is unmodified when renderBackground() is called.
GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
GL11.glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(45.0f, (float) displayMode.getWidth() / (float) displayMode.getHeight(), 0.1f, 25.0f);
//position camera
GLU.gluLookAt(5.0f, 3.0f, -5.0f, 0.0f, 0.0f, -10.0f, 0.0f, 1.0f, 0.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
I need more information to determine the problem, but here is a list with some possibilities.
1) You are using an older video card, which does not support texture non-power of 2, since you are using a library to load the texture, maybe it is detecting it, creating a power of two image, and filling it with black.
2) You (or some library you are using) changed the matrix of the texture matrix stack, and it is changing the texture coordinates.
3) You are doing something wrong when you load the texture (or call the library to do so).
The first thing I would check is if your video card supports texture non-power of 2 extension. You can check it at runtime, see how to detect if openGL/card supports non power of 2?
What I see first, is that you compute
float w = displayMode.getHeight()/2;
float h = displayMode.getWidth()/2;
switched?
Second, the texture could be flipped because the loader flipped it (when I remember right this happened to me, too especially with BMPs).

Categories