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 :)
Related
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.
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 :( ]
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
I'm just translating some bitmaps on the screen. When it's on my phone it looks fine, but when I try to run it on my tablet it looks like it's confined to a screen the size of my phone (roughly). Obviously I want it to scale to the screen size, what am I doing wrong here? I've attached some code and here's a screenshot of what's happening (I've made the background red so it's easy to see what I'm talking about). Thanks!
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//Settings
gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(1.0f, 0.0f, 0.0f, 0.5f); //Black Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glEnable(GL10.GL_BLEND); //Enable blending
gl.glDisable(GL10.GL_DEPTH_TEST); //Disable depth test
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE); //Set The Blending Function For Translucency
//Initiate our stars class with the number of stars
stars = new Stars(num);
//Load the texture for the stars once during Surface creation
stars.loadGLTexture(gl, this.context);
}
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, (float)width / (float)height, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
}
If you need any other code please ask, I assume my problem is somewhere there.
Here's the screenshot
assuming that some opengl-veterans might facepalm now :-)
I am working on a tilebased game (2D only) on android with open gl es.
After days of introducing myself into the concepts of opengl basics, I still don't know how to keep the relation between object and screen size.
To be concrete: My mobile display has 480x800 pixels. When I specify the simple square with its following dimensions, it fills the whole screen (?):
object-vertices:
float vertices[] = { -1.0f, -1.0f, 0.0f, // 0, Top Left
1.0f, -1.0f, 0.0f, // 1, Bottom Left
1.0f, 1.0f, 0.0f, // 2, Bottom Right
-1.0f, 1.0f, 0.0f // 3, Top Right
};
short[] indices = { 0, 1, 2, 2, 3, 0 };
onSurfaceCreated:
public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glShadeModel(GL10.GL_FLAT);
gl.glEnable(GL10.GL_TEXTURE_2D);
GLU.gluOrtho2D(gl, 0, Shared.dm.widthPixels, Shared.dm.heightPixels, 0);
onDrawFrame:
#Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Replace the current matrix with the identity matrix
gl.glLoadIdentity();
//Move this only
gl.glPushMatrix();
Log.d(Shared.LOGTAG, "X: " + offset.x + "Y: " + offset.y);
gl.glTranslatef(offset.x, offset.y, 0);
root.draw(gl);
gl.glPopMatrix();
}
Can anyone give me a hint into the right direction? I assume it has something to do with the matrices?
It looks like this is happening because your projection matrix is getting reset. I see in onSurfaceCreated, you call gluOrtho2D. That's fine, but it doesn't look like you're switching back with glMatrixModel(GL_MODELVIEW). So when glLoadIdentity gets called in onDrawFrame, it will reset your projection matrix.
When the project matrix is identity, coordinates just get passed through. -1 and +1 on the X axis correspond to the left and right sides of the window (respectively). On the Y axis, they are the bottom and top of the window. On the Z axis they are the far and near clipping planes.
Typical, misconception done by OpenGL newbies: They think there is some kind of "one time projection initialization".
You normally setup the whole requires OpenGL state anew everytime you start drawing things. This also catches mishaps like accidently overwriting projection matrices.
onSurfaceCreated:
public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
// Just upload textures and shaders here.
onDrawFrame:
#Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// set everything just right before you need it
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, 0, Shared.dm.widthPixels, Shared.dm.heightPixels, 0);
// order in which different matrices are set is not important,
// but order in which each matrix is manipulated is!
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
// enable and configure blending on a as-needed base
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glShadeModel(GL10.GL_FLAT);
gl.glEnable(GL10.GL_TEXTURE_2D);
//Move this only
// make sure this is operating really on the modelview matrix
// redundant in this rather simple example, but in large codebases
// inevitable.
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glPushMatrix();
Log.d(Shared.LOGTAG, "X: " + offset.x + "Y: " + offset.y);
gl.glTranslatef(offset.x, offset.y, 0);
root.draw(gl);
gl.glPopMatrix();
}