I recently created my first GLUT window and gave it a white background and somewhere for a camera to look at.
Anyway, I resize my window and I got these strange lines. It seemed like it glitched and captured recent fragments of my desktop screen. Here is my screenshot link on imgur:
http://i.imgur.com/gSRWnc5.png
Sorry if the picture was a little oversized, but I was wondering if there was a fix to that weird glitch.
Here is my code:
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
void display(void) {
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glFlush();
}
int main (int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowSize(400, 400);
glutInitWindowPosition(100, 100);
glutCreateWindow("My First GLUT/OpenGL Window");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
You get those weird glitches because you don't resize your viewport. What you need to do is create a callback function for glutReshapeFunc in which you call glViewport to resize your viewport. Then, you need to call glutPostRedisplay in order to re-execute your display function.
On a side note, if you want your display function to be executed constantly, use glutIdleFunc along side glutDisplayFunc.
Cheers!
Related
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.
I've been trying to draw a cone and a cylinder using GLUT. The code I've written so far takes two points from the user, which represents the height of the cone/cylinder, and I want to draw a cone and a cylinder using the two points.
I looked up Google and found standard functions called glutWireCone() and gluCylinder(), but I'm unable to understand how to use these functions to draw in the manner that I want to draw. Can someone tell me how to draw a cone and a cylinder using the two points? Please let me know if you need some extra information to understand my question correctly.
Here are my init() and main() functions for you to know the settings of my program:
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, 0, -1000.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutInitWindowPosition(220, 80);
glutCreateWindow("Mini Paint - 3D");
init();
glutDisplayFunc(display);
glutMouseFunc(mouseClick);
glutMotionFunc(mouseMove);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Well lets take that gluCylinder function and apply it to your display function. Look at it's parameters:
void gluCylinder(GLU quadric* quad,
GLdouble base,
GLdouble top,
GLdouble height,
GLint slices,
GLint stacks);
So you want to draw a cylinder given the height parameter as input. I'm guessing everything else will remain constant. every time you render you'll want to use glPushMatrix and maybe glRotatef depending on how you would like its orientation, ending this call with a glPopMatrix
Ex: OnRender(float pHeight)
void OnRender(float pHeight) {
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); //clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity();
gluCylinder(quadratic, 0.1f, 0.1f, pHeight, 32, 32);
glFlush();
}
declaring a quadratic object:
GLUquadricObj *quadratic;
quadratic = gluNewQuadric();
gluCylinder documentation: https://www.opengl.org/sdk/docs/man2/xhtml/gluCylinder.xml
The exact same code snippet is working on another machine but its not working properly for me. The GLUT is working absolutely fine as it open the created window but the line segment is not shown on the window which means there is a problem with opengl. It is not even changing the background color of the window.
I even test the opengl on my windows with a testing application and its working fine.
#ifdef WIN32
#include <windows.h>
#endif
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
void init(void){
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 400.0, 0.0, 400.0);
}
void linesegment(void){
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex2i(180, 15);
glVertex2i(10, 145);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 50);
glutInitWindowSize(400, 400);
glutCreateWindow("Testing Open GL");
init();
glutDisplayFunc(linesegment);
glutMainLoop();
return 0;
}
Most likely you're running into the rather new class of problems introduced by compositing graphics systems (Aero in Windows, Quartz Extreme on MacOS X and a multitude of various programs on Linux/X11). The gist of the problem is, that compositing is inherently double buffered: There's always an offscreen (back) buffer for the window to be drawn. And when a program indicates that it's finished with drawing the compositor will integrate it into the on-screen image.
This however brings a few caveats. Most importantly, single buffered drawing somehow needs to indicate that it's finished. While OpenGL's glFinish call should suffice from a implementors point of view, most compositing systems are not sensitive to it. You'll have to create a double buffered window pixel format and do a buffer swap to make the compositor present your image.
So for your program:
replace GLUT_SINGLE with GLUT_DOUBLE in glutInitDisplayMode
replace glFlush with glutSwapBuffers
I am starting with openGL and c++, and I was wondering why I don't see anything on the window. Here is my code:
#include <GLUT/GLUT.h>
#include <stdlib.h>
void init() {
glClearColor(0, 0, 1, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -10);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glVertex3i(-0.5, -0.5, 0);
glVertex3i(0, 0.5, 0);
glVertex3i(0.5, -0.5, 0);
glEnd();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE| GLUT_RGBA);
glutInitWindowPosition(200, 200);
glutInitWindowSize(400, 400);
glutCreateWindow("Window");
init();
glutDisplayFunc(display);
glutMainLoop();
}
I have a few questions:
If I run the program like this all I see is a white window... Didn't I set the color to blue?
When I do glutSwapBuffers() at the end of display function and run the program, I see the blue window without the triangle. So, I thought glutSwapBuffers() function only worked with double buffering.
And the most important, where the hell is my triangle? O.o Didn't I translate the camera with glTranslatf() function to -10 in the z-axes? If you are wondering why I used gluPerspective, I have to say that I am trying out new things, but neither works if I use gluOrtho2D().
I don't know if I am missing something or what. Maybe I need to search more information about this, but I think most of the code is correct.
1 & 2) Well you don't have to call glutSwapBuffers() when using single buffer. But you have to call glFlush(), so the draw commands are executed on the GPU.
3) I noticed that you are creating vertices with double coordinates, but you are calling integer version of glVertex** function (decimal part will be truncated) - it means that you will be drawing triangle with zero size.
Use glVertex3d() or glVertex3f() instead of glVertex3i().
Small note: intermediate mode is deprecated in the latest OpenGL.
I need to flash two 2d object at a certain frequency. I am using for this OpenGL (glut) and C++ in Visual C++ Express Edition. OS is Windows XP Sp3, 32 bit.
I think I have successfully implemented the basic application, but I can not figure out how to make flash objects at a certain frequency. Do you have any suggestions for me? The code I've done is this.
void display(void) {
glClear( GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glColor3f(0.0, 0.0, 0.0);
glVertex3f(140.0, 250.0+300.0, 0.0); //bottom left corner
glVertex3f(140.0+300.0, 250.0+300.0, 0.0); //bottom right corner
glVertex3f(140.0+300.0, 250.0, 0.0); //top right corner
glVertex3f(140.0, 250.0, 0.0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 1.0);
glVertex3f(640.0+200.0, 250.0+300.0, 0.0); //bottom left corner
glVertex3f(640.0+200.0+300.0, 250.0+300.0, 0.0); //bottom right corner
glVertex3f(640.0+200.0+300.0, 250.0, 0.0); //top right corner
glVertex3f(640.0+200.0, 250.0, 0.0);
glEnd();
glFlush();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode ( GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(0,0);
glutInitWindowSize(1280,800);
glutGameModeString("1280x800:32#60");
glutEnterGameMode();
glutSetWindowTitle("OpenGL SSVEP stimulator");
glDisable(GL_DEPTH_TEST);
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0,1280,800,0.0,0.0,1.0);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
To flash I thought of something like this (Pseudo-code):
int leftFrequency=12;
int rightFrequency=20;
int i=0;
while(running) {
if(i%leftFrequency)
blackSquare;
}
else {
whiteSquare;
}
if(i%rightFrequency)
blackSquare;
}
else {
whiteSquare;
}
}
but I do not know where to put this code. In the display() function maybe? Where can I increment the i variable? I tried to put everything inside the display() function, but the two squares do not flash. The i variable is increased up to 3. I have no type of error.
Maybe is it not correct the flickering logic?
Make i a global variable (or make it a static local) and put your flashing code (the last code snippet) into the display function.
Enable double buffering glutInitDisplayMode(… | GLUT_DOUBLE) and replace the glFlush() in display with glutSwapBuffers().
Add an increment of i at the end of display.
Register glutPostRedisplay as GLUT idle function, i.e. in your main function before calling glutMainLoop()
glutIdleFunc(glutPostRedisplay);
If it's going to be a certain frequency, then you need to flick based on time.