i heed help with openGL and rotations. This is My code:
#include <math.h>
#include <GL/glut.h>
float transZ=50;
float rotateA=0;
float rotateAspeed=0.0;
void cube (float dimX, float dimY, float dimZ)
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(0,dimY/2,0);
glScalef(dimX/2, dimY/2, dimZ/2);
glBegin(GL_QUADS);
glColor3f(0.0, 1.0, 0.0); // Color Green - TOP
glVertex3f(1.0, 1.0, 1.0); // TOP-RIGHT-NEAR
glVertex3f(-1.0, 1.0, 1.0); // TOP-LEFT-NEAR
glVertex3f(-1.0, 1.0, -1.0); //TOP-LEFT-FAR
glVertex3f(1.0, 1.0, -1.0); // TOP-RIGHT-FAR
glColor3f(1.0, 0.0, 0.0); // Color RED - Bottom
glVertex3f(1.0, -1.0, 1.0); //BOTTOM-RIGHT-NEAR
glVertex3f(-1.0, -1.0, 1.0); //BOTTOM-LEFT-NEAR
glVertex3f(-1.0, -1.0, -1.0); //BOTTOM-LEFT-FAR
glVertex3f(1.0, -1.0, -1.0); //BOTTOM-RIGHT-FAR
glColor3f(1.0, 1.0, 0.0); // Color Yellow - Back
glVertex3f(1.0, 1.0, -1.0); //TOP-RIGHT-FAR
glVertex3f(-1.0, 1.0, -1.0); //TOP-LEFT-FAR
glVertex3f(-1.0, -1.0, -1.0); //BOTTOM-LEFT-FAR
glVertex3f(1.0, -1.0, -1.0); //BOTTOM-RIGHT-FAR
glColor3f(0.0, 0.0, 1.0); //Color Blue - RIGHT
glVertex3f(1.0, 1.0, 1.0); //TOP-FRONT-NEAR
glVertex3f(1.0, 1.0, -1.0); //TOP-BACK-FAR
glVertex3f(1.0, -1.0, -1.0); //BOTTOM-BACK-FAR
glVertex3f(1.0, -1.0, 1.0); //BOTTOM-FRONT-NEAR
glColor3f(1.0, 0.5, 0.0); //Color Orange - Left
glVertex3f(-1.0, 1.0, 1.0); //TOP-FRONT-NEAR
glVertex3f(-1.0, 1.0, -1.0); //TOP-BACK-FAR
glVertex3f(-1.0, -1.0, -1.0);//BOTTOM-BACK-FAR
glVertex3f(-1.0, -1.0, 1.0); //BOTTOM-FRONT-NEAR
glEnd();
glPopMatrix();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(transZ*cos(rotateA),10,transZ*sin(rotateA), 0,10,0, 0,1,0);
cube(30,30,30);
glFlush();
glutSwapBuffers();
}
void init (void)
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1, 1, -1, 1, 1, 1000);
glEnable(GL_DEPTH_TEST);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
case 'S':
transZ+=1.0f;
glutPostRedisplay();
break;
case 'W':
transZ-=1.0f;
if (transZ<0) transZ=0;
glutPostRedisplay();
break;
case 's':
transZ+=0.5f;
glutPostRedisplay();
break;
case 'w':
transZ-=0.5f;
if (transZ<0) transZ=0;
glutPostRedisplay();
break;
case 'A':
rotateAspeed+=0.001f;
glutPostRedisplay();
break;
case 'a':
rotateAspeed+=0.001f;
glutPostRedisplay();
break;
case 'D':
rotateAspeed-=0.001f;
glutPostRedisplay();
break;
case 'd':
rotateAspeed-=0.001f;
glutPostRedisplay();
break;
}
}
void idle(void)
{
rotateA=rotateA + rotateAspeed;
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Cube");
init ();
glutDisplayFunc(display);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
When i press A or D the cube is rotated horizontally but i need to make, when i press, for example J the cube to start rotating vertically. Any help on how to do that?
You need to look at glRotate and how transformations are done in openGL. Then parameterize the rotation by three angles, called Euler angles, or use quaternions, or some other suitable rotation representation. From this the transformations will rotate the cube properly, it might look like this:
glPushMatrix()
glRotatef(alpha, 1, 0, 0); //rotate alpha around the x axis
glRotatef(beta, 0, 1, 0); //rotate beta around the y axis
glRotatef(gamma, 0, 0, 1); //rotate gamma around the z axis
//dram my cube
glPopMatrix();
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();
}
Currently creating a small animation of Neptune and its moon's revolving around the sun. With some help I managed to get a background of stars but instead of being white, they're now black. I've tried putting glColor3f(1.0, 1.0, 1.0) inside and outside of the matrix consisting the background and none of it seems to be working. Any solutions?
Background declaration: Display()
Background call: End of Display()
int triton = 0;
int proteus = 0;
int neptune = 0;
int sun = 0;
GLint buf, sbuf;
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
// Kind of Useless rn
glGetIntegerv(GL_SAMPLE_BUFFERS, &buf);
printf("Number of sample Buffers: %d\n", buf);
glGetIntegerv(GL_SAMPLES, &sbuf);
printf("Number of samples: %d\n", sbuf);
printf("Controls: \n A = Orbit Left. \n D = Orbit Right. \n S = Stop. \n (,) = Move Left. \n (.) = Move right.");
glShadeModel(GL_SMOOTH);
// Material Specs
GLfloat mat_specular[] = { 0.8, 0.8, 0.9, 0.1 };
GLfloat mat_shininess[] = { 40.0 };
GLfloat lightDiffuse[] = { 1.0, 1.0, 1.0, 0.8 };
GLfloat lmodel_ambient[] = { 0.1, 0.2, 0.7, 0.0 };
// Light 0 Initialized.
GLfloat light0[] = { 1.0, 1.0, 1.0, 0.9 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
// Spotlight (Sun)
// Mat Specs Implmentations.
glMaterialfv(GL_FRONT, GL_DIFFUSE, lightDiffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
// Light 0 implementation
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0);
glLightfv(GL_LIGHT0, GL_SPECULAR, light0);
// Ambient surrounding light on object.
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
// Antialias 3D Shape (In Progress)
/*glEnable(GL_BLEND);
glEnable(GL_POLYGON_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);*/
// Enable Lighting and Depth
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
void orbit(void)
{
triton = (triton - 2) % 360;
proteus = (proteus - 5) % 360;
neptune = (neptune - 1) % 360;
glutPostRedisplay();
}
void backorbit(void)
{
triton = (triton + 2) % 360;
proteus = (proteus + 5) % 360;
neptune = (neptune + 1) % 360;
glutPostRedisplay();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_COLOR_MATERIAL);
glPushMatrix();
glNewList(1, GL_COMPILE);
glBegin(GL_POINTS);
glColor3f(1.0, 1.0, 1.0);
for (int i = 0; i < 300; i++)
{
for (int j = 0; j < 300; j++)
{
if (((i + j) % 2) == 0)
{
glVertex2f(30 * i, 30 * j);
}
}
}
glEnd();
glEndList();
// Sun
glPushMatrix();
glColor3f(1.0, 0.35, 0.1);
glTranslatef(0.0, 0.0, 0.0);
glutSolidSphere(2.0, 100, 100);
// Neptune
glPushMatrix();
glRotatef((GLfloat)neptune, 0.0, 1.0, 0.0);
glTranslatef(3.0, 0.0, 0.0);
glColor3f(0.1, 0.1, 0.3);
glutSolidSphere(0.3, 100, 100);
// Triton
glPushMatrix();
glColor3f(0.85, 0.7, 0.8);
glRotatef((GLfloat)triton, 1.0, 1.0, 1.0);
glTranslatef(1.0, 0.0, 0.0);
glutSolidSphere(0.05, 100, 100);
glPopMatrix(); // Ends Triton
// Proteus
glPushMatrix();
glColor3f(1.0, 1.0, 1.0);
glRotatef((GLfloat)proteus, 0.0, 1.0, 0.0);
glTranslatef(1.0, 0.0, 0.0);
glutSolidSphere(0.02, 100, 100);
glPopMatrix(); // Ends Proteus
glPopMatrix(); // Ends Neptune
glPopMatrix(); // Ends Sun
glEnable(GL_MULTISAMPLE);
// Stars
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, 1000, 0, 1000);
glColor3f(1.0, 1.0, 1.0);
glCallList(1);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopMatrix();
glDisable(GL_COLOR_MATERIAL);
glPopMatrix(); // Ends Solar System
glFlush();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
// Triton + Proteus Orbit.
case 'a':
glutIdleFunc(orbit);
break;
case 'd':
glutIdleFunc(backorbit);
break;
case 's':
glutIdleFunc(NULL);
break;
case ',':
glTranslatef(-0.3, 0.0, 0.0);
glutPostRedisplay();
break;
case '.':
glTranslatef(0.3, 0.0, 0.0);
glutPostRedisplay();
break;
case 27:
exit(0);
break;
default:
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB | GLUT_MULTISAMPLE);
glutInitWindowSize(1000, 1000);
glutInitWindowPosition(100, 100);
glutCreateWindow("Neptune and Space");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
I'm trying to illustrate orbits of Triton and Proteus around Neptune with a background of stars. I decided to sketch a template background by multisampling an array of white dots ( stars ) as the background. Could someone explain why my array isn't displaying?
*Background is called in Display() created in Init().
Full Code here:
int triton = 0;
int proteus = 0;
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
// Material Specs
GLfloat mat_specular[] = { 0.8, 0.8, 0.9, 0.1 };
GLfloat mat_shininess[] = { 40.0 };
GLfloat lightDiffuse[] = { 1.0, 1.0, 1.0, 0.8 };
GLfloat lmodel_ambient[] = { 0.1, 0.2, 0.7, 0.0 };
// Light 0 Initialized.
GLfloat light0[] = { 1.0, 1.0, 1.0, 0.9 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
// Mat Specs Implmentations.
glMaterialfv(GL_FRONT, GL_DIFFUSE, lightDiffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
// Light 0 implementation
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0);
glLightfv(GL_LIGHT0, GL_SPECULAR, light0);
// Ambient surrounding light on object.
//glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
// Enable Lighting and Depth
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
// Background (Stars: In Progress)
glNewList(1, GL_COMPILE);
glBegin(GL_POINTS);
glColor3f(1.0, 1.0, 1.0);
for (int i = 0; i < 1000; i++)
{
for (int j = 0; j < 1000; j++)
{
if (((i + j) % 2) == 0)
{
glVertex2f(2*i, 2*j);
}
}
}
glEnd();
glEndList();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glEnable(GL_COLOR_MATERIAL);
// Neptune
glColor3f(0.1, 0.1, 0.3);
glutSolidSphere(2.0, 100, 100);
// Triton
glPushMatrix();
glColor3f(0.9, 0.7, 0.8);
glRotatef((GLfloat)triton, 1.0, 1.0, 1.0);
glTranslatef(2.5, 0.0, 0.0);
glRotatef((GLfloat)triton, 1.0, 0.0, 0.0);
glutSolidSphere(0.35, 100, 100);
glPopMatrix();
// Proteus
glPushMatrix();
glColor3f(1.0, 1.0, 1.0);
glRotatef((GLfloat)proteus, 0.7, -0.4, 1.0);
glTranslatef(3.5, 0.0, 0.0);
glRotatef((GLfloat)proteus, 1.0, 0.0, 0.0);
glutSolidSphere(0.1, 100, 100);
glPopMatrix();
// Stars Background
glEnable(GL_MULTISAMPLE);
glPushMatrix();
glCallList(1); // Not Coding
glPopMatrix();
glDisable(GL_COLOR_MATERIAL);
glPopMatrix();
glFlush();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
// Triton + Proteus Orbit.
case 'a':
triton = (triton - 2) % 360;
proteus = (proteus - 5) % 360;
glutPostRedisplay();
break;
case 'd':
triton = (triton + 2) % 360;
proteus = (proteus + 5) % 360;
glutPostRedisplay();
break;
case ',':
glTranslatef(- 0.3, 0.0, 0.0);
glutPostRedisplay();
break;
case '.':
glTranslatef(0.3, 0.0, 0.0);
glutPostRedisplay();
break;
case 27:
exit(0);
break;
default:
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB | GLUT_MULTISAMPLE);
glutInitWindowSize(1000, 1000);
glutInitWindowPosition(100, 100);
glutCreateWindow("Neptune and Space");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
You you draw the start, then the perspective projection matrix and the view matrix are stills set. The "stars" are not on the viewport.
Use a scale of about 1/500 to put the points into clip space:
glVertex2f(2*i / 500.0f, 2*j / 500.0f);
Or setup an orthographic projection, before you draw the stars:
// Stars Background
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
gluOrtho2D( 0, 1000, 0, 1000 );
glCallList(1);
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
So I am still a newbie with opengl and I used this tutorial as a reference
https://www.youtube.com/watch?v=8p76pJsUP44
I am now trying to draw a set of 4 triangles that made up a square (it's my project assignment) and this is my code
#include <Windows.h>
#include <GL\glew.h>
#include <GL\freeglut.h>
#include <iostream>
using namespace std;
void changeViewPort(int w, int h)
{
glViewport(0, 0, w, h);
}
void draw() {
glBegin(GL_TRIANGLES);
glColor3f(0.0, 0.0, 255.0);
glVertex3f(0.0, 0.0, 0.0); // top triangle
glVertex3f(-1.0,1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glColor3f(50.0, 50.0, 255.0);
glVertex3f(0.0, 0.0, 0.0); // right triangle
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glColor3f(75.0, 75.0, 255.0);
glVertex3f(0.0, 0.0, 0.0);//bottom triangle
glVertex3f(1.0, -1.0, 0.0);
glVertex3f(-1.0, -1.0, 0.0);
glColor3f(50.0, 50.0, 255.0);
glVertex3f(0.0, 0.0, 0.0); //left triangle
glVertex3f(-1.0, -1.0, 0.0);
glVertex3f(-1.0, 1.0, 0.0);
glEnd();
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw();
glutSwapBuffers();
}
int main(int argc, char* argv[]) {
// Initialize GLUT
glutInit(&argc, argv);
// Set up some memory buffers for our display
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
// Set the window size
glutInitWindowSize(350, 300);
// Create the window with the title "Hello,GL"
glutCreateWindow("Hello, GL");
// Bind the two functions (above) to respond when necessary
glutReshapeFunc(changeViewPort);
glutDisplayFunc(render);
//glutDisplayFunc(draw);
// Very important! This initializes the entry points in the OpenGL driver so we can
// call all the functions in the API.
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW error");
return 1;
}
glutMainLoop();
return 0;
}
notice that in my draw function, I am just trying to create 4 different triangles with different shades of blue.
However, whenever this code is executed, only the top triangle is blue while the rest stays white
Does anyone know why this wouldnt work ? I even tried to create a for loop version of the draw function but it also didnt work
void draw() {
double x = 1.0;
double y = 1.0;
double coords[8] = { -x,y,x,y,x,-y,-x,-y };
for (int i = 0; i < 7; i=i+2) { // i = [0,2,4,6]
switch (i) {
case 0:
glColor3f(0, 0, 255);
break;
case 2:
glColor3f(50, 50, 255);
break;
case 4:
glColor3f(75, 75, 255);
break;
case 6:
glColor3f(50, 50, 255);
break;
}
if (i == 6) { //4th and 1st coordinate
glBegin(GL_TRIANGLES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(coords[i], coords[i + 1], 0.0);
glVertex3f(coords[0], coords[1], 0.0);
glEnd();
}
else {
glBegin(GL_TRIANGLES);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(coords[i], coords[i + 1], 0.0);
glVertex3f(coords[i + 2], coords[i + 3], 0.0);
glEnd();
}
}
}
glColor3f takes color components in the [0, 1] range as input and not [0, 255] as currently used.
Colors in OpenGL are stored in [0, 1] range. Unsigned ints map onto that range linearly automatically, but floats are just straight up stored.
See https://msdn.microsoft.com/en-us/library/windows/desktop/dd318399(v=vs.85).aspx
I'm having a trouble with my OpenGL program. I draw three axis Ox, Oy and Oz, along with 4 pyramids lying on the axis. When I rotate the shapes, the axis should be visible, but they are hidden by the four triangles. What can I do to see the axis?
#include <iostream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
using namespace std;
float x_angle, y_angle, z_angle;
void init() {
x_angle = y_angle = z_angle = 0;
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
}
void color3f(GLfloat red, GLfloat green, GLfloat blue) {
glColor3f(red / 255, green / 255, blue / 255);
}
void drawLine(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2, GLfloat red, GLfloat green, GLfloat blue) {
color3f(red, green, blue);
glBegin(GL_LINES);
glVertex3f(x1, y1, z1);
glVertex3f(x2, y2, z2);
glEnd();
}
void drawTriangle(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2, GLfloat x3, GLfloat y3, GLfloat z3, GLfloat red, GLfloat green, GLfloat blue) {
color3f(red, green, blue);
glBegin(GL_TRIANGLES);
glVertex3f(x1, y1, z1);
glVertex3f(x2, y2, z2);
glVertex3f(x3, y3, z3);
glEnd();
}
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-15.0, 15.0, -15.0, 15.0, -15.0, 15.0);
glViewport(100, 100, 500, 500);
glRotatef(x_angle, 1.0, 0.0, 0.0);
glRotatef(y_angle, 0.0, 1.0, 0.0);
glRotatef(z_angle, 0.0, 0.0, 1.0);
glPointSize(10.0);
drawLine(-10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0, 0.0, 0.0);
drawLine(0.0, -10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0, 0.0);
drawLine(0.0, 0.0, -10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0);
// draw pyramid
drawTriangle(0.0, 5.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 255, 255, 255);
drawTriangle(0.0, 5.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, -5.0, 0, 255, 204);
drawTriangle(0.0, 5.0, 0.0, -5.0, 0.0, 0.0, 0.0, 0.0, -5.0, 102, 102, 255);
drawTriangle(0.0, 5.0, 0.0, -5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 255, 255, 0);
glFlush();
}
void onKeyPressed(unsigned char key, int a, int b) {
switch (key) {
case 'x':
x_angle -= 3;
break;
case 'X':
x_angle += 3;
break;
case 'y':
y_angle -= 3;
break;
case 'Y':
y_angle += 3;
break;
case 'z':
z_angle -= 3;
break;
case 'Z':
z_angle += 3;
break;
default:
break;
}
display();
}
int main(int argv, char** argc) {
glutInit(&argv, argc);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(800, 800);
glutCreateWindow("3D program");
init();
glutKeyboardFunc(onKeyPressed);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
This is the result
while it should be like this
You can by removing the
glEnable(GL_DEPTH_TEST)
more information about DEPTH BUFFER: https://www.opengl.org/wiki/Depth_Buffer
I don't think the fix you mentioned in your answer works; you probably changed something else and didn't realize it had an effect. Here's a better, working version of your display function:
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-15.0, 15.0, -15.0, 15.0, -15.0, 15.0);
glViewport(100, 100, 500, 500);
glRotatef(x_angle, 1.0, 0.0, 0.0);
glRotatef(y_angle, 0.0, 1.0, 0.0);
glRotatef(z_angle, 0.0, 0.0, 1.0);
// draw pyramid
drawTriangle(0.0, 5.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 255, 255, 255);
drawTriangle(0.0, 5.0, 0.0, 0.0, 0.0, -5.0, 5.0, 0.0, 0.0, 0, 255, 204);
drawTriangle(0.0, 5.0, 0.0, -5.0, 0.0, 0.0, 0.0, 0.0, -5.0, 102, 102, 255);
drawTriangle(0.0, 5.0, 0.0, 0.0, 0.0, 5.0, -5.0, 0.0, 0.0, 255, 255, 0);
glDisable(GL_DEPTH_TEST);
glPointSize(10.0);
drawLine(-10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0, 0.0, 0.0);
drawLine(0.0, -10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0, 0.0);
drawLine(0.0, 0.0, -10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0);
glFlush();
}
As you've already figured out, make sure you supply GLUT_DEPTH to the display mode.
Make sure depth testing is on for the pyramid
Make sure it is off for the lines
Draw the lines after the pyramid, so that they'll be drawn on top of it. Without depth testing, things are just drawn one on top of another, in the order they're sent.
For bonus points, I rearranged the vertex order of your pyramid, so that it is all consistently CCW. Now if you do glEnable(GL_CULL_FACE) you'll only see the pyramid from the outside.
Failure to use GLUT_DEPTH and glEnable(GL_DEPTH_TEST) for the pyramid will result in the sides being drawn in order, which will be bizarre and non-physical.
I've changed my code by moving the function glEnable(GL_DEPTH_TEST); from init() function to main() function like this
int main(int argv, char** argc) {
glutInit(&argv, argc);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(800, 800);
glutCreateWindow("3D program");
glEnable(GL_DEPTH_TEST);
glutKeyboardFunc(onKeyPressed);
glutDisplayFunc(display);
glutMainLoop();
init();
return 0;
}
Then, the program worked like I expected. I don't know why this works. However, thanks for your helps.