I don't know very much about openGL/glut, but I've used it before successfully for some exceedingly simple things in 2D.
Now I want to be able to draw spheres in 3D. I'm trying to simulate particle collisions, so all I'm really going to need to do on the graphics end is draw spheres.
Here's my abortive attempt
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glutSwapBuffers();
}
void timerProc(int arg)
{
glutTimerFunc(50,timerProc,0);
// Reset transformations
glLoadIdentity();
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glColor3f(0.0,0.0,0.0); //color = black
glPushMatrix();
glTranslated(0,0,0);
glutSolidSphere(.74, 500, 500);
glPopMatrix();
glutSwapBuffers();
}
int main(int argc, char **argv)
{
srand(time(NULL));
init();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(50,30);
glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH)-80,glutGet(GLUT_SCREEN_HEIGHT)-60);
mainWindow=glutCreateWindow("New Window"); //global variable
WIDTH=glutGet(GLUT_WINDOW_WIDTH); //global variable
HEIGHT=glutGet(GLUT_WINDOW_HEIGHT); //global variable
glutDisplayFunc(renderScene);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glutTimerFunc(50,timerProc,0);
glutMainLoop();
return 0;
}
Hopefully all of my problems stem from one really basic mistake...
For some reason, this creates an oval. And, though the oval is pretty big (maybe about an 1/8th of the screen wide and tall), if I lower the radius down to .73 it vanishes, I'm guessing because it's too small to see.
How would I make it so that this sphere would show up circular like you'd expect, and so that as I can see everything that's happening in a given volume, say a 10x10x10 box, the way you would if you were just standing next to a box of particles that were flying around and peering into it, or a reasonable approximation. Right now it's hard to tell what exactly I'm looking at (I know that I'm standing at 1,1,1 and looking at the origin, but it's hard to grasp exactly what I'm seeing)
Also, occasionally when I run it the whole screen is just black. Then when I clean and build and run again it's fine. Not really a huge concern, but annoying, and I'd love to understand what was going on.
Also, when I the number of slices and stacks was lower, it would look fine if the radius was large, but become extremely distorted when the radius was small, which I thought was very strange...
The main problem you are having here is Z clipping. The initial Z range for the scene is (-1, 1) so you only see a part of the actual sphere and by change in its size you go out of z range.
Image
There are several problems I see in the code.
It is good to get a grasp of how the GLUT workflow actually works.
Lets see what the code does wrong.
Main
int main(int argc, char **argv)
{
srand(time(NULL));
init();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(50, 30);
glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH) - 80,
glutGet(GLUT_SCREEN_HEIGHT) - 60);
mainWindow = glutCreateWindow("New Window"); //global variable
WIDTH = glutGet(GLUT_WINDOW_WIDTH); //global variable
HEIGHT = glutGet(GLUT_WINDOW_HEIGHT); //global variable
glutDisplayFunc(renderScene);
Here you define the display function. It is called every time the window contents has to be invalidated. In this case it is invalidated only at start. The renderScene function does not do anything awesome, just clears the screen. So you get a black screen at the beginning.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
No need for blending at the moment. You can skip that part altogether.
glutTimerFunc(50, timerProc, 0);
Now you set up the timerProc function to be called in 50 milliseconds.
glutMainLoop();
As the documentation states: glutMainLoop enters the GLUT event processing loop. This routine should be called at most once in a GLUT program. Once called, this routine will never return. It will call as necessary any callbacks that have been registered.
return 0;
}
Render Scene
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
This is the only place where you clear the screen. Timer Func does not do this.
glLoadIdentity();
You are reseting the matrices.
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
Setting up the matrices. (One matrix to be precise)
glutSwapBuffers();
And without drawing anything you swap buffers.
}
Scene rendering function is called each time the window frame has to be redrawn.
Timer
This function does rely on the screen being cleared at first by the renderScene.
void timerProc(int arg)
{
glutTimerFunc(50, timerProc, 0);
// Reset transformations
glLoadIdentity();
// Set the camera
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
Not clearing this time. Only setting the color.
glColor3f(0.0, 0.0, 0.0); //color = black
glPushMatrix();
glTranslated(0, 0, 0);
glutSolidSphere(.74, 500, 500);
glPopMatrix();
glutSwapBuffers();
}
How to fix it?
Just setup the matrices. With proper Z range.
void resetTransformations() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1000, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
}
void renderScene()
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset transformations
resetTransformations();
// Just to see some triangles
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0.0, 0.0, 0.0); //color = black
glPushMatrix();
glTranslated(0, 0, 0);
glutSolidSphere(0.74, 500, 500);
glPopMatrix();
glutSwapBuffers();
}
int main(int argc, char **argv)
{
srand(time(NULL));
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(50, 30);
glutInitWindowSize(256, 256);
mainWindow = glutCreateWindow("New Window"); //global variable
WIDTH = glutGet(GLUT_WINDOW_WIDTH); //global variable
HEIGHT = glutGet(GLUT_WINDOW_HEIGHT); //global variable
glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glutMainLoop();
return 0;
}
Related
i have an assignment to draw a pyramid onto the screen and then rotate after i press the 'k' key in my keyboard.
Everything works ok, except the rotation part as the program doesn't seem to be noting me pressing the key. The code goes as follows:
void changeSize(int w, int h) {
if(h == 0)
h = 1;
float ratio = w * 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
// Set perspective
gluPerspective(45.0f ,ratio, 1.0f ,1000.0f);
// return to the model view matrix mode
glMatrixMode(GL_MODELVIEW);
}
void renderScene(void) {
// clear buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// set the camera
glLoadIdentity();
gluLookAt(5.0,5.0,5.0,
0.0,0.0,0.0,
0.0f,2.0f,0.0f);
// put the geometric transformations here
// put drawing instructions here
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-100.0f, 0.0f, 0.0f);
glVertex3f( 100.0f, 0.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, -100.0f, 0.0f);
glVertex3f(0.0f, 100.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, -100.0f);
glVertex3f(0.0f, 0.0f, 100.0f);
glEnd();
//triangulos da base
glBegin(GL_TRIANGLES);
glColor3f(255.0f,255.0f,255.0f);
glVertex3f(1.0f,0.0f,1.0f);
glVertex3f(-1.0f,0.0f,-1.0f);
glVertex3f(-1.0f,0.0f,1.0f);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(1.0f,0.0f,1.0f);
glVertex3f(1.0f,0.0f,-1.0f);
glVertex3f(-1.0f,0.0f,-1.0f);
glEnd();
//triangulos das faces
glBegin(GL_TRIANGLES);
glVertex3f(1.0f,0.0f,1.0f);
glVertex3f(0.0f,2.0f,0.0f);
glVertex3f(-1.0f,0.0f,1.0f);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(1.0f,0.0f,-1.0f);
glVertex3f(0.0f,2.0f,0.0f);
glVertex3f(1.0f,0.0f,1.0f);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(1.0f,0.0f,-1.0f);
glVertex3f(0.0f,2.0f,0.0f);
glVertex3f(-1.0f,0.0f,-1.0f);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f,0.0f,-1.0f);
glVertex3f(0.0f,2.0f,0.0f);
glVertex3f(-1.0f,0.0f,1.0f);
glEnd();
// End of frame
glutSwapBuffers();
}
// write function to process keyboard events
void rotate (unsigned char key, int x, int y) {
if (key == 'k')
glRotatef(45,1.0,1.0,0.0);
glutPostRedisplay();
}
int main(int argc, char **argv) {
// init GLUT and the window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(1200,1200);
glutCreateWindow("CG#DI-UM");
// Required callback registry
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
// put here the registration of the keyboard callbacks
glutKeyboardFunc(rotate);
// OpenGL settings
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
// enter GLUT's main cycle
glutMainLoop();
return 0;
}
It seems that my program is not noting me pressing the key even tho i am. Im tried only printing the keys that are being pressed, and that works, so i'm really lost here.
glRotatef seem to have no effect in rotate, because glLoadIdentity() is called at the begin of renderScene. Actually glRotatef changes the current matrix, but when the scene is rendered (renderScene), then glLoadIdentity() loads the Identity matrix to the current matrix.
Anyway it is a bad style to do changes to the current matrix in input event callbacks. Change states and values of variables in the input events and use the variables to set the current model view matrix before the scene is rendered in renderScene.
Add a global variable angle:
float angle = 0.0f;
Change the value of the variable in renderScene. e.g:
void rotate (unsigned char key, int x, int y) {
if (key == 'k') {
angle += 45.0f;
glutPostRedisplay();
}
}
And apply the rotation to the current matrix in renderScene:
void renderScene(void) {
// clear buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// set the camera
glLoadIdentity();
gluLookAt(5.0,5.0,5.0,
0.0,0.0,0.0,
0.0f,2.0f,0.0f);
// apply rotation
glRotatef(angle, 1.0f, 1.0f, 0.0f);
// [...]
}
I tired implementing a simple zoom in/out using the glutMouseWheelFunc in VC++. I am able to achieve the zooming in/out but while doing so, the axes(GLlines) tend to disappear after zooming more than a certain level.
Am using the glutMouseWheelFunc to increase/decrease z- axis value in glTranslatef.
I have defined 'z' of glTranslatef for as camera distance:
float cDist= 30.0f; // camera distance
Then used it in glTranslatef as,
glTranslatef(0.0f, 0.0f, -cDist);
in display function below.
void display(void) {
glClearColor(0.0, 0.0, 0.0, 1.0); //clear the screen to black
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//clear the color buffer and the depth buffer
enable();
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -cDist);
glRotatef(xrot, 1.0, 0.0, 0.0);
---------------
glBegin(GL_LINES);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-500, 0, 0);
glVertex3f(500, 0, 0);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0, -500, 0);
glVertex3f(0, 500, 0);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0, 0, -500);
glVertex3f(0, 0, 500);
glTranslated(-xpos, 0.0f, -zpos); //translate the screento the position of our camera
glColor3f(1.0f, 1.0f, 1.0f);
glutSwapBuffers();
}
Afterwards, I defined wheelfunc as,
void mouseWheel(int button, int dir, int x, int y)
{
if (dir > 0)
{
cDist = cDist++;
}
else
{
cDist= cDist--;
}
return;
}
and called it in main function with glutMouseWheelFunc(mouseWheel);
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Window");
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);
glutMotionFunc(mouseMovement);
glutMouseWheelFunc(mouseWheel);---- here
-----
---
glutMainLoop();
return 0;
}
Is this approach of zooming in proper? if not, what could be the alternative ? Also how can I define axes(lines I drew) to full extent of the screen?
thanks for the help. Seems like I missed up setting up proper depth value for gluPerspective. Once I increased the depth value, zoom out/in was working fine
So I am working on making a game in c++ and I am using SDL2 and OpenGL/GLEW. I am attempting to just draw basic shapes to my window, however, it is just creating a black screen when it should be drawing a triangle. This is the code.
Game Loop:
int main(int argc, char** argv) {
Window window("Test", 600, 400);
RenderingEngine e(window);
e.Init();
while (!window.IsCloseRequested()) {
window.SwapBuffers();
e.Render();
}
return 0;
}
Window Class:
Window::Window(const std::string& title, unsigned int width, unsigned int height) :
m_title(title), m_width(width), m_height(height), m_isCloseRequested(false) {
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
m_window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
m_glContext = SDL_GL_CreateContext(m_window);
SDL_GL_MakeCurrent(m_window, m_glContext);
SDL_GL_SetSwapInterval(1);
glewExperimental = GL_TRUE;
GLenum res = glewInit();
if (res != GLEW_OK) {
std::cerr << "Error initializting OpenGL." << std::endl;
exit(1);
}
}
void Window::SwapBuffers() {
SDL_GL_SwapWindow(m_window);
}
RenderingEngine Class:
RenderingEngine::RenderingEngine(const Window& window) : m_window(&window) {
}
RenderingEngine::~RenderingEngine() {
if (m_window) delete m_window;
}
void RenderingEngine::Init() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_FRAMEBUFFER_SRGB);
}
void RenderingEngine::Render() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f, -1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
glEnd();
}
I cannot figure out why it isn't drawing to the screen, so any help is greatly appreciated. Thanks!
You're setting up back face culling specifying that your front facing triangles have clockwise winding order, and you want to cull everything that is not front facing:
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
But the triangle you specify has counter-clockwise winding order:
glVertex3f(-1.0f, -1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
You can verify that by drawing the points on a piece of paper, with the x-axis going right and the y-axis up. You will see the order of points is counter-clockwise around the origin.
Based on this, your triangle is eliminated by back face culling. Since using counter-clockwise winding order is much more commonly used with OpenGL, I would suggest using it by changing the glFrontFace() call to:
glFrontFace(GL_CCW);
Or don't make the call at all, since this is the default.
you didn`t loaded View/Projection/Model matrices ... i guess that would be a problem... also you should use shaders if you want to make in 3.2 style
The idea from this code is to let a windmill like structure to rotate, the problem is that the entire object rotates instead of the windmill fan itself (not the red triangles only). here is the code (I use the keys to control speed)
#include <windows.h> // for MS Windows
#include <GL/glut.h> // GLUT, include glu.h and gl.h
float angle = 0.00002f;
int refreshMills = 30;
void initGL() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black and opaque
}
void Timer(int value) {
glutPostRedisplay(); // Post re-paint request to activate display()
glutTimerFunc(refreshMills, Timer, 0); // next Timer call milliseconds later
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f)
glVertex2f(0.0f, 0.0f);
glVertex2f(-0.4f, 0.2f);
glVertex2f(-0.2f, 0.4f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.4f, -0.2f);
glVertex2f(0.2f, -0.4f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(-0.4f, -0.2f)
glVertex2f(-0.2f, -0.4f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.4f, 0.2f);
glVertex2f(0.2f, 0.4f);
glEnd();
glRotatef(angle, 0.0f, 0.0f, 1.0f);
angle=angle+0.000002f;
glutPostRedisplay();
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(-0.4f, -0.6f);
glVertex2f(0.4f, -0.6f);
glEnd();
glFlush();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 'a':{
angle+=1;
glutPostRedisplay();
}
case 's':
angle+=2;
glutPostRedisplay();
case 'd':
angle+=3
glutPostRedisplay();
case 'f':
angle=0;
}
}
}
int main(int argc, char** argv) {
glutInit(&argc, argv); // Initialize GLUTx
glutCreateWindow("Windmill"); // Create window with the given title
glutInitWindowSize(320, 320); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutDisplayFunc(display);
glutTimerFunc(0, Timer, 0);
glutSpecialFunc(specialKeys);
glutKeyboardFunc(keyboard);
initGL(); // Our own OpenGL initialization
glutMainLoop(); // Enter the event-processing loop
return 0;
}
You need to implement some sort of hierarchy(commonly a scene graph) here that uses transformation matrixes to do your transformations.
Basically, create a "Windmill" object that has its own transformation matrix. Then create a "Windmill Fan" object that has its own. Make the fan a child of the parent. The transformations essentially propagate down. Transform the Windmill, then transform the Windmill Fan.
Post on Scene Graphs
You may also want to check out the Game Development section of stackoverflow. These questions are usually not met with open arms here.
You need to clear your transformations before trying to draw a new frame. So, put a glLoadIdentity() after you glClear function.
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity(); // <-- put it here
glBegin(GL_TRIANGLES);
...
You need to call glRotate before drawing the rotating object. And before that, you need to push the current model view matrix onto the stack with glPushMatrix, then pop it with glPopMatrix before drawing the rest of the windmill.
Once you have a more complex scene you might consider using a scene graph. Note that the matrix functions like glRotate are now deprecated. You might consider switching to e.g. glm as soon as possible.
Try this:
#include <GL/glut.h> // GLUT, include glu.h and gl.h
void Timer(int value)
{
glutPostRedisplay(); // Post re-paint request to activate display()
glutTimerFunc(16, Timer, 0); // next Timer call milliseconds later
}
float rate = 1.0f;
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'a':
rate=2;
break;
case 's':
rate=3;
break;
case 'd':
rate=4;
break;
case 'f':
rate=0;
break;
}
glutPostRedisplay();
}
float angle = 0.0f;
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black and opaque
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// base
glPushMatrix();
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(-0.4f, -0.6f);
glVertex2f(0.4f, -0.6f);
glEnd();
glPopMatrix();
// prop
glPushMatrix();
glRotatef(angle, 0.0f, 0.0f, 1.0f);
angle=angle+rate;
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(-0.4f, 0.2f);
glVertex2f(-0.2f, 0.4f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.4f, -0.2f);
glVertex2f(0.2f, -0.4f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(-0.4f, -0.2f);
glVertex2f(-0.2f, -0.4f);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.4f, 0.2f);
glVertex2f(0.2f, 0.4f);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv); // Initialize GLUTx
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize(320, 320); // Set the window's initial width & height
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutCreateWindow("Windmill"); // Create window with the given title
glutDisplayFunc(display);
glutTimerFunc(0, Timer, 0);
glutKeyboardFunc(keyboard);
glutMainLoop(); // Enter the event-processing loop
return 0;
}
I am trying to program in OpenGL.
so wrote a test program call t_gl1.cpp
I built it successfully with
$ g++ t_gl1.cpp -lglut -lGL -lGLU -o t_gl1
No any error.
However, if I try to run it, I got
freeglut (./t_gl1): ERROR: Internal error in function fgOpenWindow
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 4 (X_DestroyWindow)
Resource id in failed request: 0x0
Serial number of failed request: 26
Current serial number in output stream: 29
Does any one know what is going on?
Here is the code, tested on Windows and Mac, no problem. But can't get it run on Fedora nor Ubuntu
#include <iostream>
#include <stdlib.h>
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
using namespace std;
//Called when a key is pressed
void handleKeypress(unsigned char key, //The key that was pressed
int x, int y) { //The current mouse coordinates
switch (key) {
case 27: //Escape key
exit(0); //Exit the program
}
}
//Initializes 3D rendering
void initRendering() {
//Makes 3D drawing work when something is in front of something else
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL); //NEW OF THIS
glClearColor(0.7f,0.9f,1.0f,1.0f); //background, last number to be 1.0f
}
//Called when the window is resized
void handleResize(int w, int h) {
//Tell OpenGL how to convert from coordinates to pixel values
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective
//Set the camera perspective
glLoadIdentity(); //Reset the camera
gluPerspective(45.0, //The camera angle
(double)w / (double)h, //The width-to-height ratio
1.0, //The near z clipping coordinate
200.0); //The far z clipping coordinate
}
float _angle=30.0f; //kinda global variable
//Draws the 3D scene
void drawScene() {
//Clear information from last draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glTranslatef(0.0f,0.0f,-5.0f);
glPushMatrix();
glRotatef(_angle, 0.0f, 1.0f , 0.0f);
glColor3f(0.5f,0.0f,0.8f);
glBegin(GL_QUADS); //Begin quadrilateral coordinates
//Trapezoid
glVertex3f(-0.7f, -1.5f, 0.0f);
glVertex3f(0.7f, -1.5f, 0.0f);
glVertex3f(0.4f, -0.5f, 0.0f);
glVertex3f(-0.4f, -0.5f, 0.0f);
glEnd(); //End quadrilateral coordinates
glPopMatrix();
glPushMatrix(); //push
glRotatef(_angle, 1.0f, 0.0f, 0.0f);
glBegin(GL_TRIANGLES); //Begin triangle coordinates Begin Pentagon
glColor3f(1.0f,0.0f,0.0f);
//Pentagon
glVertex3f(0.5f, 0.5f, -0.0f);
glVertex3f(1.5f, 0.5f, -0.0f);
glVertex3f(0.5f, 1.0f, -0.0f);
glVertex3f(0.5f, 1.0f, -0.0f);
glVertex3f(1.5f, 0.5f, -0.0f);
glVertex3f(1.5f, 1.0f, -0.0f);
glVertex3f(0.5f, 1.0f, -0.0f);
glVertex3f(1.5f, 1.0f, -0.0f);
glVertex3f(1.0f, 1.5f, -0.0f);
glEnd(); //end Pentagon
glPopMatrix(); //pop
glPushMatrix();
glRotatef(_angle, -1.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
//Triangle
glVertex3f(-0.5f, 0.5f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, 1.5f, -0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(-1.5f, 0.5f, -0.0f);
glEnd(); //End triangle coordinates
glPopMatrix();
glutSwapBuffers(); //Send the 3D scene to the screen
}
void update(int value)
{
_angle+=2.0f;
if(_angle>360)
_angle-=360;
glutPostRedisplay();
glutTimerFunc(25,update,0);
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400); //Set the window size
//Create the window
glutCreateWindow("window");
initRendering(); //Initialize rendering
//Set handler functions for drawing, keypresses, and window resizes
glutDisplayFunc(drawScene); //display the "drwwScene" most important part, others are settings
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutTimerFunc(25,update,0); //add the timer function to make animation
glutMainLoop(); //Start the main loop. glutMainLoop doesn't return.
return 0; //This line is never reached
}
I aggreed with talonmies.
It was because of the Nvidia problem. I could't find a official way to install Nvidia's developer's driver on Fedora 15. So I used rpmfusion. The driver runs and I can run CUDA. Only GLX related stuff are messed up. However, it also messed up Gnome 3.
So I switched to Arch Linux. With a much clean start, install Nvida and install Xorg according to the ArchWiki. And then install Gnome. Amazingly, OpenGL works. I guess the driver in Arch repo is not the developer's driver. Maybe just for display driver. However, CUDA works.
I am glad with that. And hopefully this will be helpful to some one else who want to run CUDA and OpenGL on Linux.
Thanks,
Alfred
There is nothing wrong with the code. I can successfully compile and run it on a properly configured 64 bit linux system with NVIDIA release 280.13 drivers. You have a driver or X11 driver installation or configuration problem. There is no programming help required for this question.
Since you tagged this question cuda I'm going to assume you're running NVidia hardware.
Try installing some drivers.