开发者

Android and OpenGL - See object through another object

开发者 https://www.devze.com 2023-02-03 20:36 出处:网络
I\'m a total noob and I\'m trying to display a little submarine I built in a 3d modeling program in opengl (Blender).

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° 开发者_Python百科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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号