Make object disappear and appear in OpenGL - c++

#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();
}

Related

Simple GLUT library issue

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)

Delta zeta not applied by gltranslatef

The program should simulate a planet rotating around another planet.
I use gltranslatef to let the planet move around the bigger planet, but the problem is that the planet should hide when is over the bigger planet, because dz is -0.5.
But if I test the program I always see the red planet over the blue one.
Another problem I have: the planet rotates too fast, how do I slow it?
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include "utility.h"
GLfloat dx=0.0;
GLfloat dz=-0.5;
bool plus=true;
void init()
{
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1, 1);
glEnable(GLUT_DEPTH);
}
void render()
{
glClearColor(BLACK);
glClear(GL_COLOR_BUFFER_BIT);
glColor4f(BLUE);
glutWireSphere(0.25, 100, 100);
glPushMatrix();
glLoadIdentity();
glTranslatef(-0.5+dx, 0.0, -dz);
glColor4f(RED);
glutWireSphere(0.05, 100, 100);
glPopMatrix();
glFlush();
}
void idle()
{
if(plus)
{
dx+=0.05;
}
else
{
dx-=0.05;
}
if(dx>=1.0)
{
dx=0.5;
plus=false;
}
else if(dx<=-0.0)
{
dx=0.0;
plus=true;
}
glutPostRedisplay();
}
int main(int argc, const char * argv[])
{
glutInit(&argc, (char**)argv);
glutInitWindowSize(500, 500);
glutInitWindowPosition(150, 150);
glutInitWindowPosition(0, 0);
glutCreateWindow("Simple");
glutIdleFunc(idle);
init();
glutDisplayFunc(render);
glutMainLoop();
return 0;
}
I haven't understood well how does the idle function work, why it gets called so many times? Can't I choose a time interval with which the idle function gets called?
More info: RED and BLUE are RGB floats, defined in the utility.h header file.
plus is a bool that is used to know if I have to decrease or increase dx.
Give this a shot:
#include <GL/glut.h>
double GetSeconds()
{
return glutGet(GLUT_ELAPSED_TIME) / 1000.0f;
}
void render()
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3ub(0,0,255);
glutWireSphere(0.25, 100, 100);
glPushMatrix();
glLoadIdentity();
static double prv = GetSeconds();
double cur = GetSeconds();
double delta = cur - prv;
prv = cur;
const float DEG_PER_SEC = 60.0f;
static float angle = 0.0f;
angle += DEG_PER_SEC * delta;
while( angle > 360 ) angle -= 360;
glPushMatrix();
glRotatef( angle, 0, 1, 0 );
glTranslatef( 0.5, 0, 0);
glColor3ub(255,0,0);
glutWireSphere(0.05, 100, 100);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1, 1);
}
void timer(int extra)
{
glutPostRedisplay();
glutTimerFunc(16, timer, 0);
}
int main(int argc, const char * argv[])
{
glutInit(&argc, (char**)argv);
glutInitWindowSize(500, 500);
glutInitWindowPosition(150, 150);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Simple");
glutReshapeFunc(reshape);
glutTimerFunc(0, timer, 0);
glutDisplayFunc(render);
glEnable( GL_DEPTH_TEST );
glutMainLoop();
return 0;
}
Important parts:
Explicit glMatrixMode() calls
Calling glutInitDisplayMode() before glutCreateWindow()
Double-buffering requires glutSwapBuffers()
Clearing the depth buffer via GL_DEPTH_BUFFER_BIT
glEnable( GL_DEPTH_TEST )
glRotatef() for planet rotation
Timer-based animation

C : display every x milliseconds (OpenGL)

I've got a C / C++ (only main file is .cpp so I can use OpenGL) program, I use OpenGL (GLUT, GLUI) in it. It already displays something but I want it to move every x ms. I render some circles (known speed and coordinates) and I have already made the function that computes it's next position knowing the refresh rate.
I've tried to put my display callback in a timer callback but the program just freezed.
What can I do in order to run the display callback every x ms ?
I've tried to put my display callback in a timer callback but the program just freezed.
Make sure to re-arm the timer in your timer callback otherwise it will only fire once:
#include <GL/glut.h>
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-10, 10, -10, 10, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
static float angle = 0;
angle += 1.0f;
glRotatef(angle, 0, 0, 1);
glColor3ub(255,0,0);
glBegin(GL_TRIANGLES);
glVertex2f(0,0);
glVertex2f(10,0);
glVertex2f(10,10);
glEnd();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
}
void timer(int extra)
{
glutPostRedisplay();
glutTimerFunc(30, timer, 0);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow("Timer");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(0, timer, 0);
glutMainLoop();
return 0;
}

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.