Drawing 2D on a GLSurfaceView - android

I am attempting to draw a 2D square on a GLSurfaceView in 2D mode. I can draw the object in 3D mode and have tested that the square is out in 3D space. I then try to configure the matrix for 2d drawing and when I attempt to draw my object nothing appears.
My GLSurfaceView instance implements GLSurfaceView.Renderer.
I've broken the setup into two functions:
private void prepare3Ddrawing(GL10 gl)
{
gl.glLoadIdentity();
gl.glViewport(0, 0, getWidth(), getHeight());
gl.glDisable(GL10.GL_DITHER);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f, (float)getWidth()/(float)getHeight(),0.1f,100.0f);
}
private void prepare2Ddrawing(GL10 gl)
{
gl.glDisable(GL10.GL_CULL_FACE);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluOrtho2D(gl,0,getWidth(), 0, getHeight());
gl.glScalef(1, -1, 1);
gl.glTranslatef(0, -getHeight(), 0);
gl.glMatrixMode(GL10.GL_MODELVIEW);
}
And here is my draw method...
public void onDrawFrame(GL10 gl)
{
gl.glClear(GL10.GL_DEPTH_BUFFER_BIT|GL10.GL_COLOR_BUFFER_BIT);
prepare3Ddrawing(gl);
camera.draw(gl);
go2d.draw(gl);
prepare2Ddrawing(gl);
go2d.draw(gl);
}
and finally, my go2d object is an instance of an object I created called GameObject2d. It's draw method looks like this...
#Override
public void draw(GL10 gl)
{
super.draw(gl);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_ALPHA_TEST);
gl.glAlphaFunc(GL10.GL_GREATER, 0.0f);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2,GL10.GL_FLOAT,0,textureBuffer);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable(GL10.GL_BLEND);
gl.glFrontFace(GL10.GL_CW);
//gl.glEnable(GL10.GL_CULL_FACE);
gl.glCullFace(GL10.GL_BACK);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_SHORT, indexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
gl.glDisable(GL10.GL_ALPHA_TEST);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
Does anyone have any ideas? Again, I am still able to see the 3D rendered version of the go2D object, but I do not see the 2D version.
Thanks.

As you don't include any data, I can only propose two methods to debug the issue.
Step 1: try to force your 2d - perspective matrix and modelview matrix to be Identity Matrices. Then if you force your Square data vertices inside the clip space (e.g.
x,y = +-1 or x,y= +-0.75, z=0, you should see a square appearing in the screen.
Step 2: now that the data model is correct, check what your model view and perspective matrices do: multiply each of your square vertices (x,y,z, w=1) with ModelView Matrix * CameraMatrix * PerspectiveMatrix. What do you get? Are the x,y,z much outside |w| ?

Related

PNG with Alpha on a 3D Object Android Opengl

I have created a shpere with texture and displayed correctly using opengl es on Android 2.3. I want to add a 2-D PNG with alpha such that, transparent section of my PNG shows the sphere. I could achieve transparency with my PNG and another PNG textured on a Sqaure but when I apply same thing with Sphere it distorts the texture on Sphere. How can i achive this?
Here is the code I used.
public void onSurfaceChanged(GL10 gl, int width, int height) {
if (height == 0) height = 1; // To prevent divide by zero
float aspect = (float)width / height;
// Set the viewport (display area) to cover the entire window
gl.glViewport(0, 0, width, height);
// Setup perspective projection, with aspect ratio matches viewport
gl.glMatrixMode(GL10.GL_PROJECTION); // Select projection matrix
gl.glLoadIdentity(); // Reset projection matrix
// Use perspective projection
GLU.gluPerspective(gl, 45, aspect, 0.1f, 100.f);
gl.glMatrixMode(GL10.GL_MODELVIEW); // Select model-view matrix
gl.glLoadIdentity(); // Reset
texs[0] = loadTexture(gl, context, "e.png");
texs[1] = loadTexture(gl, context, "ipo7x.png");
gl.glEnable(GL10.GL_TEXTURE_2D);
}
// Call back to draw the current frame.
public void onDrawFrame(GL10 gl) {
// Clear color and depth buffers using clear-value set earlier
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glLoadIdentity(); // Reset model-view matrix ( NEW )
gl.glTranslatef(0.0f, 0.0f, -6.0f);
gl.glClientActiveTexture(GL10.GL_TEXTURE0); //new
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 8, sphere.getTextureBuffer());
gl.glActiveTexture(GL11.GL_TEXTURE0); //2
gl.glBindTexture(GL11.GL_TEXTURE_2D, texs[0]);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);
gl.glClientActiveTexture(GL10.GL_TEXTURE1);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 8, square.getTexBuffer());
gl.glActiveTexture(GL10.GL_TEXTURE1); //2
gl.glBindTexture(GL10.GL_TEXTURE_2D, texs[1]);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_COMBINE);
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC0_RGB, GL11.GL_PRIMARY_COLOR);
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND0_RGB, GL11.GL_SRC_COLOR);
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC1_RGB, GL11.GL_PREVIOUS);
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND1_RGB, GL11.GL_SRC_COLOR);
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_RGB, GL11.GL_TEXTURE);
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_RGB, GL11.GL_SRC_COLOR);
gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_RGB, GL11.GL_INTERPOLATE);
sphere.draw(gl);
square.draw(gl);
gl.glDisable(GL10.GL_DEPTH_TEST);
}

How to set on texture on top of another texture in android using OPEN GL

I have been searching for this for the pass two days .I am developing an android game using Open GL in which there is a situation where i have to display two images at the same time, one should be the background image and second one is displayed depending on a condition.
I have displayed the background imgae using Open GL Texture property.But when i tried to display the second image by using texture first one is not displaying.Since i am dealing with multiple texture i have used a GLTexture class to manipulate the texture (http://tkcodesharing.blogspot.in/2008/05/working-with-textures-in-androids.html).Even then i am not able to display two images at the same time.
Here is some code :
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
glTextures= new GLTextures(gl,this.context);//class to manipulate textures
//adding image resources
this.glTextures.add(R.drawable.back);
this.glTextures.add(R.drawable.hand);
//loading texture
this.glTextures.loadTextures();
gl.glEnable(GL10.GL_TEXTURE_2D);
...
}
In onDrawFrame
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -3.5f);
glTextures.setTexture(R.drawable.back);//it will bind this particular texture for drawing
draw(gl);
if(condition == 1){
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 1.0f, -7.0f);
glTextures.setTexture(R.drawable.hand);
drawSecond(gl);
}
////////////////////////////////////////////////////////
In draw code
public void draw(GL10 gl){
gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length/3);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
public void drawSecond(GL10 gl){
gl.glActiveTexture(GL10.GL_TEXTURE1);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//GLES20.glUniform1i(isShaked, 1);
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length/3);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
remove "gl.glActiveTexture(GL10.GL_TEXTURE0);" and gl.glActiveTexture(GL10.GL_TEXTURE1);
lines from the rendering code.
you use multiple texture units only if you need multi-texturing,
which is using multiple textures in one draw call.
just bind the first texture to the active texture unit (default to GL_TEXTURE0) and draw the first triangle strip, than bind the second texture (without changing the active texture unit GL_TEXTURE0) and draw the second triangle strip.

How to efficiently draw 2d with openGl es?

Originally I was using the canvas to draw my bitmaps in a 2d real time action type game, but for some reason my frame rate was terrible. I suspected it was the canvas so I switched to opengl. From surfing on the internet I learned to create a rectangle from 2 triangles and set a texture on it. I used glOrthof to set it up the 2d perspective and used the gltranslatef method to move my textures. I know the problem isn't the physics or anything because I tested moving a single texture at a constant velocity, (The x value moving at about 7 units per 33 milliseconds). It was still choppy. I set the fps to 30. This is my game loop:
public void onDrawFrame(GL10 gl) {
startTime = System.nanoTime();
gl.glClearColor(0f, .0f, .8f, 0.5f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
g.updatePhysics();
onDraw(gl);
sleepTime = (int) (TICKS_INTERVAL - (System.nanoTime() - startTime)/1000000);
if(sleepTime > 0){
try{
Thread.sleep(sleepTime);
}catch(Exception e){}
}
}
and this is how they're being drawn:
public void onDraw(GL10 gl){
gl.glLoadIdentity();
if(g.state == g.STATE_GAME){
gl.glTranslatef(x, y, z);
rectangle.draw(gl);
gl.glLoadIdentity();
gl.glTranslatef(x, y, z);
rectangle2.draw()gl;
}
}
And this is the draw method within the rectangle:
public void draw(GL10 gl){
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glFrontFace(GL10.GL_CW);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuff);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuff);
gl.glDrawElements(GL10.GL_TRIANGLES, pIndex.length, GL10.GL_UNSIGNED_SHORT, pBuff);// Draw the vertices as triangle strip
//gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
Even when I set the frame rate to 60 there's still some stuttering, and it's frustrating because for the past month I've been just trying to get the frame rate smooth. I'm testing on a galaxy s2 so I know it isn't the hardware. If all this code is right, do you think maybe it could be something else in the activity? My GLSurfaceView is actually a custom view. Even getting a single texture to move smoothly at a constant velocity would be nice.

Getting started with OpenGL ES 1.x on Android - Basic primitives

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

How to flip an Image in OpenGL?

I hate to ask such a dumb question but I just can't firgure out how to flip an image using Android OpenGL.
I try using gl.glScalef(-1,y,z) android gl.glRotatef(180,0,1,0) but when I do this the image flip but it also change the positions which I do not want. I'm sure there a easy way to do this I'm just not getting.
Here is my draw code:
public void draw(GL10 gl){
gl.glLoadIdentity();
gl.glTranslatef(position.x, position.y, 0);
gl.glRotatef(angle, rotX, rotY, rotZ);
gl.glScalef(scaleX, scaleY, scaleZ);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId[0]);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnable(GL10.GL_BLEND);
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexsBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisable(GL10.GL_BLEND);
if(animation == true){
PlayAnimations();
}
}
center the object (remember the translation)
perform the flipping by scaling to -1 with respect to the desired axis.
then "reverse translate" the object.
For more information, please grab yourself a copy of Computer Graphics by James D. Foley.
http://www.amazon.com/Computer-Graphics-Principles-Practice-2nd/dp/0201848406
You could use a different set of texture coordinates or use a texture matrix.

Categories

Resources