Perspective drawing in OpenGL using glFrustum - opengl

I'm trying to draw a cube in cabinet perspective. This is the cube in glOrtho:
Other faces:
Back - cyan, Left - magenta, down - blue
This is what I get
This is what I want to achieve
My code:
//init function
glClearColor(1, 1, 1, 1);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-10, 10, -10, 10, 4,6);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(0,0,-lat);//it doesn't show in the window without this.
DisplayAxis();
DisplayObject();
break;
//object initalization. I use glGenList and glCallList to draw it
void InitObject() {
glNewList(k, GL_COMPILE);
glColor3f(1, 0, 0);
glBegin(GL_QUADS);
glVertex3d(0, lat, lat);
glVertex3d(lat, lat, lat);
glVertex3d(lat, 0, lat);
glVertex3d(0, 0, lat);
glEnd();
glColor3f(1, 1, 0);
glBegin(GL_QUADS);
glVertex3d(lat, 0, 0);
glVertex3d(lat, 0, lat);
glVertex3d(lat, lat, lat);
glVertex3d(lat, lat, 0);
glEnd();
glColor3f(0, 1, 0);
glBegin(GL_QUADS);
glVertex3d(0, lat, lat);
glVertex3d(lat, lat, lat);
glVertex3d(lat, lat, 0);
glVertex3d(0, lat, 0);
glEnd();
glColor3f(0, 0, 1);
glBegin(GL_QUADS);
glVertex3d(0, 0, 0);
glVertex3d(lat, 0, 0);
glVertex3d(lat, 0, lat);
glVertex3d(0, 0, lat);
glEnd();
glColor3f(1, 0, 1);
glBegin(GL_QUADS);
glVertex3d(0, 0, lat);
glVertex3d(0, 0, 0);
glVertex3d(0, lat, 0);
glVertex3d(0, lat, lat);
glEnd();
glColor3f(0, 1, 1);
glBegin(GL_QUADS);
glVertex3d(0, lat, 0);
glVertex3d(lat, lat, 0);
glVertex3d(lat, 0, 0);
glVertex3d(0, 0, 0);
glEnd();
glEndList();
}
What am I doing wrong here? I tried some rotations on the object but I get some skewed results(I can post more images if needed).

The object is clipped by the near plane of the Viewing frustum.
Not you have to translate the object along the negativ z axis, to move the object in between the near and far plane of the viewing frustum:
glTranslated(0,0,-lat);//it doesn't show in the window without this.
Since the view space z axis points out out the viewport, you have to shift the object along the negative z axis.
The distance to the near plane is 4 and the distance to the far plane is 6:
glFrustum(-10, 10, -10, 10, 4,6);
The distance to the front of the cube is less than 4, thus it is clipped by the near plane.
Change the frustum, and keep the cube completely in the frustum to solve the issue:
glFrustum(-10, 10, -10, 10, 4,6);
glFrustum(-2.5, 2.5, -2.5, 2.5, 1, 10);
glTranslated(0,0,-lat);
glTranslated(0, 0, -6);
For a good perspective and look at the scene, use a projection matrix (frustum) with a smaller field of view:
glFrustum(-1, 1, -1, 1, 1, 12);
Alternatively you can define the frustum by gluPerspective and set the field of view angle in degrees:
gluPerspective(90, 1, 1, 12);
The view matrix defines the position and viewing direction of the observer (viewer) within the scene.
If you want a different look at the scene the you have to rotate the scene (glRotate):
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(0, 0, -8);
glRotatef(30, 1, 0, 0);
glRotatef(-45, 0, 1, 0);
Alternatively the look at the scene (view matrix) can be defined by gluLookAt . Arguments 1-3 are the position of the observer (x,y, z components of eye or camera position). The Arguments 4-6 are the target point (where the observer looks at). The arguments 7-9 are the upwards vector.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5, 5, 7, 0, 0, 0, 0, 1, 0);

Related

Stroke is not drawn correctly (OpenGL)

I am trying to make a stroke for chests in a minecraft game and I almost succeeded, but for some reason it is not drawn correctly.
ScreenShot
The screenshot shows how part of the line has disappeared. This happens when the line is on the chest. Maybe it's a texture mapping or something else. In this case, the stroke is drawn through the blocks normally.
ScreenShot2
Also, when the chest is in the dark, the outline becomes dark, although I turned off GL_LIGHTING
ScreenShot3
Here is a piece of code with which I draw the stroke
glPushAttrib(GL_ALL_ATTRIB_BITS);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glLineWidth(2);
glColor3ub(255, 255, 255);
glBegin(GL_LINES);
glVertex3f(1, 0, 0);
glVertex3f(1, -1, 0);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, -1, 0);
glVertex3f(0, -1, 0);
glVertex3f(1, -1, 0);
glVertex3f(1, -1, 0);
glVertex3f(1, -1, -1);
glVertex3f(1, -1, -1);
glVertex3f(1, 0, -1);
glVertex3f(1, -1, -1);
glVertex3f(0, -1, -1);
glVertex3f(0, -1, -1);
glVertex3f(0, -1, 0);
glVertex3f(0, -1, -1);
glVertex3f(0, 0, -1);
glVertex3f(0, 0, -1);
glVertex3f(1, 0, -1);
glVertex3f(0, 0, -1);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, -1);
glVertex3f(1, 0, 0);
glEnd();
glPopAttrib();
What can be wrong?
From your screenshots it seems that the order of rendering is the following:
terrain
outline
chest
Now since you have disabled GL_DEPTH_TEST in step 2, the fragments (pixels) that turned white (those on which the outline is drawn), won't get their depth information updated. That's because disabling GL_DEPTH_TEST not only disables depth testing, but also disables updating the depth information of fragments.
So when you finally draw the chest (with depth testing re-enabled), it will be drawn over all the fragments whose depth value indicates that they are behind it. That means, also over the fragments where the outline is drawn.
The black color of the outline on the third screenshot may be caused by your call to glBindTexture(GL_TEXTURE_2D, 0);. But that's just a hunch.

When applying glScalef() to a polygon, it changes its position, how to get rid of it?

Is a simple polygon.
glPushMatrix();
glBegin(GL_POLYGON);
glColor3f(1, 1, 1);
glVertex3f(-150, 150, 0);
glVertex3f(150, 150, 0);
glVertex3f(150, 450, 0);
glVertex3f(-150, 450, 0);
glEnd();
glPopMatrix();
When applying glScalef() to a polygon, it changes its position, how to get rid of it? I mean... If he was at the same height, he would change it.
glScalef() doesn't scale a polygon, it scales an entire coordinate system. Everything will be scaled around the point with coordinates (0, 0, 0), not around the center of the polygon.
If you want to scale around some other point (x, y, z), you can use the following code:
glTranslatef(x, y, z);
glScalef(your, scale, here);
glTranslatef(-x, -y, -z);
Though a more robust solution would be to make your polygon's coordinates relative to its center, in which case you don't need the second glTranslatef() anymore. In your specific example:
glPushMatrix();
glTranslatef(0, 300, 0);
glScalef(your, scale, here);
glBegin(GL_POLYGON);
glColor3f(1, 1, 1);
glVertex3f(-150, -150, 0);
glVertex3f(150, -150, 0);
glVertex3f(150, 150, 0);
glVertex3f(-150, 150, 0);
glEnd();
glPopMatrix();

Apply Shader to a surface (texture)

I'm working on a little OpenTK based 2D graphics library and I'm trying to apply a shader to a Surface object:
public void ApplyTo(Surface surface)
{
using (Surface pong = new Surface())
{
pong.Create(surface.Width, surface.Height);
pong.Clear(0, 0, 0, 0);
GL.Viewport(0, 0, surface.Width, surface.Height);
GL.LoadIdentity();
GL.Ortho(0, 1.0, 1.0, 0.0, 0.0, 4.0);
GL.UseProgram(0);
surface.BindTexture();
pong.BindFramebuffer();
GL.Begin(PrimitiveType.Quads);
GL.TexCoord2(0.0f, 1.0f);
GL.Vertex3(0, 0, 0);
GL.TexCoord2(0.0f, 0.0f);
GL.Vertex3(0, 1, 0);
GL.TexCoord2(1.0f, 0.0f);
GL.Vertex3(1, 1, 0);
GL.TexCoord2(1.0f, 1.0f);
GL.Vertex3(1, 0, 0);
GL.End();
Use(); // calls GL.UseProgram()
pong.BindTexture();
surface.BindFramebuffer();
GL.Begin(PrimitiveType.Quads);
GL.TexCoord2(0.0f, 1.0f);
GL.Vertex3(0, 0, 0);
GL.TexCoord2(0.0f, 0.0f);
GL.Vertex3(0, 1, 0);
GL.TexCoord2(1.0f, 0.0f);
GL.Vertex3(1, 1, 0);
GL.TexCoord2(1.0f, 1.0f);
GL.Vertex3(1, 0, 0);
GL.End();
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
}
}
This somehow clears the surface instead of applying the shader. My suspicion is that I'm doing something wrong with the viewport / projection, but what? I hope the provided code is sufficient.
For full screen rendering on a quad, I use that projection:
OpenTK.Matrix4 ortho = OpenTK.Matrix4.CreateOrthographicOffCenter(-1, 1, -1, 1, 1, -1);
Theres a division by 0 somewhere when your vertices are exactly on the near plane, you may also move a bit further on the z axis.

Rotate Triangle In OpenGL

I'm trying to rotate a triangle around it's center point. I'm aware that OpenGL rotates about the origin so I need to translate the middle point to the origin, then rotate, and translate back. I've commented out this last line to ensure that it at least rotates about its center at the origin. It does not. It appears to be rotating about its old origin despite the translation... Note that ccc4 and ccp generate floats. Here's my code:
ccColor4B colors[] = {
ccc4(255, 0, 0, 255),
ccc4(0, 255, 0, 255),
ccc4(0, 0, 255, 255)
};
CGPoint vertices[] = {
ccp(0,0),
ccp(50,100),
ccp(100,0),
};
CGPoint middle[] = {ccp(50,50)};
CGPoint origin[] = {ccp(0,0)};
// Rotate the triangle
glPushMatrix();
glTranslatef(-50, -50, 0);
glRotatef(45, 0, 0, 1.0);
// glTranslatef(50, 50, 0);
// Draw the triangle
glLineWidth(2);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
glColor4ub(0, 0, 255, 255);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
// Revert rotation, we only want triangle to rotate
glPopMatrix();
// Draw the points
glDisableClientState(GL_COLOR_ARRAY);
glPointSize(5);
glColor4ub(255, 255, 255, 255);
glVertexPointer(2, GL_FLOAT, 0, middle);
glDrawArrays(GL_POINTS, 0, 1);
glPointSize(5);
glColor4ub(0, 255, 0, 255);
glVertexPointer(2, GL_FLOAT, 0, origin);
glDrawArrays(GL_POINTS, 0, 1);
glEnableClientState(GL_COLOR_ARRAY);
// End points
Here's the output:
You need to think of transforms as applying in reverse relative to the order in which you call them.
Actually, it's easier to think in terms of transforming the local coordinate system (LCS), not the object, which allows you to mentally apply transforms in the order they're called. To rotate about the center, translate the LCS to the center, rotate, then translate it back out again:
glTranslatef(50, 50, 0);
glRotatef(45, 0, 0, 1);
glTranslatef(-50, -50, 0);

Cube drawing opengl, but a confused image of cube is drawn

Hi
I am trying to draw a cube of size 5*5*5 with six diffrent face colors. How ever,I can not see all the faces colored diffrently, all I see is a cube, with confusing colors format.
Some faces are clearly visible, while top face , parallel to zx plane is not visible.
Thanks in advance
void init(void)
{
glClearColor(0,0,0,0);
glShadeModel(GL_FLAT);
}
void DrawCube(void)
{
glLoadIdentity();
gluLookAt(10, 10, 10, 0, 0, 0, 0, 1, 0);
glBegin(GL_QUADS);
//face in xy plane
glColor3f(0.82, 0.41, 0.12);//this the color with which complete cube is drawn.
glVertex3f(0,0 ,0 );
glVertex3f(5, 0, 0);
glVertex3f(5, 5, 0);
glVertex3f(0, 5, 0);
//face in yz plane
glColor3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 5);
glVertex3f(0, 5, 0);
glVertex3f(0, 5, 5);
//face in zx plance
glColor3f(0, 1, 0);
glVertex3f(0, 0, 0 );
glVertex3f(0, 0, 5);
glVertex3f(5, 0, 5);
glVertex3f(5, 0, 0);
//|| to xy plane.
glColor3f(0, 0, 1);
glVertex3f(0, 0, 5);
glVertex3f(5, 0, 5);
glVertex3f(5, 5, 5);
glVertex3f(0, 5, 5);
//|| to yz plane
glColor3f(0.73, 0.58, 0.58);
glVertex3f(0,0 ,5 );
glVertex3f(5, 0, 5);
glVertex3f(5, 5, 5);
glVertex3f(0, 5, 5);
//|| to zx plane //this face is not visible. I am not understanding why.
glVertex3f(0.58, 0, 0.82);
glVertex3f(0, 5, 0 );
glVertex3f(0, 5, 5);
glVertex3f(5, 5, 5);
glVertex3f(5, 5, 0);
glEnd();
glFlush();
}
void reshape(int w,int h){
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1, 1, -1, 1, 1.5, 20);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv){
glutInit(&argc, argv);//we initizlilze the glut. functions
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(DrawCube);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
//|| to zx plane //this face is not visible. I am not understanding why.
glVertex3f(0.58, 0, 0.82);
You want glColor3f. I'm guessing this is a typo.
Two unrelated things:
Your || to xy plane quad is the same as your || to yz plane quad.
You aren't clearing the color buffer before drawing. You probably want glClear(GL_COLOR_BUFFER_BIT) at the start of DrawCube