I am currently trying to have a particle fountain spurt out random particles overlaying ontop of a volcano background (textured quad).
I have the volcano backgound and the particles draw statement inside the onDrawFrame
public void onDrawFrame(GL10 gl)
{
// Set the clear colour to red and clear the screen
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// Enable the vertex array client state
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
background.draw(gl);
// Draw then update the position of all particles
for (VolcanoParticle p : particleArray)
{
p.draw(gl);
p.update();
}
//background.draw(gl);
// Disable the vertex array client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}
The "background.draw(gl);" is meant do use the class's in VolcanoBackground.java while the p.draw(gl); is meant to use the VolcanoParticle.java. But for some reason the VolcanoParticle.draw is also affecting the background.draw causing the background to also have the same movements and colorchanges / gravity / movement as the particles.
any ideas on how to fix?
Also with the background.draw it makes the particles very hard to see as if there is a black shroud over the top of them, is there a way to remove this alpha layer or whatever it is or force the background to be behind the particles?
Perhaps you need to reset your model-view matrices between drawing each object by calling glLoadIdentity() on them.
Regarding the dimming problem, try disabling lighting. If that is the problem, then you probably need to move the light closer to the model.
Related
I'm working on an OpenGL application, specifically for Android with OpenGL ES (2.0 I think). I can currently draw objects independently and rotate the scene all at once. I need to be able to translate/rotate individual objects independently and then rotate/translate the whole scene together. How can I accomplish this? I've read several threads explaining how to push/pop matrices but I'm pretty sure this functionality was deprecated along with the fixed function pipeline of OpenGL 1.1.
To give some perspective, below is the onDrawFrame method for my renderer. Field, Background and Track are all classes I've made that encapsulate vertex data and the draw method draws the appropriate matrices to the supplied context, in this case GL10 'gl'.
//clear the screen
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |GL10.GL_DEPTH_BUFFER_BIT);
// TODO Auto-generated method stub
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, 60, 0, 0, 0, 0, 2, 0);//setup camera
//apply rotations
long time = SystemClock.uptimeMillis();
float angle = ((int)time)/150.0f;
gl.glRotatef(55.0f, -1, 0, 0);//rotates whole scene
gl.glRotatef(angle, 0, 0, -1);//rotates whole scene
MainActivity.Background.draw(gl);
MainActivity.Track.draw(gl);
MainActivity.Field.draw(gl);
*Update: As it turns out, I can push and pop matrices. Is there anything wrong with the pushing/popping method? It seems to be a very simple way of independently rotating and translating objects which is exactly what I need. *
There should be nothing wrong with using glPushMatrix and glPopMatrix. The Android implementation of ES 2.0, to my understanding, has default shaders which behave exactly like the default fixed-function pipeline, and you can use the fixed-function pipeline functions. They will behave identically.
I have some questions about using the openGL
I am newbie in using the openGL and I try to set the RGB of the square and it works but it does not work after i use the blend function. And the square finally disappear when it redraw.
The following is the part of the code
#Override
public void onDrawFrame(GL10 gl) {
// clear Screen and Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
// Drawing
gl.glTranslatef(0.0f, 0.0f, -5.0f); // move 5 units INTO the screen
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
GLES20.glEnable(GLES20.GL_BLEND); // is the same as moving the camera 5 units away
square.draw(gl); // Draw the triangle
//square.loadGLTexture(gl, this.context);
gl.glColor4f(red, green, blue, 0f);
red = red - 0.01f;
blue = blue - 0.01f;
green = green - 0.01f;
GLES20.glDisable(GLES20.GL_BLEND);
}
The first time onDrawFrame is called, both color and depth buffers are cleared, then a triangle is drawn and, after that, color is changed with a 0 alpha value.
Next time onDrawFrame gets called, the triangle is drawn once again but this time using the alpha value 0. Being both color and depth buffers cleared as they have been, all you probably see is an empty screen because 0 alpha, using that blend function, can be translated to "completely transparent".
I am new to opengl and have no idea how to deal with opacity. I have two layers that are overlapped i am drawing both the layers on to the screen. I want to fade out the one in the foreground to transtition to the background image. Is there any way to do this?? Here's my draw method.
public void draw(GL10 gl10) {
gl10.glDisable(GL10.GL_BLEND);
gl10.glEnable(GL10.GL_BLEND);
gl10.glBlendFunc(GL10.GL_TRUE, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl10.glClearColor(0F, 0F, 0F, 0);
gl10.glBindTexture(GL10.GL_TEXTURE_2D, this.mTextureId);
this.layer1.draw(gl10); // i want to transition from this layer
this.layer2.draw(gl10); // to this layer by changing opacity
}
I dont know even i framed my question correctly. Hope you get it :)
Well it depends on the method you're using for this transition. I have a similar situation with an animation view. About your opacity problem, can't you use
View v;
int i = 0; /*Values from 0 to 1, float cast might be needed for intermediate values*/
v.setAlpha(i);
this.layer2.setAlpha(i);
Or something like that, isn't this applicable in your case?
i have written code for draw a triangle and rectangle.
// Reset the Modelview Matrix
gl.glLoadIdentity();
gl.glTranslatef(0.0f, -1.2f, -6.0f);
tt.draw(gl); //rectangle class draw method
gl.glTranslatef(0.0f, 2.5f, 0.0f);
tr.draw(gl); //triangle class draw method
i have load a texture on rectangle
// Load the texture for the rectangle in onSurfaceCreated()
tt.loadGLTexture(gl, this.context);
my problem is the texture mapping on triangle shape also
the screen shot is available in following link.
http://www.freeimagehosting.net/uploads/82fe919770.png
how can i resolve this problem?
It seems like this would be a fairly simple problem to fix, and I don't believe it's Android specific... Are you defining the UV Texture Coordinates for your object? If you don't, OpenGL will not display the texture properly. You can use either the glTexCoord3f function in immediate mode, or glTexCoordPointer if you're using C arrays.
I'm a total noob and I'm trying to display a little submarine I built in a 3d modeling program in opengl (Blender).
The submarine is built using a long cylinder with a sphere intersecting on the end of it.
The problem that I'm getting is that when I look at the result, I can see the entire sphere through the cylinder. I can also see the end of the cylinder through the sphere. This appears when I have lighting on. I'm using ambient and diffuse lighting. I just want to see half the sphere on the outside of the cylinder and I don't want to see any innards.
I have face culling on and it removes the front faces of both objects, but I clearly see the sphere.
Below I pasted my onSurfaceCreated function where I set up all the opengl parameters. Any suggestions are appreciated!
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//
gl.glEnable(GL10.GL_DEPTH_TEST);
//gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glEnable(GL10.GL_POLYGON_OFFSET_FILL);
gl.glEnable(GL10.GL_LIGHTING);
gl.glEnable(GL10.GL_LIGHT0);
// Define the ambient component of the first light
float[] light0Ambient = {0.1f, 0.1f, 0.1f, 1.0f};
gl.glLightfv(gl.GL_LIGHT0, gl.GL_AMBIENT, FloatBufferFromFloatArray(light0Ambient, 4));
// Define the diffuse component of the first light
float[] light0Diffuse = {0.7f, 0.7f, 0.7f, 1.0f};
gl.glLightfv(gl.GL_LIGHT0, gl.GL_DIFFUSE, FloatBufferFromFloatArray(light0Diffuse, 4));
// Define the specular component and shininess of the first light
float[] light0Specular = {0.7f, 0.7f, 0.7f, 1.0f};
float light0Shininess = 0.4f;
//gl.glLightfv(gl.GL_LIGHT0, gl.GL_SPECULAR, FloatBufferFromFloatArray(light0Specular, 4));
// Define the position of the first light
float[] light0Position = {1.0f, 0.0f, 0.0f, 0.0f};
gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, FloatBufferFromFloatArray(light0Position, 4));
// Define a direction vector for the light, this one points correct down the Z axis
float[] light0Direction = {0.0f, 0.0f, -1.0f};
//gl.glLightfv(gl.GL_LIGHT0, gl.GL_SPOT_DIRECTION, FloatBufferFromFloatArray(light0Direction, 3));
// Define a cutoff angle. This defines a 90° field of vision, since the cutoff
// is number of degrees to each side of an imaginary line drawn from the light's
// position along the vector supplied in GL_SPOT_DIRECTION above
//gl.glLightf(gl.GL_LIGHT0, gl.GL_SPOT_CUTOFF, 180.0f);
gl.glEnable(GL10.GL_CULL_FACE);
// which is the front? the one which is drawn counter clockwise
gl.glFrontFace(GL10.GL_CCW);
// which one should NOT be drawn
gl.glCullFace(GL10.GL_BACK);
gl.glClearDepthf(10f);
gl.glPolygonOffset(1.0f, 2);
initShape();
gl.glScalef(0.5f, 0.5f, 0.5f);
}
Have you tried checking to see if it's a backface culling issue? Check it by changing the glEnable(GL_CULL_FACE) to glDisable, just to check it's definitely not that. It can be possible to have both winding orders on the same mesh, so culling can be right for one part of the model but wrong for another - it's easiest just to disable it to be sure that's not the issue.
It's either that or your surface may have been created without a depth buffer for some reason? Check the EGLConfig parameter to be sure that's not the case. Usually it would be created with a depth buffer by default, but it's possible to override that behaviour.
Also modelling things with internal faces which will never be seen is not going to do good things for your realtime performance. You should consider using a boolean 'or' operation in blender at least to get rid of the internal faces but ultimately it's best to craft your models with lots of care and attention to their topology, not just for poly count but also for how well they fit together into a triangle strip (that doesn't excuse the issue you're getting right now - that's just a note for the future)
I see, that you're still thinking in terms of "initializing some scene graph". That's not how OpenGL works (gee, this is the third time in a row I write this as answer). All that stuff you've doing in onSurfaceCreated actually belong into the display routine. OpenGL is not a scene graph. You set all the state you need right before you're drawing the stuff that requires that state.
I see you've that function "initShape" there. I don't think this does what you intend.
Are you sure you have an EGL context with the depth buffer enabled? If you are using GLSurfaceView you probably are looking for something like SimpleEGLConfigChooser(false) which should be SimpleEGLConfigChooser(true).
Lets see your onDrawFrame()? What is your projection, it could be flipped normals AND a messed up projection making it look funny.
Problems with your depth buffer or depth testing are possible too.
Edit: It looks like depth-test is not your problem, since you can see depth-culling from your the polygon that is intersecting the the sphere. It looks like your geometry is the problem.
I'd make it so your camera can move, then you can look around and figure out whats messed up with it.
If you are using textures have a look at the blending function you are using. It might be the case that pixels that overlap get multiplied as in an overlay effect rather than overwritten which is what you want I suppose.