I am new in OpenGl in android. I am making an application in which I am using the OpenGl Library. When I rotate the 3D object from the finger gesture then Model border is blurring. Please help me why model border is blurred on rotation and move.
private class Renderer implements GLSurfaceView.Renderer {
public Renderer() {
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
getHolder().setFormat(PixelFormat.TRANSLUCENT);
}
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);
build_grid(GRID_SIZE);
if(mModel != null)
mModel.bindTextures(mContext, gl);
}
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, 60.0f, 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();
//position camera
GLU.gluLookAt(gl, mCamera.x,mCamera.y,mCamera.z, mOrigin.x,mOrigin.y,mOrigin.z, 0f,1f,0f);
//draw_grid
draw_grid(gl);
//draw_model
gl.glPushMatrix();
gl.glTranslatef(mOrigin.x, mOrigin.y, 2);
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);
gl.glPopMatrix();
gl.glPopMatrix();
if(isPictureTake) {
IntBuffer ib=IntBuffer.wrap(b);
ib.position(0);
gl.glReadPixels(x, 0, w, y+h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
createBitmapFromGLSurface(context);
isPictureTake = false;
}
}
Thanks in advance.
What you are seeing are jagged (not blurred) lines because of aliasing. A way to avoid this type of aliasing is by using Multi-Sample Anti-Aliasing (MSAA). Whether you can use this easily depends on the support for MSAA (or CSAA for Tegra's) on the GPU, but I believe most modern devices will support it. There are also ways to implement this manually, but that would be a more significant undertaking.
To enable it, you have to select an EGL frame buffer configuration that supports multi-sampling. I think the config chooser that is used in libgdx will give you exactly what you need: you specify the desired number of samples for MSAA (and color depth), and it tries to match a configuration that matches that specification as close as possible.
Related
Here is my problem:
I have a GLSurfaceView with Renderer and stuff. Everything works just as I wanted, on older Android versions. But on newer versions (I guess > 4.X) it just shows a black screen without any Bitmaps. For example if I use gl.glClearColor(0.1f, 0.2f, 0.3f, 0.5f); in my onSurfaceCreated method, it changed from black to the color. So I think the problem must be the camera looking in the wrong direction or something, because the background-color is drawn.
Since I am pretty new to OpenGL, I wanted to ask if there are any connections between Android versions and the OpenGL-camera or something like that?
Many people say my Bitmap-Sizes have to be powers of 2, but it doesnt solve anything.
Here is my Renderer:
public class GlRenderer implements Renderer {
#Override
public void onDrawFrame(GL10 gl) {
// clear Screen Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -5.0f); // move 5 units INTO the screen
// is the same as moving the camera 5 units away
updateLogic(gl);
drawEverything(gl);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION); // or some matrix uniform if using shaders
gl.glLoadIdentity();
gl.glOrthof(0, width, height, 0, -1, 1); // this will allow to pass vertices in 'canvas pixel' coordinates
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping ( NEW )
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Set Background
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
}
}
Not sure if this is the issue you are having, but try changing the following line:
gl.Orthof(0, widht, height, 0, -1, 1);
to
gl.Orthof(0, widht, height, 0, 1, -1);
Notice that the near/far values are inverted. See this for a description of this maddness :)
Do there is any special emulator settings needed to run OpenGL Apps?
I already set "GPU emulation" property to "yes".
I am trying to run an Android sample live wallpaper, using the sample source found from this link, The desired output is a rotating triangle.
After a little effort I got the app running but it doesn't draw anything in emulator but when I tested in device it works, But in the emulator it still just shows a green screen, I found a discussion on it in Google groups here. I tried to set view port as said in it. But still it doesn't show any result, on surface changed I had added this line
gl.glViewport(0, 0, width, height);
Do this is the correct way to set view port?
This is my render class,
public class MyRenderer implements GLWallpaperService.Renderer {
GLTriangle mTriangle;
public void onDrawFrame(GL10 gl) {
gl.glClearColor(0.2f, 0.4f, 0.2f, 1f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
autoRotate(gl);
gl.glColor4f(.2f, 0f, .5f, 1f);
mTriangle.draw(gl);
}
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, 60f, (float)width/(float)height, 1f, 100f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -5);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
mTriangle = new GLTriangle();
gl.glClearDepthf(1f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
}
/**
* Called when the engine is destroyed. Do any necessary clean up because
* at this point your renderer instance is now done for.
*/
public void release() {
}
private void autoRotate(GL10 gl) {
gl.glRotatef(1, 0, 1, 0);
gl.glRotatef(0.5f, 1, 0, 0);
}
}
Herse is GLTriangle class
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.opengles.GL10;
public class GLTriangle {
private FloatBuffer _vertexBuffer;
private final int _nrOfVertices = 3;
private ShortBuffer _indexBuffer;
public GLTriangle() {
init();
}
private void init() {
// We use ByteBuffer.allocateDirect() to get memory outside of
// the normal, garbage collected heap. I think this is done
// because the buffer is subject to native I/O.
// See http://download.oracle.com/javase/1.4.2/docs/api/java/nio/ByteBuffer.html#direct
// 3 is the number of coordinates to each vertex.
_vertexBuffer = BufferFactory.createFloatBuffer(_nrOfVertices * 3);
_indexBuffer = BufferFactory.createShortBuffer(_nrOfVertices);
// Coordinates for the vertexes of the triangle.
float[] coords = {
-1f, -1f, 0f, // (x1, y1, z1)
1f, -1f, 0f, // (x2, y2, z2)
0f, 1f, 0f // (x3, y3, z3)
};
short[] _indicesArray = {0, 1, 2};
_vertexBuffer.put(coords);
_indexBuffer.put(_indicesArray);
_vertexBuffer.position(0);
_indexBuffer.position(0);
}
public void draw(GL10 gl) {
// 3 coordinates in each vertex
// 0 is the space between each vertex. They are densely packed
// in the array, so the value is 0
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, getVertexBuffer());
// Draw the primitives, in this case, triangles.
gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer);
}
private FloatBuffer getVertexBuffer() {
return _vertexBuffer;
}
}
What's going wrong here? Is there a better sample code for Open GL live wallpaper?
AT LAST I FOUND IT..
What I need to do is just add
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
to onSurfaceCreated method along with the code line
gl.glViewport(0, 0, width, height);
in the onSurfaceChanged method in MyRenderer Class
I found a similar question in stack itself [ But Solution worked for me is not marked as correct :( ]
In my program I am rendering a simple triangle and a textured cube, Individually both work fine but when i call the respective draw methods together , the texturing of cube doesn't show.
The onSurfaceCreated function is as shown below:
public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) {
cub.loadGLTexture(gl, this.context);
//gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
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);
}
The onDrawFrame is as shown below:
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, -5, 0, 0, 0, 0, 2, 0);
tri.draw(gl);
gl.glRotatef(-90, 1, 0, 0);
gl.glTranslatef(-6, 0, 0);
cub.draw(gl);
}
I got the answer. Actually i just had to clear the color of the 2D model before binding the 3D model to its texture.Thanks everyone.
I want to display shapes as different as one likes using OpenGL ES on an Android device. Problem is that my code doesn't even work for easy shapes like a rectangle (which I am going to use below).
I think somthing is wrong with the glTranslatef. I've adjusted all the values but I can't figure out what it is.
The Rectangle is defined by the points P(0,0,0), P(0,1,0), P(1,1,0), P(1,0,0). In the Activity I implemented the GLSurfaceView.Renderer like this:
private static FloatBuffer getVertexCoords() {
float coords[] = {
0f, 0f, 0f, // first triangle first point
0f, 1f, 0f, // first triangle second point
1f, 1f, 0f, // first triangle third point
1f, 1f, 0f, // second triangle first point
1f, 0f, 0f, // second triangle second point
0f, 0f, 0f, // second triangle third point
}
ByteBuffer vbb = ByteBuffer.allocateDirect(coords.length * 4); // n coords * 4 bytes per float
vbb.order(ByteOrder.nativeOrder());
FloatBuffer trianglesVB = vbb.asFloatBuffer();
trianglesVB.put(coords);
trianglesVB.position(0);
return trianglesVB;
}
#Override
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(0f, 0f, -4f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // glBegin
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, getVertexCoords());
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 2 * 3 * 3); // triangles * points * coords
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // glEnd
int error = gl.glGetError();
if (error != GL10.GL_NO_ERROR) {
Log.e(TAG, "OpenGL ES Error: " + error);
}
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// think this one doesn't matter
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // white background
gl.glFrontFace(GL10.GL_CW); // front face is clockwise
}
I think you need a projection matrix in there somewhere. If you don't set one, then you are drawing directly in normalized device coordinates, of which the only valid z-values are from (-1 to 1).
Simply your triangle is outside of the depth range displayed.
Try adding a simple projection matrix to onSurfaceCreated:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-10, 10, -10, 10, 0, 10);
I've been on Android for a while, after using Android libraries based on OpenGL ES, I've decided to take the plunge and learn it myself. It seems to be a pretty steep learning curve but I'm committed and always willing to learn. However, after reading whatever beginner tutorials I could find, I'm struggling to string together my first application. I'm simply trying to display a triangle on the screen, but so far all I end up with is a black screen.
If anyone is able to point out where I'm going wrong (and if possible explain why), I'd be really appreciative! Thanks! (Below is the Renderer, I saw no point in including the Activity as well).
public class OpenGLRenderer implements Renderer {
private OpenGLActivity mContext;
public OpenGLRenderer(OpenGLActivity pContext) {
mContext = pContext;
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glClearColor(0.0f, 0.0f, 0.0f, 1f);
gl.glShadeModel(GL10.GL_FLAT);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glDisable(GL10.GL_DITHER);
gl.glDisable(GL10.GL_LIGHTING);
gl.glDisable(GL10.GL_MULTISAMPLE);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glEnable(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnable(GL10.GL_VERTEX_ARRAY);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glFrontFace(GL10.GL_CCW);
gl.glCullFace(GL10.GL_BACK);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glViewport(0, 0, 480, 800);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
}
#Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glLoadIdentity();
gl.glDisable(GL10.GL_TEXTURE_2D);
gl.glColor4f(0f, 1f, 0f, 1f);
float[] vertices = new float[ ]{1,0, 0,1, -1,0};
FloatBuffer buffer = ByteBuffer.allocateDirect(24).order(ByteOrder.nativeOrder()).asFloatBuffer();
buffer.put(vertices);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, buffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, 480, 800);
gl.glLoadIdentity();
}
}
This is a lot of code for just displaying a triangle, probably copied from somewhere. You should try to remove line after line in the onSurfaceCreated method and look if somethings changing. You should also post your activity here.
Here are to examples of rendering a triangle
http://blog.jayway.com/2009/12/03/opengl-es-tutorial-for-android-part-i/
http://code.google.com/p/android-gamedev/source/browse/trunk/src/com/badlogic/gamedev/samples/TriangleSample.java
And since you're learning OpenGL you should have a look at the Jayway tutorials. They helped me a lot