I am trying this sample open gl program on my codelite ide.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glut.h>
GLenum doubleBuffer;
GLint thing1, thing2;
static void Init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearAccum(0.0, 0.0, 0.0, 0.0);
thing1 = glGenLists(1);
glNewList(thing1, GL_COMPILE);
glColor3f(1.0, 0.0, 0.0);
glRectf(-1.0, -1.0, 1.0, 0.0);
glEndList();
thing2 = glGenLists(1);
glNewList(thing2, GL_COMPILE);
glColor3f(0.0, 1.0, 0.0);
glRectf(0.0, -1.0, 1.0, 1.0);
glEndList();
}
static void Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void Key(unsigned char key, int x, int y)
{
switch (key) {
case '1':
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glutPostRedisplay();
break;
case '2':
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glutPostRedisplay();
break;
case 27:
exit(0);
}
}
static void Draw(void)
{
glPushMatrix();
glScalef(0.8, 0.8, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glCallList(thing1);
glAccum(GL_LOAD, 0.5);
glClear(GL_COLOR_BUFFER_BIT);
glCallList(thing2);
glAccum(GL_ACCUM, 0.5);
glAccum(GL_RETURN, 1.0);
glPopMatrix();
if (doubleBuffer) {
glutSwapBuffers();
} else {
glFlush();
}
}
static void Args(int argc, char **argv)
{
GLint i;
doubleBuffer = GL_FALSE;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-sb") == 0) {
doubleBuffer = GL_FALSE;
} else if (strcmp(argv[i], "-db") == 0) {
doubleBuffer = GL_TRUE;
}
}
}
int main(int argc, char **argv)
{
GLenum type;
glutInit(&argc, argv);
Args(argc, argv);
type = GLUT_RGB | GLUT_ACCUM;
type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
glutInitDisplayMode(type);
glutInitWindowSize(300, 300);
glutCreateWindow("Accum Test");
Init();
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutDisplayFunc(Draw);
glutMainLoop();
}
Program compiles fine on my machine, when tried to run it just output press any key to continue and program exits after key is pressed.
What I am missing ?
What command line arguments have you passed? You have no choice but to use -db for reasons I will explain.
In Windows 7, you cannot draw a single-buffered window because the window manager makes a copy of the framebuffer when you swap buffers and that is what it displays (composites). Without swapping buffers, nothing will ever be displayed. This modern window system design prevents painting partially completed frames, but it mandates double-buffered rendering.
In fact, you should re-write your software so that it defaults to double-buffered rendering unless you specify a command line argument instead of the other way around. This issue affects other platforms besides modern Windows (Vista and newer).
Related
When I execute the code I get a hot air balloon formed of three elements. My issue is that when I move the objects from the keyboard, the objects loose color, and become more like wire than solid.
From what I discovered until now, my trouble comes from this function call:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
But I need it to make the ropes...
/*
This program shows a hot air balloon rotating around its own axe to the left and to the right
*/
#include "glos.h"
#include<math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
void myinit(void);
void CALLBACK display(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
void CALLBACK rotateRight(void);
void CALLBACK rotateLeft(void);
static GLfloat x = 0;
static GLfloat y = 0;
static GLfloat z = 0;
static GLfloat alfa = 0;
double PI = 3.14159265;
void myinit (void) {
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
}
void CALLBACK rotateLeft(void) { y -= 5; }
void CALLBACK rotateRight(void) { y += 5; }
void CALLBACK display (void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(x, 1, 0, 0);
glRotatef(y, 0, 1, 0);
glTranslatef(0, -80, 0);
//cube = basket
glColor3f(1, 1, 0);
auxSolidCube(50);
//full sphere = baloon
glPushMatrix();
glColor3f(1.0, 0.0, 0.0);
glTranslatef(0,200,0);
glRotatef(-90, 1, 0, 0);
auxSolidSphere(130.0);
glPopMatrix();
//polygon cylinder = ropes
glPushMatrix();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUAD_STRIP);
glColor3f(0.0, 1.0, 1.0);
for (alfa = 0; alfa <= 360; alfa+=30) {
glVertex3f(65 * sin((PI * alfa) / 180), 100, 65 * cos((PI * alfa) / 180));//top of the cylinder
glVertex3f(15 * sin((PI * alfa) / 180),0, 15 * cos((PI * alfa) / 180));//base of the cylinder
}
glEnd();
glPopMatrix();
glPopMatrix();
glFlush();
}
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
if (!h) return;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho (-400,400, -400 *(GLfloat)h / (GLfloat)w, +400.0*(GLfloat)h/(GLfloat)w, -1000.0, 1000.0);
else
glOrtho (-400*(GLfloat)w / (GLfloat)h, 400.0*(GLfloat)w/(GLfloat)h, -400, 400.0, -1000.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGB | AUX_DEPTH);
auxInitPosition (100, 0, 600, 400);
auxInitWindow ("Hot air balloon");
myinit ();
auxKeyFunc(AUX_RIGHT, rotateRight);
auxKeyFunc(AUX_LEFT, rotateLeft);
auxReshapeFunc (myReshape);
auxMainLoop(display);
return(0);
}
OpenGL is a state engine. Once a state has been set, it is retained until it is changed again, even beyond frames. Therefore, you need to set the polygon mode GL_FILL before rendering the solid geometry:
void CALLBACK display (void)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// render solid geometry
// [...]
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// render wireframe geometry
// [...]
}
#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();
}
I have my program configured to close when I press the 'q' key. It was simple enough to orchestrate after reading the glutKeyboard prototype, so I thought I would also add the option to close with the right mouse button. However, no matter what I do, I can't get this to work. I'm curious if there is some subtle difference between mouseFunc and keyboardFunc that I'm missing? Here is my code:
#define GLUT_DISABLE_ATEXIT_HACK
#include <GL/glut.h>
#include <GL/gl.h>
//#include <assert.h>
void init (void)
{
glClearColor (1.0, 1.0, 0.0, 0.0); /* Set background to yellow */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (0.0, 0.0, 1.0);
glBegin(GL_TRIANGLES);
glVertex2d (0.0, 0.0);
glVertex2d (1.0, 0.0);
glVertex2d (0.5, 0.866);
glEnd();
glFlush (); //Display immediately
}
void keyEscape( unsigned char key, int x, int y )
{
switch ( key )
{
case 113: // 'Q' key for escape
int windowID = glutCreateWindow ("triangle");
glutDestroyWindow (windowID);
exit (0);
break;
}
glutPostRedisplay();
}
void mouseEscape( int button, int state, int x, int y )
{
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
int windowID = glutCreateWindow ("triangle");
glutDestroyWindow (windowID);
exit (0);
glutPostRedisplay();
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (250, 250);
glutInitWindowPosition ((glutGet(GLUT_SCREEN_WIDTH)-250)/2, (glutGet(GLUT_SCREEN_HEIGHT)-250)/2);
glutCreateWindow ("triangle");
init ();
glutDisplayFunc(display);
glutKeyboardFunc(keyEscape);
glutMouseFunc(mouseEscape);
glutMainLoop();
return 0;
}
I parsed out a few more keyboard shortcuts (such as z for zooming) that all work similarly, hence my use of a switch statement as opposed to an if, but that is the only real difference I can see, and attempting to use a switch case has not worked for me either. I've also tried moving the redisplay command outside the if, to no avail. Any idea why mouse closing won't cooperate, but key closing will?
Turns out I was somehow building against an old .exe that wouldn't updated even with a 'Clean Project' operation. I changed projects and now all is fine... Thanks for the assistance all the same!
I am fiddling with graphics, and trying to find a way to have the shape I am drawing (in this case, a triangle) scale with window sizing. However, I only want the width to update, and the height to remain the same.
I have done some research, and tried using glutGet(GLUT_SCREEN_WIDTH) as a multiplier or similar (e.g. (GLUT_SCREEN_WIDTH /100) - 250) to the vertices of my shape, but I feel I may be missing a key idea. Should I instead be applying the scaling operation to the viewport, not the shape's points? Whenever I scale the points, they don't seem to scale with the window. Code below.
#define GLUT_DISABLE_ATEXIT_HACK
#include <GL/glut.h>
#include <GL/gl.h>
//#include <assert.h>
void init (void)
{
glClearColor (1.0, 1.0, 0.0, 0.0); /* Set background to yellow */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (0.0, 0.0, 1.0);
glBegin(GL_TRIANGLES);
glVertex2d (0.0, 0.0);
glVertex2d(1.0, 0.0);
glVertex2d (0.5, 0.866);
glEnd();
glFlush (); //Display immediately
}
void keyEscape( unsigned char key, int x, int y )
{
switch ( key )
{
case 113: // 'Q' key for escape
int windowID = glutCreateWindow ("triangle");
glutDestroyWindow (windowID);
exit (0);
break;
}
glutPostRedisplay();
}
void mouseEscape( int button, int state, int x, int y )
{
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
int windowID = glutCreateWindow ("triangle");
glutDestroyWindow (windowID);
exit (0);
glutPostRedisplay();
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (250, 250);
glutInitWindowPosition ((glutGet(GLUT_SCREEN_WIDTH)-250)/2, (glutGet(GLUT_SCREEN_HEIGHT)-250)/2);
glutCreateWindow ("triangle");
init ();
glutKeyboardFunc(keyEscape);
glutMouseFunc(mouseEscape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Step 1: Get rid of the Init function. Projection setup is part of the drawing process.
Step 2: Use the Window width as input for the left/right parameter of glOrtho
Like this:
void display(void)
{
int const win_width = glutGet(GLUT_WINDOW_WIDTH);
int const win_height = glutGet(GLUT_WINDOW_HEIGHT);
float const win_aspect = (float)win_width / (float)win_height;
glClearColor (1.0, 1.0, 0.0, 0.0); /* Set background to yellow */
glClear (GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, win_aspect, 0.0, 1.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f (0.0, 0.0, 1.0);
glBegin(GL_TRIANGLES);
glVertex2d (0.0, 0.0);
glVertex2d(1.0, 0.0);
glVertex2d (0.5, 0.866);
glEnd();
glFlush (); // Tell OpenGL to process what we submitted so far
}
BTW: You should switch to a double buffered mode and use glutSwapBuffers instead of glFlush/glFinish; on some systems single buffered mode doesn't work (well). Today the only reliable method is double buffering.
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);