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.
Related
I'm trying to make a hexagon with 6 triangles using rotation and translation. Rather than making multiple translate calls, I instead want to translate the triangle downward once and rotate around the Z axis at 60 degrees six times (my sketch may help with that explanation: http://i.imgur.com/SrrXcA3.jpg). After repeating the drawTriangle() and rotate() methods six times, I should have a hexagon.
Currently my code looks like this:
public void onDrawFrame(GL10 unused)
{
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); //start by clearing the screen for each frame
GLES20.glUseProgram(mPerVertexProgramHandle); //tell OpenGL to use the shader program we've compiled
//Get pointers to the program's variables. Instance variables so we can break apart code
mMVPMatrixHandle = GLES20.glGetUniformLocation(mPerVertexProgramHandle, "uMVPMatrix");
mPositionHandle = GLES20.glGetAttribLocation(mPerVertexProgramHandle, "aPosition");
mColorHandle = GLES20.glGetAttribLocation(mPerVertexProgramHandle, "aColor");
//Prepare the model matrix!
Matrix.setIdentityM(mModelMatrix, 0); //start modelMatrix as identity (no transformations)
Matrix.translateM(mModelMatrix, 0, 0.0f, -0.577350269f, 0.0f); //shift the triangle down the y axis by -0.577350269f so that its top point is at 0,0,0
drawTriangle(mModelMatrix); //draw the triangle with the given model matrix
Matrix.rotateM(mModelMatrix, 0, 60f, 0.0f, 0.0f, 1.0f);
drawTriangle(mModelMatrix);
}
Here's my problem: it appears my triangle isn't rotating around (0,0,0), but instead it rotates around the triangle's center (as shown in this picture: http://i.imgur.com/oiLFSCE.png).
Is it possible for to rotate triangle around (0,0,0), where its vertex is located?
Are you really be sure that your constant -0.577350269f is the correct value for the triangle center?
Also your code looks unfinish (You use an mvp handle but never use it in the code), could you provide more information?
As for OpenGL ES 2 I have understood that there no longer are any Matrices (matrix stack) in it. So I have to create my own matrices.
What I want to do is just draw some simple 2D graphics, like a couple of rectangles.
Lots of code I find use OpenGL ES 1 or older OpenGL where there still was a matrix stack, so I can't use it directly in 2.0.
I believe I want code that does something like this
public void onSurfaceCreated(GL10 unused, EGLConfig eglConfig) {
// Set the background frame color
GLES20.glClearColor(0.1f, 0.3f, 0.5f, 1.0f);
// Set 2D drawing mode
GLES20.glViewport(0, 0, windowWidth, windowHeight);
GLES20.glMatrixMode(GL_PROJECTION);
GLES20.glLoadIdentity();
GLES20.glOrtho(0, windowWidth, windowHeight, 0, -1, 1);
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
}
but there are no longer any methods glMatrixMode, glLoadIdentity, glOrtho.
How would I translate this into OpenGL ES 2 to set it up for 2D drawing? I believe I can use the Matrix class procvided by android, but I am not sure how.
Basically, you don't "set" any matrices with OpenGL ES 2.0 (as you setup other things, like the viewport, disable GL_DEPTH_TEST, etc). Instead, you create and manage the matrices yourself, passing them to your shaders on each frame render.
You can just create an orthographic projection matrix, then pass it to your shader as a uniform (eg: glUniformMatrix4fv).
I cannot comment on exactly how to do that with Android, but if you have a Matrix class, it should have functions to create an orthographic projection matrix. Then you would just pass a pointer to the data (ie: the 16 floats - 4x4 matrix) to glUniformMatrix4fv before calling glDrawArrays/glDrawElements/etc.
So, your above setup function would be much smaller..
public void onSurfaceCreated(GL10 unused, EGLConfig eglConfig) {
// Set the background frame color
GLES20.glClearColor(0.1f, 0.3f, 0.5f, 1.0f);
// Set 2D drawing mode
GLES20.glViewport(0, 0, windowWidth, windowHeight);
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
}
But your render functions would look different (you could still create your ortho projection matrix above... just making sure to update it if necessary.. ie: screen resizing/moving/etc).
This page covers it pretty well for Android:
http://www.learnopengles.com/android-lesson-one-getting-started/
I've been following the tutorials over at http://www3.ntu.edu.sg/home/ehchua/programming/android/Android_3D.html and I've encountered a problem.
I've managed to get both of the following examples to work:
2.7 Example 5: 3D Shapes - Rotating Color Cube and Pyramid (Nehe Lesson 5: 3D Shapes)
Example 2: Cube2.java
2.8 Example 6: Texture (Nehe Lesson 6: Texture)
But when I try to draw both a coloured cube and a textured cube I get the following:
http://i.imgur.com/Smbsa.png
(First part of the image)
The coloured cube is invisible but clips the texture cube and the texture cube's textures are coloured by the last colour (yellow) of the coloured cube.
I basically just draw both of the cubes with:
// ----- Render the Color Cube -----
gl.glLoadIdentity(); // Reset the model-view matrix
gl.glTranslatef(0.0f, 0.0f, -6.0f); // Translate right and into the screen
gl.glScalef(0.5f, 0.5f, 0.5f); // Scale down (NEW)
gl.glRotatef(angleCube, 1.0f, 1.0f, 0.0f); // rotate about the axis (1,1,1) (NEW)
cube.draw(gl); // Draw the cube (NEW)
// Update the rotational angle after each refresh (NEW)
angleCube += speedCube; // (NEW)
// ----- Render the Texture Cube -----
gl.glLoadIdentity(); // Reset the model-view matrix
gl.glTranslatef(-1.0f, 0.0f, -6.0f); // Translate right and into the screen
gl.glScalef(0.5f, 0.5f, 0.5f); // Scale down (NEW)
gl.glRotatef(angleCube, 1.0f, 1.0f, 0.0f); // rotate about the axis (1,1,1) (NEW)
texturecube.draw(gl); // Draw the cube (NEW)
I tried adding a third so called "Photo cube" from the part "2.9 Example 6a: Photo-Cube".
(Can only post 2 links check the imgur link above)
I added:
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
to the texture cube and noticed that the blue colour "spills" over to the photo cube.
When I add:
gl.glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
the following textures are no longer coloured but this feels like a crude way to remove past colours..
When I remove:
texturecube.loadTexture(gl, context); // Load image into Texture (NEW)
photocube.loadTexture(gl); // Load image into Texture (NEW)
gl.glEnable(GL10.GL_TEXTURE_2D); // Enable texture (NEW)
this happens:
(Can only post 2 links check the imgur link above)
The colour cube is back and all other surfaces are coloured.
My questions:
What am I doing wrong when the coloured cube disappears? (I guess that it should be possible to both use textures and colours at the same time)
Is there a better way to "clear" the colour from previous cubes/objects other than "gl.glColor4f(1.0f, 1.0f, 1.0f, 0.0f);"?
Your question is very detailed which is good, though it would help if you posted the full code sample of your drawing section. It's hard for me to guess what you might be doing that would cause the problem.
Anyway I'll try your two questions:
First: My guess is that you don't disable texturing before drawing your colored cube. But you don't have the full code so I can't say with certainty. Call glDisable(GL_TEXTURE_2D) before rendering your second cube, and reenable it before drawing the next textured cube.
Second: No, that's the correct way to do it (Though you probably want 1,1,1,1, not 1,1,1,0 in case you ever want to do anything with transparency). Alternatively there's a way to do it via pushing the color state onto an OpenGL stack and popping it later, though that's deprecated and shouldn't be used.
actually I'm drawing a cube, I'm checking rotation problems of the cube, but for this I need to draw a point on the 0,0,-1 opengl coordinate of the screen, I'm using perspective projection, MyGLSurfaceView and android 1.5 opengl es 1.x
How can I draw a black or white point on the 0,0,-1 opengl coordinate of the screen?
If you want to be able to draw directly in window space then the easiest thing would be to load modelview and projection temporarily with the identity matrix and draw a GL_POINT with the location that you need. So that'd be something like:
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// draw the point here; specifics depending on whether you
// favour VBOs, VBAs, etc
// e.g. (assuming you don't have any client state enabled
// on entry and don't care about leaving the vertex array
// enabled on exit)
GLfloat vertexLocation[] = {0.0f, 0.0f, -1.0f};
glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertexLocation);
glDrawArrays(GL_POINTS, 0, 1);
// end of example to plot a GL_POINT
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
// and possibly restore yourself to some other matrix mode
// if, atypically, the rest of your code doesn't assume modelview
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.