Simple GLUT library issue - c++

This will be my first post on stackoverflow.
So, I'm making a simple program(VISUAL STUDIO 2012), using GLUT library. I basically try to display a torus, but instead I get a black screen.
#include<gl/glut.h>
#include<math.h>
GLfloat r=8;
GLint spin=0;
GLfloat light_position[]={0.0,0.0,0.0,1.0};
GLfloat ex,ey=0, ez, upx=0, upy=0, upz=0;
void init(){
glClearColor(1.0,1.0,1.0,1.0);
glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_TEST);
glPushMatrix();
double sine = (float)sin((float)spin);
double cosine = (float)cos((float)spin);
ex=r*sine;
ez=r*cosine;
gluLookAt(ex,ey,-5.0,0,0,0,upx,upy,upz);
glColor3b(1.0,0,0);
glutSolidTorus(0.275,0.85,8,15);
glPopMatrix();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0,0,(GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0,20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv( GL_LIGHT0, GL_POSITION, light_position);
}
void mouse(int button, int state, int x, int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if( state == GLUT_DOWN){
spin = (spin+15)%360;
glutPostRedisplay();
}
break;
default:
break;
}
}
void main(int argc, char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(800,600);
glutInitWindowPosition(300,300);
glutCreateWindow("Light Rotating Torus");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMouseFunc(mouse);
glutMainLoop();
}
Can somebody modify it/give a hint, so it displays something?
Thanks

The most obvious problem is your UP vector. You set upx, upy and upz. That is not a valid up vector, try changing upy to 1.0f. Because of this, your torus was probably rendered out of screen.
Also, glClear doesn't take GL_DEPTH_TEST as a parameter.
Correct call should be:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Because of this, your screen was not cleared and stayed black (while you set glClearColor to be white).
And lastly, main function should always return int, never void (though it doesn't change anything in your case)

Related

Make object disappear and appear in OpenGL

#include <stdio.h> // this library is for standard input and output
#include "glut.h" // this library is for glut the OpenGL Utility Toolkit
#include <math.h>
// left square
void drawShape1(void) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(82, 250);
glVertex2f(82, 200);
glVertex2f(140, 200);
glVertex2f(140, 250);
glEnd();
}
// right square
void drawShape2(void) {
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(232, 250);
glVertex2f(232, 200);
glVertex2f(290, 200);
glVertex2f(290, 250);
glEnd();
}
void initRendering() {
glEnable(GL_DEPTH_TEST);
}
// called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, (float)w, 0.0f, (float)h, -1.0f, 1.0f);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawShape1();
drawShape2();
glutSwapBuffers();
glutPostRedisplay();
}
// the timer code
void update(int value) {
// add code here
glutPostRedisplay();
glutTimerFunc(5, update, 0);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
glutCreateWindow("Squares");
initRendering();
glutDisplayFunc(display);
glutReshapeFunc(handleResize);
glutTimerFunc(5, update, 0);
glutMainLoop();
return(0);
}
I have two squares in the middle. One square is on the left and the other square is on the right (see screenshot below). I am trying to make the left square disappear/appear every 5 seconds. I have added the timer code, but I am struggling on how to make the object disappear/appear.
Preview:
The unit of the first parameter of glutTimerFunc milliseconds rather than seconds. So a 5 seconds equals the value 5000.
Create a variable (square1_visible) of type bool which states whether the left square is visible:
bool square1_visible = true;
Change the state of the variable square1_visible every 5 seconds in the timer function update:
void update(int value) {
glutTimerFunc(5000, update, 0);
square1_visible = !square1_visible;
}
Draw the left square dependent on the state of the variable square1_visible:
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if ( square1_visible )
drawShape1();
drawShape2();
glutSwapBuffers();
glutPostRedisplay();
}

Using glutPassiveMotionFunc(); in GLUT

I have written a simple OpenGL program in C++ that displays a line joining the center of the window to the current position of the mouse pointer.
My code is :
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include<iostream>
using namespace std;
void passive(int,int);
void reshape(int,int);
void init(void);
void display(void);
void camera(void);
int x=3,y=3;
int main (int argc,char **argv) {
glutInit (&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowSize(1364,689);
glutInitWindowPosition(0,0);
glutCreateWindow("Sample");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutPassiveMotionFunc(passive);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
void display(void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
camera();
glBegin(GL_LINES);
glVertex3f(0,0,0);
glVertex3f(x,y,0);
glEnd();
glutSwapBuffers();
}
void camera(void) {
glRotatef(0.0,1.0,0.0,0.0);
glRotatef(0.0,0.0,1.0,0.0);
glTranslated(0,0,-20);
}
void init(void) {
glEnable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_COLOR_MATERIAL);
}
void reshape(int w, int h) {
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,(GLfloat)w/(GLfloat)h,1.0,100.0);
glMatrixMode(GL_MODELVIEW);
}
void passive(int x1,int y1) {
x=x1; y=y1;
}
The problem I am facing is that the x and y values set in the passive() function is not correctly mapped into the screen which uses perspective projection. So the line drawn is joining the center to some other coordinate outside the screen. Any modifications to the code to get it working properly?
An easy way would be to create an orthographic projection matrix and then render all of your "2D" elements (including this line, using the screen coordinates provided by glutPassiveMotionFunc).
Something like this:
void display() {
// clear
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( ... ) // create 3D perspective projection matrix
glMatrixMode(GL_MODELVIEW);
// Render 3D content here
// Render 2D content
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, height, 0); // create 2D orthographic projection matrix with coordinate system roughly equivalent to window position
glMatrixMode(GL_MODELVIEW);
glBegin(GL_LINES);
glVertex2f( width / 2, height / 2 ); // now we can use "pixel coordinates"
glVertex2f( cursorX, cursorY );
glEnd();
...
}
Compare this to your modification of the perspective projection in your reshape method.
Obviously you'll also want to disable states that don't make sense for a "2D" rendering (like depth buffer checking, etc) but it should be pretty obvious. Take a look at this GDSE post for a discussion of how other people do this same task.

Opengl proper lighting problem

I have written the following program to display a teapot on a table in a room with 2side walls and a floor.
#include <stdio.h>
#include <glut.h>
void wall1(float thickness)
{
glPushMatrix();
glTranslatef(100,100,0);
glRotatef(90,1,0,0);
glScalef(thickness,1,1);
glutSolidCube(100);
glPopMatrix();
}
void wall2(float thickness)
{
glPushMatrix();
glTranslatef(150,100,-50);
glScalef(1,1,thickness);
glutSolidCube(100);
glPopMatrix();
}
void floor(float thickness)
{
glPushMatrix();
glTranslatef(150,50,0);
glScalef(1,thickness,1);
glutSolidCube(100);
glPopMatrix();
}
void leg(float thickness)
{
glPushMatrix();
glScalef(thickness,.5,thickness);
glutSolidCube(100);
glPopMatrix();
}
void tableTop(float thickess)
{
glPushMatrix();
glTranslatef(150,100,0);
glScalef(.5,thickess,.5);
glutSolidCube(100);
glPopMatrix();
}
void table()
{
tableTop(.05);
glPushMatrix();
glTranslatef(125,75,-25);
leg(.05);
glPopMatrix();
glPushMatrix();
glTranslatef(175,75,-25);
leg(.05);
glPopMatrix();
glPushMatrix();
glTranslatef(175,75,25);
leg(.05);
glPopMatrix();
glPushMatrix();
glTranslatef(125,75,25);
leg(.05);
glPopMatrix();
glPushMatrix();
glTranslatef(150,110,0);
glScalef(.1,.1,.1);
glutSolidTeapot(100);
glPopMatrix();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float pos[] = {200,200,0};
float dif[] = {.3,.3,.3,3};
float spe[] = {1,1,1,1};
float amb[] = {1,1,1,0};
glLightfv(GL_LIGHT0,GL_POSITION,pos);
glLightfv(GL_LIGHT0,GL_DIFFUSE,dif);
glLightfv(GL_LIGHT0,GL_AMBIENT,amb);
glLightfv(GL_LIGHT0,GL_SPECULAR,spe);
glTranslatef(50,50,0);
glRotatef(30,1,0,0);
glRotatef(-30,0,1,0);
wall1(.05);
wall2(.05);
floor(0.05);
table();
glFlush();
}
void reshape(int w,int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,400,0,400,-400,400);
glMatrixMode(GL_MODELVIEW);
}
void main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("woot");
glClearColor(1,1,1,1);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_SMOOTH);
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
}
The problem with this is my lighting part is not working as expected. Its not illuminating evenly all my objects... What am i missing? This making even the teapot hard to sea.
My lighting part is in display function.
I was missing
glEnable(GL_NORMALIZE);
in the main function, and thus opengl was not rendering it properly! Alse #Christian's answer of using ambient only worked.
:)
OpenGL fixed function pipeline lighting is evaluated at the vertices only. glutSolidCube just creates vertices at the corners and nowhere else. So your lighting is calculated only very coarse. You could either switch to per fragment lighting by using a shader, or tesselate your objects. The latter requires you don't use glutSolidCube and instead load objects modelled in a 3D modeller or write your own primitive generators that offer a higher tesselation. I strongly recommend the first option.
glutSolidCube is just a very crude stand in function BTW.
If you want to evenly light all objects, only use ambient lighting.

OpenGL particle system

I'm trying to simulate a particle system using OpenGl but I can't get it to work, this is what I have so far:
#include <GL/glut.h>
int main (int argc, char **argv){
// data allocation, various non opengl stuff
............
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );
glutInitWindowPosition(100,100);
glutInitWindowSize(size, size);
glPointSize (4);
glutCreateWindow("test gl");
............
// initial state, not opengl
............
glViewport(0,0,size,size);
glutDisplayFunc(display);
glutIdleFunc(compute);
glutMainLoop();
}
void compute (void) {
// change state not opengl
glutPostRedisplay();
}
void display (void) {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
for(i = 0; i<nparticles; i++) {
// two types of particles
if (TYPE(particle[i]) == 1) glColor3f(1,0,0);
else glColor3f(0,0,1);
glVertex2f(X(particle[i]),Y(particle[i]));
}
glEnd();
glFlush();
glutSwapBuffers();
}
I get a black window after a couple of seconds (the window has just the title bar before that). Where do I go wrong?
LE: the x and y coordinates of each particle are within the interval (0,size)
Try to make these changes in your code:
move the Main function at the end of the file
glPoinSize call belongs to the Display function
then you should provide a function to handle resizing of the window glutReshapeFunc(reshape), something like this
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
}
glFlush is called from glutSwapBuffers function so you don't need it there
insert this code (after glutCreateWindow call) to set the initial position for the projection
glClearColor(0.2, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 10, 0.0, 10, -1.0, 1.0);

why does not my opengl program work?

I was writing a program to draw a square in my XY plane and make it rotate 360 degree, but it is not working.
void setupRC()
{
glClearColor(0,0,1,1);
glColor3f(1,0,0);
}
void timerfunc(int value)
{
glutPostRedisplay();
glutTimerFunc(33, timerfunc ,1);
}
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
static GLfloat rot = 0.0f,x =0.0f , y=10.0f , z=0.0f;
rot++;
x = 10 * cos(rot);
y = 10 * sin(rot);
glPushMatrix();
glRotatef(rot,0.0,1.0,0.0);
glBegin(GL_POLYGON);
glVertex3i(10,-10,0);
glVertex3i(10,10,0);
glVertex3i(-10,10,0);
glVertex3i(-10,-10,0);
glVertex3i(10,-10,0);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
void ChangeSize(GLint w, GLint h)
{
if(h==0)
h = 1;
GLfloat aspectratio = (GLfloat)w/(GLfloat)h;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, aspectratio, -1.0, 400.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc , char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800,600);
glutInitWindowPosition(0,0);
glutCreateWindow("chelsea");
glutTimerFunc(33, timerfunc , 1);
setupRC();
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutMainLoop();
return 0;
}
I get no output, just a blank screen.
gluPerspective(60.0f, aspectratio, -1.0, 400.0);
Looks wrong, the near clipping plane needs to be a positive number
You should really use glRotatef for rotating, because your code is wrong if you want a plane rotating around XY (x and y will be 0 for some values of rot and you'll get to see nothing at all).
And you should perhaps give your polygons a color using the glColor commands.
As JB said, your gluPerspective call seems wrong, too. See this link for a reference.