I am trying to create and display a 3D square but for some reason when I render it, parts of it are missing:
void DrawCube::drawCubes(int amount){
glBegin(GL_POLYGON);
glVertex3f( 1.0, -1.0, 1);
glVertex3f( 1.0, -1.0, -1);
glVertex3f( 1.0, 1.0, -1);
glVertex3f( 1.0, 1.0, 1);
glEnd();
glBegin(GL_POLYGON);
glVertex3f(-1.0, -1.0, -1);
glVertex3f( 1.0, -1.0, -1);
glVertex3f( 1.0, 1.0, -1);
glVertex3f(-1.0, 1.0, -1);
glEnd();
glBegin(GL_POLYGON);
glVertex3f(-1.0, -1.0, 1);
glVertex3f( 1.0, -1.0, 1);
glVertex3f( 1.0, 1.0, 1);
glVertex3f(-1.0, 1.0, 1);
glEnd();
glBegin(GL_POLYGON);
glVertex3f( -1.0, -1.0, 1);
glVertex3f( -1.0, -1.0, -1);
glVertex3f( -1.0, 1.0, -1);
glVertex3f( -1.0, 1.0, 1);
glEnd();
}
}
I'm not looking for answers that just give me the code, but rather an explanation as to what causes this thanks.
The cube seems to be clipped by the far plane of the projection. Increase the distance to the far plane, when you set the projection matrix by glOrtho.
Note, the projection matrix defines a view volume (see 3D projection). All the geometry which is out of the viewing volume is clipped.
Related
I am trying to draw something like this image of the target output using OpenGL. I am using freeglut. I could draw three polygons, but I don't know how to give the three polygons right positioning. Below I attached the target output and my correct output.
The target output
My output
#include <GL/glut.h>
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW);
}
void drawSquare(void)
{
glBegin(GL_POLYGON);
glVertex2f(0.0f, -1.0f);
glVertex2f(2.0f, 0.0f);
glVertex2f(0.0f, 1.0f);
glVertex2f(-2.0f, 0.0f);
glEnd();
}
void myDraw1(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glColor3f(1.0, 0.0, 0.0);
drawSquare();
glTranslatef(2.0, 3.0, 0.0);
glRotatef(30, 0.0, 0.0, 1.0);
glColor3f(0.0, 1.0, 0.0);
drawSquare();
glLoadIdentity();
glTranslatef(-2.0, -3.0, 0.0);
glRotatef(-30, 0.0, 0.0, 1.0);
glColor3f(0.0, 0.0, 1.0);
drawSquare();
glFlush();
}
void myDraw2(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glColor3f(1.0, 0.0, 0.0);
drawSquare();
glPushMatrix();
glTranslatef(2.0, 3.0, 0.0);
glRotatef(30, 0.0, 0.0, 1.0);
glColor3f(0.0, 1.0, 0.0);
drawSquare();
glPopMatrix();
glTranslatef(-2.0, -3.0, 0.0);
glRotatef(-30, 0.0, 0.0, 1.0);
glColor3f(0.0, 0.0, 1.0);
drawSquare();
glFlush();
}
void main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(0, 0);
glutInitWindowSize(600, 600);
glutCreateWindow("Rotate");
init();
glutDisplayFunc(myDraw1);
glutMainLoop();
}
The angle between the polygons is 120°. The center of the polygons is (0, 0). You have to rotate around the point (-2, 0). Translate the polygon in that way that that (-2, 0) is moved to (0, 0) and rotate the polygon:
glRotatef(120.0, 0.0, 0.0, 1.0);
glTranslatef(2.0, 0.0, 0.0);
Note, operations like glTranslatef and glRotatef, specify a matrix and multiply the current matrix by the new specified matrix. Use glPushMatrix/glPopMatrix to save and restore the matrix (push on and pop from matrix stack).
e.g:
void myDraw1(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glColor3f(1.0, 0.0, 0.0);
glPushMatrix();
glRotatef(90.0, 0.0, 0.0, 1.0);
glTranslatef(2.0, 0.0, 0.0);
drawSquare();
glPopMatrix();
glColor3f(0.0, 1.0, 0.0);
glPushMatrix();
glRotatef(210.0, 0.0, 0.0, 1.0);
glTranslatef(2.0, 0.0, 0.0);
drawSquare();
glPopMatrix();
glColor3f(0.0, 0.0, 1.0);
glPushMatrix();
glRotatef(330.0, 0.0, 0.0, 1.0);
glTranslatef(2.0, 0.0, 0.0);
drawSquare();
glPopMatrix();
glFlush();
}
I am trying to apply a texture to 1 face of a cube, but the problem I have is the cube is in the z direction as well.
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Tex);
glBegin(GL_POLYGON);
glTexCoord2f( 1.0, 1.0); glVertex3f( 1.0, 1.0, 1);
glTexCoord2f( 1.0, -1.0); glVertex3f( 1.0, -1.0, 1);
glTexCoord2f( 1.0, -1.0); glVertex3f( 1.0, -1.0, -1);
glTexCoord2f( 1.0, 1.0); glVertex3f( 1.0, 1.0, -1);
glEnd();
glDisable(GL_TEXTURE_2D);
Obviously by doing it this way I end up with repeated texture vertices (1,1) and (1,-1) because they don't include the z axis. How can I resolve this issue?
It is not necessary that the texture coordinates are associated to the x and y component of the vertex coordinates or even have to be the same. The texture coordinates are completely independent.
You have to define how the 2 dimensional texture is wrapped on a surface in 3 dimensional space. For each side of the cube you've to define individual texture coordinates.
Chang the texture coordinates. e.g.:
glBegin(GL_POLYGON);
glTexCoord2f( 1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f( 1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
glTexCoord2f( 0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f( 0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
glEnd();
I'm facing a problem in my opengl code
I'm trying to build a house, and rotate it 360°, for simplicity let's assume the house has the front wall with window and dor, and a back wall.
I'm using DEPTH_BUFFER not to see the back wall when viewing the front wall, and the other way around, but when I rotate the house the door and window start to shake and get distorced.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glLoadIdentity();
gluLookAt(0.0, 0.0, 40.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(angle, 0.0, 1.0, 0.0);
glEnable(GL_DEPTH_TEST);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(8.0, 3.0, 0.0);
glVertex3f(8.0, -10.0, 0.0);
glVertex3f(1.0, -10.0, 0.0);
glVertex3f(1.0, 3.0, 0.0);
glEnd();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(-9.0, -4.0, 0.0);
glVertex3f(-9.0, 3.0, 0.0);
glVertex3f(-2.0, 3.0, 0.0);
glVertex3f(-2.0, -4.0, 0.0);
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(10.0, -10.0, -20.0);
glVertex3f(-10.0, -10.0, -20.0);
glVertex3f(-10.0, 10.0, -20.0);
glVertex3f(10.0, 10.0, -20.0);
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(10.0, -10.0, 0.0);
glVertex3f(10.0, 10.0, 0.0);
glVertex3f(-10.0, 10.0, 0.0);
glVertex3f(-10.0, -10.0, 0.0);
glEnd();
glDisable(GL_DEPTH_TEST);
glutSwapBuffers();
The issue is called Z-fighting. This is caused, because depth of the "door", "window" and "wall" are equal. The vertiex coordinates are transformed by the model view matrix and projection matrix and interpolated for each fragment which is covered by the polygon. This results in inaccuracies of the final z coordinate (depth).
Enable the polygon fill offset (glPolygonOffset) by before drawing the walls, to solve the issue:
glEnable(GL_DEPTH_TEST);
glDisable( GL_POLYGON_OFFSET_FILL );
// draw door and window
// ...
glEnable( GL_POLYGON_OFFSET_FILL );
glPolygonOffset( 1, 1 );
// draw walls
// ...
Polygon fill offset manipulates the depth of a fragment by a minimum amount. This causes that the depth of the "walls" is different to the depth of the "window" and "door", even after the transformation by the model view and projection matrix.
Since an offset is added to the depth of the "wall", the "wall" is always behind the window and the door, independent of the point of view.
I use Lazarus (under Linux) Please anybody help me. I have problem. I have install LasOpenGLContext. There is "OpenGL Controll" at components panel. And I wish to draw a simple cube. But I can not do it. I get raised an exception class 'External:SIGSEGV' What's wrong? Please, if any ideas.
unit Ex1;
{$mode objfpc}{$H+}
{$LinkLib GL}
interface
uses
Classes, SysUtils, FileUtil, OpenGLContext, Forms, Controls, Graphics, gl, glu, Glut,
Dialogs, ExtCtrls, LazOpenGLContext, LCLType;
type
{ Tfrm }
Tfrm = class(TForm)
OpenGLControl1: TOpenGLControl;
Timer: TTimer;
procedure FormCreate(Sender: TObject);
procedure TimerTimer(Sender: TObject);
private
{ private declarations }
public
cube_rotation: GLFloat;
Speed: Double;
{ public declarations }
end;
var
frm: Tfrm;
implementation
{$R *.lfm}
{ Tfrm }
procedure Tfrm.FormCreate(Sender: TObject);
begin
glClearColor(1.0, 1.0, 1.0, 1.0); // here brakepoint raised an exception class 'External:SIGSEGV'
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, double(width) / height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0,-6.0);
glRotatef(cube_rotation, 1.0, 1.0, 1.0);
glBegin(GL_QUADS);
glColor3f(0.0,1.0,0.0);
glVertex3f( 1.0, 1.0,-1.0);
glVertex3f(-1.0, 1.0,-1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f( 1.0, 1.0, 1.0);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,0.5,0.0);
glVertex3f( 1.0,-1.0, 1.0);
glVertex3f(-1.0,-1.0, 1.0);
glVertex3f(-1.0,-1.0,-1.0);
glVertex3f( 1.0,-1.0,-1.0);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,0.0,0.0);
glVertex3f( 1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(-1.0,-1.0, 1.0);
glVertex3f( 1.0,-1.0, 1.0);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,1.0,0.0);
glVertex3f( 1.0,-1.0,-1.0);
glVertex3f(-1.0,-1.0,-1.0);
glVertex3f(-1.0, 1.0,-1.0);
glVertex3f( 1.0, 1.0,-1.0);
glEnd();
glBegin(GL_QUADS);
glColor3f(0.0,0.0,1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0,-1.0);
glVertex3f(-1.0,-1.0,-1.0);
glVertex3f(-1.0,-1.0, 1.0);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0,0.0,1.0);
glVertex3f( 1.0, 1.0,-1.0);
glVertex3f( 1.0, 1.0, 1.0);
glVertex3f( 1.0,-1.0, 1.0);
glVertex3f( 1.0,-1.0,-1.0);
glEnd();
cube_rotation += 5.15 * Speed;
OpenGLControl1.SwapBuffers;
end;
procedure Tfrm.TimerTimer(Sender: TObject);
begin
end;
end.
You seem to be missing the OpenGL context creation. Without it every OpenGL call can crash your program. I haven't used Lazarus, but according to their website the code to create a context could be the following:
procedure TForm1.FormCreate(Sender: TObject);
begin
GLbox:= TOpenGLControl.Create(Form1);
GLbox.AutoResizeViewport:= true;
GLBox.Parent := self;
GLBox.MultiSampling:= 4;
GLBox.Align := alClient;
GLBox.OnPaint := #GLboxPaint; //for "mode delphi" this would be "GLBox.OnPaint := GLboxPaint"
GLBox.invalidate;
end;
So I am working on a homework assignment and I have managed to create my skybox and it looks correct, the only problem is that my camera is outside the skybox.
I tried the command gluLookAt thinking maybe that would focus me into the box, but it didn't work. Here's the code that I have now. If anyone could let me know what I'm doing wrong it would be greatly appreciated:
gluLookAt(
0,0,0,
0,0,0
0,1,0);
glPushMatrix();
//load identity matrix
glLoadIdentity();
//update x, y and z rotation directions
glRotatef(currentRotation[1], 1.0, 0.0, 0.0); //x rotation
glRotatef(currentRotation[2], 0.0, 1.0, 0.0); //y rotation
glRotatef(currentRotation[3], 0.0, 0.0, 1.0); //z rotation
/*
//update scale of display
glScalef(currentScaling[1],
currentScaling[2],
currentScaling[3]);*/
//translate the image
glTranslatef(currentTranslation[1],
currentTranslation[2],
currentTranslation[3]);
/* Clear buffers */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D); // Enable texturing from now on
//front quadrant
glBindTexture(GL_TEXTURE_2D,frontTextureId); // select which texture to use
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 1.0);
glTexCoord2f(1.0 ,0.0); glVertex3f(-0.5, 0.5, 0.5);
glTexCoord2f(0.0 ,0.0); glVertex3f(0.5, 0.5, 0.5);
glTexCoord2f(0.0 ,1.0); glVertex3f(0.5, 0.5, -0.5);
glTexCoord2f(1.0 ,1.0); glVertex3f(-0.5, 0.5, -0.5);
glEnd();
//left quadrant
glBindTexture(GL_TEXTURE_2D, leftTextureId);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, 0.5, -0.5);
glTexCoord2f(1.0, 1.0); glVertex3f(-0.5, -0.5, -0.5);
glTexCoord2f(1.0, 0.0); glVertex3f(-0.5, -0.5, 0.5);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, 0.5, 0.5);
glEnd();
//back quadrant
glBindTexture(GL_TEXTURE_2D, backTextureId);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(0.5, -0.5, -0.5);
glTexCoord2f(1.0, 0.0); glVertex3f(0.5, -0.5, 0.5);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, -0.5, 0.5);
glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, -0.5, -0.5);
glEnd();
//right quadrant
glBindTexture(GL_TEXTURE_2D, rightTextureId);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(0.5, 0.5, -0.5);
glTexCoord2f(1.0, 0.0); glVertex3f(0.5, 0.5, 0.5);
glTexCoord2f(0.0, 0.0); glVertex3f(0.5, -0.5, 0.5);
glTexCoord2f(0.0, 1.0); glVertex3f(0.5, -0.5, -0.5);
glEnd();
//up quadrant
glBindTexture(GL_TEXTURE_2D, upTextureId);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, -0.5, 0.5);
glTexCoord2f(1.0, 0.0); glVertex3f(-0.5, 0.5, 0.5);
glTexCoord2f(1.0, 1.0); glVertex3f(0.5, 0.5, 0.5);
glTexCoord2f(0.0, 1.0); glVertex3f(0.5, -0.5, 0.5);
glEnd();
//down quadrant
glBindTexture(GL_TEXTURE_2D, downTextureId);
glBegin(GL_QUADS);
glColor3f(1.0, 1.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, -0.5, -0.5);
glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, 0.5, -0.5);
glTexCoord2f(1.0, 1.0); glVertex3f(0.5, 0.5, -0.5);
glTexCoord2f(1.0, 0.0); glVertex3f(0.5, -0.5, -0.5);
glEnd();
Thank you for any help you can provide!
I think your problem is in the glulookat
try with this values
gluLookAt(0.0, 0.0 , 2.0 ,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
Few problems at a glance: gluLookAt arguments: first three are camera position, next three are camera target - should not be the same, camera must have valid direction vector. Next, your skybox is only 1.0 unit size - make it bigger. Use a constant instead of 0.5 everywhere, that way you can control it in one place.
Well you do have a glTranslate() call in there, so unless you're passing it zeros, that's probably why you're not in the box.