UPDATE2: Tried rendering just a quad.
UPDATE: The FULL code is here. Somebody can please confirm any problem with my code? http://dl.dropbox.com/u/8489109/HelloAndroid.7z
I've been trying to draw a circle with Opengl ES 1.0. I've used a lot of SDL and OpenGL on the Windows platform and been using mostly glBegin and glEnd because of the low polygon count that my games used.
Pasted down is my code that is called when the object is created.
float ini[]=new float[360*3];
ByteBuffer temp=ByteBuffer.allocateDirect(ini.length*4);
temp.order(ByteOrder.nativeOrder());
vertex=temp.asFloatBuffer();
int i;
float D2R=(float) (3.14159265/180);
for (i=0;i<360;i++){
float XX=(float)(Math.sin(i*D2R)*size);
float YY=(float)(Math.cos(i*D2R)*size);
ini[i*2]=XX;
ini[i*2+1]=YY;
ini[i*2+2]=0;
}
vertex.put(ini);
Log.d("GAME","SPAWNED NEW OBJECT");
length=ini.length;
//vertex=ByteBuffer.allocateDirect(temp.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
//vertex.put(temp);
vertex.position(0);
Now here is the draw code
Log.d("OBJECT","DUH WRITE");
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glPushMatrix();
gl.glTranslatef((float)x,(float)y,0);
gl.glVertexPointer(3, GL10.GL_FLOAT,0, vertex);
gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, length);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
It draws a circle (when it actually decides to run), and adds some wierd lines.
An example here:
It's the fault of?
gl.glMatrixMode(gl.GL_PROJECTION);
gl.glLoadIdentity();
gl.glViewport(0, 0, arg1, arg2);
gl.glOrthof(0,(float)arg1,(float)arg2,0,-1,1);
gl.glMatrixMode(gl.GL_MODELVIEW);
gl.glLoadIdentity();
This doesn't make sense:
float ini[]=new float[360*3];
/* ... */
for (i=0;i<360;i++){
float XX=(float)(Math.sin(i*D2R)*size);
float YY=(float)(Math.cos(i*D2R)*size);
ini[i*2]=XX;
ini[i*2+1]=YY;
ini[i*2+2]=0;
}
You allocate a multiple of 3 elements, but multiply with a stride of 2. Either do
float ini[]=new float[360*2];
/* ... */
for (i=0;i<360;i++){
float XX=(float)(Math.sin(i*D2R)*size);
float YY=(float)(Math.cos(i*D2R)*size);
ini[i*2]=XX;
ini[i*2+1]=YY;
}
/* ... */
gl.glVertexPointer(2, GL10.GL_FLOAT,0, vertex);
or
float ini[]=new float[360*3];
/* ... */
for (i=0;i<360;i++){
float XX=(float)(Math.sin(i*D2R)*size);
float YY=(float)(Math.cos(i*D2R)*size);
ini[i*3]=XX;
ini[i*3+1]=YY;
ini[i*3+2]=0;
/* ^ */
/* ^ */
}
/* ... */
gl.glVertexPointer(3, GL10.GL_FLOAT,0, vertex);
Also you're using glDrawArrays wrong. You don't use the length of the array in bytes, but the count of vertices to draw – 360 in your case.
gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 360);
Related
I have a float array containing all points in a mesh, and I'm trying to render it as a point cloud, but no matter what, all I get is glitches
Here is the relevant code:
public Plane()
{
...
ByteBuffer bb = ByteBuffer.allocateDirect(vertexCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(vertexCoords);
vertexBuffer.position(0);
...
}
public void draw(GL10 gl)
{
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glPointSize(3);
// Specifies the location and data format of an array of vertex
// coordinates to use when rendering.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawArrays(GL10.GL_POINTS, 0, vertexCoords.length / 3);
// Disable the vertices buffer.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
MyRenderer.java:
public void onSurfaceChanged(GL10 gl10, int i, int i2) {
// Sets the current view port to the new size.
gl10.glViewport(0, 0, i, i2);
// Select the projection matrix
gl10.glMatrixMode(GL10.GL_PROJECTION);
// Reset the projection matrix
gl10.glLoadIdentity();
// Calculate the aspect ratio of the window
GLU.gluPerspective(gl10, 45.0f,
(float) i / (float) i2,
0.1f, 100.0f);
// Select the modelview matrix
gl10.glMatrixMode(GL10.GL_MODELVIEW);
// Reset the modelview matrix
gl10.glLoadIdentity();
}
I got the rendering code from another StackOverflow question, but no matter what I do, all I get is what looks like static. For reference, I get the same (or a similar) effect when I try to triangulate it. (using and index buffer).
As a beginner to android and openGL 2.0 es, I'm testing simple things and see how it goes.
I downloaded the sample at http://developer.android.com/training/graphics/opengl/touch.html .
I changed the code to check if I could animate a rotation of the camera around the (0,0,0) point, the center of the square.
So i did this:
public void onDrawFrame(GL10 unused) {
// Draw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// Set the camera position (View matrix)
long time = SystemClock.uptimeMillis() % 4000L;
float angle = ((float) (2*Math.PI)/ (float) 4000) * ((int) time);
Matrix.setLookAtM(mVMatrix, 0, (float) (3*Math.sin(angle)), 0, (float) (3.0f*Math.cos(angle)), 0 ,0, 0, 0f, 1.0f, 0.0f);
// Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
// Draw square
mSquare.draw(mMVPMatrix);
}
I expected the camera to look always to the center of the square (the (0,0,0) point) but that's not what happens. The camera is indeed rotating around the square but the square does not stay in the center of the screen.. instead it is moving along the X axis...:
I also expected that if we gave the eyeX and eyeY the same values as centerX and centerY,like this:
Matrix.setLookAtM(mVMatrix, 0, 1, 1, -3, 1 ,1, 0, 0f, 1.0f, 0.0f);
the square would keep it's shape (I mean, your field of vision would be dragged but along a plane which would be paralel to the square), but that's also not what happens:
This is my projection matrix:
float ratio = (float) width / height;
// this projection matrix is applied to object coordinates
// in the onDrawFrame() method
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 2, 7);
What is going on here?
Looking at the source code to the example you downloaded, I can see why you're having that problem, it has to do with the order of the matrix multiplication.
Typically in OpenGL source you see matrices set up such that
transformed vertex = projMatrix * viewMatrix * modelMatrix * input vertex
However in the source example program that you downloaded, their shader is setup like this:
" gl_Position = vPosition * uMVPMatrix;"
With the position on the other side of the matrix. You can work with OpenGL in this way, but it requires that you reverse the lhs/rhs of your matrix multiplications.
Long story short, in your case, you should change your shader to read:
" gl_Position = uMVPMatrix * vPosition;"
and then I believe you will get the expected behavior.
I contact because, I try to use openGL with android, in order to make a 2D game :)
Here is my way of working:
I have a class GlRender
public class GlRenderer implements Renderer
In this class, on onDrawFrame I do
GameRender() and GameDisplay()
And on gameDisplay() I have:
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
// 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);
for(Sprites...)
{
sprite.draw(gl, att.getX(), att.getY());
}
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
And in the draw method of sprite I have:
_vertices[0] = x;
_vertices[1] = y;
_vertices[3] = x;
_vertices[4] = y + height;
_vertices[6] = x + width;
_vertices[7] = y;
_vertices[9] = x + width;
_vertices[10] = y + height;
if(vertexBuffer != null)
{
vertexBuffer.clear();
}
// fill the vertexBuffer with the vertices
vertexBuffer.put(_vertices);
// set the cursor position to the beginning of the buffer
vertexBuffer.position(0);
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer.mByteBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer.mByteBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, _vertices.length / 3);
My problem is that I have a low frame rate, even at 30 FPS I loose some frame sometimes with only 1 sprite (but it is the same with 50)
Am I doing something wrong? How can I improve FPS?
In general, you should not be changing your vertex buffer for every sprite drawn. And by "in general", I pretty much mean "never," unless you're making a particle system. And even then, you would use proper streaming techniques, not write a quad at a time.
For each sprite, you have a pre-built quad. To render it, you use shader uniforms to transform the sprite from a neutral position to the actual position you want to see it on screen.
Im drawing a circle and even if i draw a basic shape (eg.square, diamond) using java opengl ES in android.
If I run the application in honeycomb the shape is coming fine but if I run it in gingerbread with the shape few more unnecessary points where getting drawn(it getting scattered) and if I keep on executing it rarely it comes without those points.
My Renderer class,
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -5.0f);
gl.glRotatef(-100, 1.0f, 0.0f, 0.0f);
gl.glRotatef(40, 1.0f, 0.0f, 0.0f);
mCircle= new Circle();
Circle.setCirclePoints(1.5f,4, 1, 360);
Circle.draw(gl);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(-6.5f, +6.5f, -6.5f, 6.5f, 6.5f, -6.5f);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glClearColor(0,0,0,0);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
}
In my Circle Class
public void setCirclePoints(float radius, int slices, int stacks,
float angle)
ByteBuffer vbb = ByteBuffer.allocateDirect(((slices+2)* 3 * 4));
vbb.order(ByteOrder.nativeOrder());
mSliceVertexBuffer = vbb.asFloatBuffer();
mSliceVertexBuffer.put(0.0f);
mSliceVertexBuffer.put(0.0f);
mSliceVertexBuffer.put(nsign * radius);
for (int j = 0; j <= slices; j++) {
theta = j * dtheta;
x = (float) 1.25f * (float) (Math.cos(theta + dupTheta));
y = (float) Math.sin(theta + dupTheta);
z = nsign;
mSliceVertexBuffer.put(x * radius);
mSliceVertexBuffer.put(y * radius);
mSliceVertexBuffer.put(z * radius);
}
}
public void draw(GL10 gl){
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mSliceVertexBuffer);
gl.glColor4f(212,21,54,34);
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0,sliceCount);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
Im really clue less.. I dont know why its not drawing properly in android version <3.0.
edit: I tried to solve it, I found that when I'm trying to plot the points, few vertex are going out of the viewport(may be infinity, I dont know) in android 2.3.3, but for the same points in android 3.0 it drawing the proper shape.
Help me out.
x = (float) 1.25f * (float) (Math.cos(theta + dupTheta));
What's that factor 1.25 supposed to mean? If your circle is coming out as an ellipse, then that's because your projection matrix doesn't take into account window aspect.
I made a blunder mistake
The issue was in
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0,sliceCount);
where the sliceCount is total number of points x,y,z. I divided that one by 3.
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0,sliceCount/3);
I need a little help with this:
android developers, Tutorials: OpenGLES10.
a link
It all works fine for the first Triangle, until I put in the code for Projection & Camera View. This should rezise OpenGLES Square view to match Phone's screen, so object stay in propotions.
As a Newbie watching, the code looks fine and i have cheked with referencefiles, that there's not missing a parameter or something like that. But now i'm lost..! Can't see what's wrong.
If Projection and Camera code are applied, there is no triangle, but the app. is runing and the View with backgroundcolor are shown.
Here is my code:
package notme.helloopengles10;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
public class HelloOpenGLES10Renderer implements GLSurfaceView.Renderer {
// Set the background frame color
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
// initialize the triangle vertex array
initShapes();
//enable use of vertex arrays
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
}
public void onDrawFrame(GL10 gl) {
// Redraw background color
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
/* // set GL_MODELVIEW transformation mode (If outline from here to after GLU.gluLookAt() - it works when also outlines further down i code!
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity(); // reset Matrix to its default state
// when using GL_MODELVIEW, you must set the view point
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f); */
//Draw Triangel
gl.glColor4f(0.63671875f, 0.76953125f, 0.22265625f, 0.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleVB);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
}
// Redraw on orientation changes // adjust for screen size ratio
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
// Make adjustments for screen ratio
/*(If outline from here to after gl.Frumstumf() - it works!
float 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 */
}
/*
* Draw a shape, a triangle. first add new member variable to contain
* the vertices of a triangle
*/
private FloatBuffer triangleVB;
//Create a method, initShaoe(), which populate the members variable
private void initShapes(){
//create a array
float triangleCoords[] = {
// X, Y, Z
-0.5f, -0.25f, 0,
0.5f, -0.25f, 0,
0.0f, 0,559016994f, 0
};
// initialize vertex Buffer for triangle
ByteBuffer vbb= ByteBuffer.allocateDirect(
//(# of coordinates values * 4 bytes per float)
triangleCoords.length * 4 );
vbb.order(ByteOrder.nativeOrder()); // use device hardware's native byte order
triangleVB = vbb.asFloatBuffer(); //create floating point buffer from the ByteBuffer
triangleVB.put(triangleCoords); // add coordinates to the FloatBuffer
triangleVB.position(0); // set the buffer to read the first coordinate
}
} // end
I hope some one can tell me, where things go wrong?
DevTool: Eclipse.
I had the same problem with this tutorial and it got solved when I changed the order of multiplying in the vertex shader code in the Triangle class. So instead of having uMVPMatrix * vPosition, replace it with vPosition * uMVPMatrix. I guess the reason for this is because vPosition is a row vector.
The code looks resonable (if you uncomment the parts that are commented out at the moment). Your matrix modification code is quite correct and all transformations are applied to the correct matrices.
But at the moment you are looking from the point (0,0,-5) to the point (0,0,0) and therefore along the +z axis. But since the default OpenGL view looks along the -z axis, you actually rotate the view 180 degrees around the y-axis. Whereas this is absolutely no problem, you now see the back-side of the triangle. So can it be, that you have back-face culling enabled and this back-side is just optimized away? Just try disabling back-face culling by calling glDisable(GL_CULL_FACE) or change the -5 in the gluLookAt call to a 5, so that you look along the -z axis.
You can also try to use gluPerspective(45, ratio, 3, 7) instead of the glFrustum call, but your arguments to glFrustum look quite reasonable. Of course, keep in mind that both calls create a perspective view, with farther objects getting smaller, like in reality. If you actually want a parallel/orthographic view (where size on screen is independent on depth) you should replace the glFrustum with a glOrtho, though the parameters can stay the same.
Your call to gluLookAt trashes your modelview matrix. You should call this function with the projection matrix active.
http://www.opengl.org/sdk/docs/man/xhtml/gluLookAt.xml
This code shows the triangle for me:
public void onDrawFrame(GL10 gl) {
// Redraw background color
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
// when using GL_MODELVIEW, you must set the view point
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// set GL_MODELVIEW transformation mode (If outline from here to after GLU.gluLookAt() - it works when also outlines further down i code!
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity(); // reset Matrix to its default state
//Draw Triangel
gl.glColor4f(0.63671875f, 0.76953125f, 0.22265625f, 0.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleVB);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
}