Glut subwindow toggle - opengl

I have a program and i have created a subwindow from my main window. The problem is that its always there, my goal is to press a key and then get that subwindow "on" and when i press it again , to make it disappear. I managed to destroy it with glutDistroyWindow but then i dont know how to make it appear again. Here is my code:
void init(void)
{
// pregatim o scena noua in opengl
if(glutGetWindow() == mainWindow)
glClearColor(0.0, 0.0, 0.0, 0.0);
else
glClearColor(1.0, 1.0, 1.0, 1.0); fereastra
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
}
void reshape2(int w,int h){
glViewport(0,0,(GLsizei) w,(GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,(float)w/h,1.0,40.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
init();
}
void reshape(int w, int h)
{
// Main Window
glViewport(0,0, (GLsizei) w, (GLsizei) h);
// calculare aspect ratio ( Width/ Height )
GLfloat aspect = (GLfloat) w / (GLfloat) h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 1.0, 100);
// init context
init();
if(damageWindow != -1)
glutDestroyWindow(damageWindow);
damageWindow=glutCreateSubWindow(mainWindow,0,0,w/5,h/5);
glutDisplayFunc(display);
glutReshapeFunc(reshape2);
glutKeyboardFunc(keyboard);
glutSpecialFunc(keyboard);
glutKeyboardUpFunc(keyboardup);
glutMouseFunc(mouse);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
int w = 800, h= 600;
glutInitWindowSize(w,h);
glutInitWindowPosition(100,100);
// Main window
mainWindow=glutCreateWindow("Tema4 - Asteroid Attack!");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardup);
glutReshapeFunc(reshape);
glutSpecialFunc(keyboard);
glutMouseFunc(mouse);
// Initializeaza scena 3D
initScene();
glutMainLoop();
return 0;
}
Ok so these are the functions that matters. In my keyboard function i want to toggle damageWindow. How do i do that ? I know how to destroy it but i can't seem to make it again.
LE: I keep getting downvotes because people dont really understand the question. The keyboard function is redundant because there is nothing there , thats what im asking you.But for the sake of you guys here it is:
void keyboard(unsigned char ch,int x,int y){
switch(ch){
case 27: exit(0);break;
case 'n':
view_subwindow=!view_subwindow;
if(view_subwindow == false)
glutDestroyWindow(damageWindow);
else{
//here i want to recreate my window DONT KNOW HOW
damageWindow=glutCreateSubWindow(mainWindow,0,0,w/5,h/5);
glutDisplayFunc(display);
glutReshapeFunc(reshape2);
glutKeyboardFunc(keyboard);
glutSpecialFunc(keyboard);
glutKeyboardUpFunc(keyboardup);
glutMouseFunc(mouse);
}
}
}

I don't think you're supposed to create or destroy any windows after you called glutMainLoop. During initialization you should create the subwindow, then afterwards you should just hide it instead, using glutHideWindow, possibly after calling glutSetWindow to make it the current window. To show it again, call glutShowWindow.
Also, you don't need to call functions like glutReshapeFunc or glutKeyboardFunc multiple times, do that just once during initialization. If you need them to do different things depending on a condition, use if's in the functions you passed to them.

Related

Draw shape with GLUT_DOUBLE mode

I have a code:
#include <gl/glut.h>
#include <stdio.h>
#define WinW 1000
#define WinH 500
/* ----------------------------------------------------------------------- */
bool mousedown = false;
void myInit(void) {
glClearColor(1.0, 1.0, 1.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
glPointSize(5.0);
glShadeModel(GL_SMOOTH);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, WinW, WinH, 0.0, -1.0, 1.0);
}
void myDisplay(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_POINTS);
glColor3f(1.0, 0.0, 0.0);
glVertex2i(50, 50);
glEnd();
//glFlush();
glutSwapBuffers();
}
void myMouse(int button, int state, int x, int y){
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
mousedown = true;
}
else
mousedown = false;
}
void myMovedMouse(int mouseX, int mouseY){
if (mousedown){
//printf("%d %d\n", mouseX, mouseY);
glBegin(GL_POINTS);
glColor3f(0.0, 1.0, 0.0);
glVertex2i(mouseX, mouseY);
glEnd();
//glFlush();
glutSwapBuffers();
}
}
/* ----------------------------------------------------------------------- */
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(WinW, WinH);
glutInitWindowPosition(100, 150);
glutCreateWindow("Computer Graphic");
myInit();
glutDisplayFunc(myDisplay);
glutMouseFunc(myMouse);
glutMotionFunc(myMovedMouse);
glutMainLoop();
}
I want to draw free shape by mouse dragging.
I have try with glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)and glFlush(), it work for me.
But when I use GLUT_DOUBLE and glutSwapBuffers() in myMovedMouse(), the screen is blinking (black-white-black-white...)
I am new in OpenGL, anyone have solution for this.
Thanks for help!
When using double buffering, you have to draw all your points on each redraw. So you have to maintain a list of all the points. The steps are then:
On startup, create an empty point list. If you want nice code, define a class/struct that contains two values for the x and y position, and use a C++ container like std::vector for your list of points.
When you get a new point from mouse input, add that point to the point list, and call glutPostRedisplay().
In the myDisplay() function, draw all the points in the list.
Having to maintain a list of points may seem to add complexity compared to using single buffering. But as soon as you go a little farther, you will probably need it anyway. For example, if the user resizes the window, you will have to be able to redraw all the points anyway. So drawing the points one by one in single buffering mode will not get you very far.

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)

OpenGL /GLUT Creating window after mainEventLoop()

I am developing a game in OpenGL/GLUT and I need to open a new window to show the score when the game is won.
In order to do this, i will call glutCreateWindow() and register the callbacks after calling mainEventLoop().
Is there a problem with this ? How should I do it properly ?
Is there a problem with this?
Yes.
Why don't you simply draw the results in the same window as the game?
Why are you using GLUT in the first place? It's not a very good framework for games. Better use GLFW or SDL.
How should I do it properly ?
By adding a small GUI system to your engine, that allows you to overlay the screen with stats (like a HUD) and a score screen.
You will need two display callback functions, display( ) and display2( ) for each window plus window = glutCreateWindow("Window 1"); and window2 = glutCreateWindow("Window 2");.
Code example :
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glut.h>
int window2 = 0, window = 0, width = 400, height = 400;
void display(void)
{
glClearColor(0.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
printf("display1\n");
glFlush();
}
void display2(void)
{
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
printf("display2\n");
glFlush();
}
void reshape (int w, int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glutPostRedisplay();
}
int main(int argc, char **argv)
{
// Initialization stuff
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(width, height);
// Create window main
window = glutCreateWindow("Window 1");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutInitWindowPosition(100,100);
// Create second window
window2 = glutCreateWindow("Window 2");
glutDisplayFunc(display2);
glutReshapeFunc(reshape);
// Enter Glut Main Loop and wait for events
glutMainLoop();
return 0;
}

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);