I am trying to draw a line based on the mouse input coordinates.
The following code compiles, however, a line is not displayed from mouse input.
int coord_1[2]; //(x,y) of first point for line
int coord_2[2]; //(x,y) of second point for line
bool ready_1=false;
bool ready_2=false;
void drawLine()
{
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(coord_1[0], coord_1[1]);
glVertex2f(coord_2[0], coord_2[1]);
glEnd();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1,1,-1,1,-1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if(ready_1 && ready_2)
{
drawLine();
ready_1 = ready_2 = false;
}
glutSwapBuffers();
}
void mouse(int button, int state, int x, int y)
{
switch (button)
{
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) //button pressed down
{
//only do something on release
}
if (state == GLUT_UP) //released button
{
cout << "right button up" << endl;
}
break;
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) //button pressed down
{
coord_1[0]=x;
coord_2[1]=y;
cout << "first pos" << endl;
ready_1=true;
}
if (state == GLUT_UP) //released button
{
coord_2[0]=x;
coord_2[1]=y;
cout << "second pos" << endl;
ready_2=true;
}
break;
default:
break;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA|GLUT_MULTISAMPLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(512,512);
glutCreateWindow("Asn 1");
glutDisplayFunc(display);
glutIdleFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(processNormalKeys);
// GLUT main loop
glutMainLoop();
return(0);
}
Any help or pointers in the right direction?
You probably draw the line, but since you reset your drawing condition afterwards, your line gets hidden in the next draw step (which might be VERY quick).
Remove the ready_1 = ready_2 = false; and the line should stay visible.
Instead you can set ready_2 = false when you receive a left button down event.
Related
I am writing a program that will continuously draw a polygon until the user right-clicks. The user can only draw if and only if the user makes a selection in the menu, if the user does not make a selection in the menu, the program will not draw. Up to now, my program has successfully drawn a polygon with the mouse, but the problem is that when I right-click to complete, the program pops up the menu instead of completing the polygon. Now how can I right-click to be able to complete the polygon, here's my program:
const int MAX = 100;
float mouseX, mouseY, ListX[MAX], ListY[MAX];
int numPoints = 0, closed = 0, shape = 0;
void mouse(int button, int state, int x, int y)
{
mouseX = x;
mouseY = y;
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
if (closed || numPoints >= MAX - 1)
numPoints = 0;
closed = 0;
ListX[numPoints] = mouseX;
ListY[numPoints] = mouseY;
numPoints++;
}
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
closed = 1;
}
void motion(int x, int y)
{
mouseX = x;
mouseY = y;
glutPostRedisplay();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
if (shape == 1)
{
if (numPoints)
{
glBegin(GL_LINE_STRIP);
for (int i = 0; i < numPoints; ++i)
glVertex2f(ListX[i], ListY[i]);
if (closed)
glVertex2f(ListX[0], ListY[0]);
else
glVertex2f(mouseX, mouseY);
glEnd();
}
}
glFlush();
}
void menu(int choice)
{
switch (choice)
{
case 1:
shape = 1;
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow("");
gluOrtho2D(0, 640, 480, 0);
glutCreateMenu(menu);
glutAddMenuEntry("Polygon", 1);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutPassiveMotionFunc(motion);
glutMainLoop();
}
Edit: Thanks to genpfault, I finished the polygon by right-clicking but I don't know how to reattach it so I can re-open the menu.
...
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
if (shape == 1)
{
glutDetachMenu(GLUT_RIGHT_BUTTON); // Add this
...
}
glFlush();
}
void menu(int choice)
{
switch (choice)
{
case 1:
shape = 1;
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow("");
gluOrtho2D(0, 640, 480, 0);
glutCreateMenu(menu);
glutAddMenuEntry("Polygon", 1);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutPassiveMotionFunc(mouse_move);
glutMainLoop();
}
Capture the return-value from glutCreateMenu(), that's the handle for the new menu.
Detach the menu in the menu callback via glutDetachMenu() and set a bool indicating you're in "add points" mode.
If you're in "add points" mode and detect a right-click, set the current menu to the menu handle from #1 via glutSetMenu(), then re-attach the menu with glutAttachMenu(). Reset the "add points" bool to false.
All together:
#include <GL/glut.h>
const int MAX = 100;
float mouseX, mouseY, ListX[MAX], ListY[MAX];
int numPoints = 0, closed = 0, shape = 0;
int hMenu = 0;
bool addingPoints = false;
void mouse(int button, int state, int x, int y)
{
mouseX = x;
mouseY = y;
if( addingPoints )
{
if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
{
if (closed || numPoints >= MAX - 1)
numPoints = 0;
closed = 0;
ListX[numPoints] = mouseX;
ListY[numPoints] = mouseY;
numPoints++;
}
if( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN )
{
closed = 1;
addingPoints = false;
glutSetMenu(hMenu);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
}
}
void motion(int x, int y)
{
mouseX = x;
mouseY = y;
glutPostRedisplay();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 640, 480, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (shape == 1)
{
if (numPoints)
{
glBegin(GL_LINE_STRIP);
for (int i = 0; i < numPoints; ++i)
glVertex2f(ListX[i], ListY[i]);
if (closed)
glVertex2f(ListX[0], ListY[0]);
else
glVertex2f(mouseX, mouseY);
glEnd();
}
}
glutSwapBuffers();
}
void menu(int choice)
{
switch (choice)
{
case 1:
numPoints = 0;
shape = 1;
addingPoints = true;
glutDetachMenu(GLUT_RIGHT_BUTTON);
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutCreateWindow("");
hMenu = glutCreateMenu(menu);
glutSetMenu(hMenu);
glutAddMenuEntry("Polygon", 1);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutPassiveMotionFunc(motion);
glutMainLoop();
}
I'm trying to left click and drag any 3d Object and if i let go of it, it should stay in its new position, how would i achieve this? The 3d object is loaded from the draw function that i have in a header file.
Someone said i should be using glutMouseFunc or glutMotionFunc.
void MouseClickCallbackFunction(int button, int state, int x, int y)
{
if (state == GLUT_DOWN) {
if (button == GLUT_LEFT)
{
std::cout << "Left " << x << " " << y <<std::endl;
leftClick.x = x;
leftClick.y = y;
}
else if (button == GLUT_RIGHT_BUTTON) {
std::cout << "Right " << x << " " << y << std::endl;
rightClick.x = x;
rightClick.y = y;
}
}
theGame->mouseClicked(button, state, x, y);
glutPostRedisplay();
}
/* function MouseMotionCallbackFunction()
* Description:
* - this is called when the mouse is clicked and moves
*/
void MouseMotionCallbackFunction(int x, int y)
{
theGame->mouseMoved(x, y);
glutPostRedisplay();
}
int main(int argc, char **argv)
{
/* initialize the window and OpenGL properly */
glutInit(&argc, argv);
glutInitContextVersion(4, 2);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("OpenGL Framework");
glewExperimental = true;
if (glewInit() != GLEW_OK)
{
std::cout << "GLEW could not be initialized. \n";
system("pause");
return 0;
}
//glewInit();
std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;
/* set up our function callbacks */
glutDisplayFunc(DisplayCallbackFunction);
glutKeyboardFunc(KeyboardCallbackFunction);
glutKeyboardUpFunc(KeyboardUpCallbackFunction);
glutMouseFunc(MouseClickCallbackFunction);
glutMotionFunc(MouseMotionCallbackFunction);
glutTimerFunc(1, TimerCallbackFunction, 0);
/* init the game */
theGame = new Game();
theGame->initializeGame();
/* start the game */
glutMainLoop();
return 0;
}
Here is the Draw fucntion with the object
void Game::draw()
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
PassThrough.Bind();
PassThrough.SendUniformMat4("uModel", MonkeyTransform.data, false);
PassThrough.SendUniformMat4("uView", CameraTransform.GetInverse().data, false);
PassThrough.SendUniformMat4("uProj", CameraProjection.data, false);
PassThrough.SendUniform("uTex", 0);
PassThrough.SendUniform("LightPosition", CameraTransform.GetInverse() * vec4(4.0f,0.0f,0.0f,1.0f));
PassThrough.SendUniform("LightAmbient", vec3(0.15f, 0.15f, 0.15f));
PassThrough.SendUniform("LightDiffuse", vec3(0.7f,0.1f,0.2f));
PassThrough.SendUniform("LightSpecular", vec3(0.8f,0.1f,0.1f));
PassThrough.SendUniform("LightSpecularExponent", 50.0f);
PassThrough.SendUniform("Attenuation_Constant", 1.0f);
PassThrough.SendUniform("Attenuation_Linear", 0.1f);
PassThrough.SendUniform("Attenuation_Quadratic", 0.01f);
glBindVertexArray(Monkey.VAO);
glDrawArrays(GL_TRIANGLES, 0, Monkey.GetNumVerticies());
glBindVertexArray(0);
PassThrough.unBind();
glutSwapBuffers();
}
The concept is called mouse picking. A method to achieve this is ray casting. Essentially what you want to do is map the mouse coordinates to a region in your scene. In your case you want to check if the position is within the monkey. Then it is as simple as handling the mouse up, down, and move events.
Mouse down: check if object is being picked. If it is, great- maybe highlight it or something. Store ref to object picked; store position of mouse at beginning of pick (pos)
Mouse move: is mouse down? Is picked object ref? Update object position based on delta between pos and coord in mouse move event
Mouse up: clear picked obj ref, position
This link may be of interest http://antongerdelan.net/opengl/raycasting.html
I need help in understanding how to scale my coordinates. The instruction says, modify the code to move the triangle to the mouse click position. Can someone explain how this is done?
Here is the source code I'm working with:
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <stddef.h>
#include <iostream>
// values controlled by fast keys
float g_angle = 0.0f;
float g_xoffset = 0.0f;
float g_yoffset = 0.0f;
int x;
int y;
// increments
const float g_angle_step = 32.0f; // degrees
const float g_offset_step = 32.0f; // world coord units
// last cursor click
int g_cursor_x = 0;
int g_cursor_y = 0;
void draw_triangle()
{
// in model cooridnates centred at (0,0)
static float vertex[3][2] =
{
{-1.0f, -1.0f},
{1.0f, -1.0f},
{0.0f, 1.0f}
};
glBegin(GL_LINE_LOOP);
for (size_t i=0;i<3;i++)
glVertex2fv(vertex[i]);
glEnd();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 1.0f, 1.0f);
glLineWidth(2.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(500.0f+g_xoffset, 500.0f+g_yoffset, 0.0f);
glScalef(100.0f, 100.0f, 1.0f);
glRotatef(g_angle, 0.0f, 0.0f, 1.0f);
draw_triangle();
glPopMatrix(); // done with stack
glutSwapBuffers();
}
// handles mouse click events
// button will say which button is presed, e.g. GLUT_LEFT_BUTTON, GLUT_RIGHT_BUTTON
// state will say if the button is GLUT_UP or GLUT_DOWN
// x and y are the poitner position
void mouse_click(int button, int state, int x, int y)
{
if (button==GLUT_LEFT_BUTTON)
{
std::cerr << "\t left mouse button pressed!" << std::endl;
if (state==GLUT_UP)
{
std::cerr << "\t button released...click finished" << std::endl;
g_cursor_x = x;
g_cursor_y = y;
std::cerr << "\t cursor at (" << g_cursor_x << ", " <<
g_cursor_y << ")" << std::endl;
}
}
else
if (button==GLUT_RIGHT_BUTTON)
{
std::cerr << "\t right mouse button pressed!" << std::endl;
}
// Here is my attempt:
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
float x_min = (-x+500)/512;
float x_max = (x-500)/512;
float y_min = (-y+500)/512;
float y_max = (y-500)/512;
gluOrtho2D(x_min, x_max, y_min, y_max);
//glTranslatef(x/512, 1-y/512, 0.0f);
std::cerr << x << ", " << y << std::endl;
}
glutPostRedisplay();
}
void mouse_motion(int x, int y)
{
std::cerr << "\t mouse is at (" << x << ", " << y << ")" << std::endl;
glutPostRedisplay();
}
// will get which key was pressed and x and y positions if required
void keyboard(unsigned char key, int, int)
{
std::cerr << "\t you pressed the " << key << " key" << std::endl;
switch (key)
{
case 'q': exit(1); // quit!
// clockwise rotate
case 'r': g_angle += g_angle_step; break;
}
glutPostRedisplay(); // force a redraw
}
// any special key pressed like arrow keys
void special(int key, int, int)
{
// handle special keys
switch (key)
{
case GLUT_KEY_LEFT: g_xoffset -= g_offset_step; break;
case GLUT_KEY_RIGHT: g_xoffset += g_offset_step; break;
case GLUT_KEY_UP: g_yoffset += g_offset_step; break;
case GLUT_KEY_DOWN: g_yoffset -= g_offset_step; break;
}
glutPostRedisplay(); // force a redraw
}
void init()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 1000, 0, 1000);
glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
g_cursor_x = g_cursor_y = 500; // middle of window
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(512, 512);
glutInitWindowPosition(50, 50);
glutCreateWindow("Mouse Test");
glutDisplayFunc(display);
// handlers for keyboard input
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
// mouse event handlers
glutMouseFunc(mouse_click);
glutPassiveMotionFunc(mouse_motion);
init();
glutMainLoop();
return 0;
}
This should solve your issue.replace your code(your attempt) with the code below.
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
g_xoffset = x;
g_yoffset = 1000-y;
} glutPostRedisplay();
I have this code:
#include <iostream>
#include <GL/glut.h>
using namespace std;
bool* Keys = new bool[256];
void keyboardDown(unsigned char key, int x, int y)
{
Keys[key] = true;
}
void keyboardUp(unsigned char key, int x, int y)
{
Keys[key] = false;
}
void reshape(int width, int height)
{
GLfloat fieldOfView = 90.0f;
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fieldOfView, (GLfloat)width / (GLfloat)height, 0.1, 500.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void draw()
{
if (Keys['e'])
cout << "e" << endl;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
glColor3f(0.1, 0.1, 0.1); glVertex3f(1.0, 1.0, -1.0);
glColor3f(0.1, 0.9, 0.1); glVertex3f(1.0, -1.0, -1.0);
glColor3f(0.9, 0.1, 0.1); glVertex3f(-1.0, -1.0, -1.0);
glColor3f(0.1, 0.1, 0.9); glVertex3f(-1.0, 1.0, -1.0);
glEnd();
glFlush();
glutSwapBuffers();
}
void initGL(int width, int height)
{
reshape(width, height);
glClearColor(0.1f, 0.5f, 0.7f, 1.0f);
glClearDepth(1.0f);
glOrtho(0, 1, 0, 1, 1, 10);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
}
/* initialize GLUT settings, register callbacks, enter main loop */
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800, 800);
glutInitWindowPosition(100, 100);
glutCreateWindow("Perspective's GLUT Template");
glutKeyboardFunc(keyboardDown);
glutKeyboardUpFunc(keyboardUp);
glutSpecialFunc(keyboardSpecialDown);
glutSpecialUpFunc(keyboardSpecialUp);
glutReshapeFunc(reshape);
glutDisplayFunc(draw);
glutIgnoreKeyRepeat(true); // ignore keys held down
initGL(800, 600);
glutMainLoop();
return 0;
}
When I start the program, it writes 'e' only when I press on the mouse. I can't find the problem. Why does it only work when the mouse is held down?
You dont have mouse functions in your code, thats why it is not working. Insert from here : http://www.zeuscmd.com/tutorials/glut/03-MouseInput.php
#include <iostream>
#include <gl/glut.h>
using namespace std;
bool lbuttonDown = false;
bool init()
{
return true;
}
void display()
{
}
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_RIGHT_BUTTON)
{
if (state == GLUT_DOWN)
cout << "Right button pressed"
<< endl;
else
cout << "Right button lifted "
<< "at (" << x << "," << y
<< ")" << endl;
}
else if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
lbuttonDown = true;
else
lbuttonDown = false;
}
}
void motion(int x, int y)
{
if (lbuttonDown)
cout << "Mouse dragged with left button at "
<< "(" << x << "," << y << ")" << endl;
}
void motionPassive(int x, int y)
{
cout << "Mouse moved at "
<< "(" << x << "," << y << ")" << endl;
}
void entry(int state)
{
if (state == GLUT_ENTERED)
cout << "Mouse Entered" << endl;
else
cout << "Mouse Left" << endl;
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition(200, 200);
glutInitWindowSize(200, 200);
glutCreateWindow("03 - Mouse Input");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutPassiveMotionFunc(motionPassive);
glutEntryFunc(entry);
if (!init())
return 1;
glutMainLoop();
return 0;
}
I had the same problem [using freeglut] and calling 'draw()' [or whatever display callback you use] right after glutPostRedisplay() in the key callback function forced it to do the redraw. I actually don't know why it behaves like this. After data is changed by keyboard input and the key callback returned, a redraw is expected but not executed.
I'm trying to make it so that when I press W, A, S, or D, it moves a bunch of lines around on the screen. I read in all the lines from a file and display them, and that works fine.
So I have a keyboard function that has a switch statement that increments an X and Y variable which I use in glTranslate inside of my display function, but my lines don't move. Could anyone help me out with this?
#include <GL/glut.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
int height = 640, width = 640;
int X = 0, Y = 0;
void drawPolyLineFile(char * fileName) {
std::fstream inStream;
inStream.open(fileName, std::ios::in);
if (inStream.fail()) {
std::cerr<< "Error opening file";
return;
}
glClear(GL_COLOR_BUFFER_BIT);
GLint numpolys, numLines, x, y;
inStream >> numpolys;
for ( int j =0; j < numpolys; j++) {
inStream >> numLines;
glBegin(GL_LINE_STRIP);
for (int i = 0; i < numLines; i++) {
inStream >> x >> y;
glVertex2i(x, y);
}
glEnd();
}
//glutSwapBuffers();
inStream.close();
}
void display(void)
{
/* clear all pixels */
glClear (GL_COLOR_BUFFER_BIT);
glTranslatef(X, Y, 0);
drawPolyLineFile("dino.dat");
/* don't wait!
* start processing buffered OpenGL routines
*/
glutSwapBuffers();
}
void init (void)
{
/* select clearing color */
glClearColor (0.0, 0.0, 0.0, 0.0);
/* initialize viewing values */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 640.0, 0.0, 640.0, -1.0, 1.0);
}
void keyboard(unsigned char key, int x, int y) {
float speed = 5.0f;
switch ( key ) {
case 'a':
X -= speed;
std::cerr<< X << std::endl;
break;
case 'd':
X += speed;
std::cerr<< X << std::endl;
break;
case 's':
Y -= speed;
std::cerr<< Y << std::endl;
break;
case 'w':
Y += speed;
std::cerr<< Y << std::endl;
break;
default:
break;
}
}
/*
* Declare initial window size, position, and display mode
* (single buffer and RGBA). Open window with "hello"
* in its title bar. Call initialization routines.
* Register callback function to display graphics.
* Enter main loop and process events.
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (640, 640);
glutInitWindowPosition (100, 100);
glutCreateWindow ("hello");
init ();
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
I haven't read too carefully, but you're most likely missing a
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
before the call to glTranslate. glTranslate composes a translation. From your code it seems like you're expecting it to set a translation.
You'll probably also want to avoid reading from disk at every frame. Load your model into a data structure at startup and render from that instead.
You were missing a glutPostRedisplay in your keyboard handler. Without that no redraw of the window would have been initiated. Settings display as idle func does the trick as well, but works differently: The window is constantly redrawn, almost all CPU time used up for drawing. Your code also had some other fallacies. I fixed that.
#include <GL/glut.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <stdexcept>
int X = 0, Y = 0;
void drawPolyLineFile(char * fileName) throw(std::runtime_error)
{
std::fstream inStream;
inStream.open(fileName, std::ios::in);
if (inStream.fail()) {
throw std::runtime_error("Error opening file")
}
GLint numpolys, numLines, x, y;
inStream >> numpolys;
for ( int j =0; j < numpolys; j++) {
inStream >> numLines;
glBegin(GL_LINE_STRIP);
for (int i = 0; i < numLines; i++) {
inStream >> x >> y;
glVertex2i(x, y);
}
glEnd();
}
inStream.close();
}
void display(void)
{
int window_width, window_height;
window_width = glutGet(WINDOW_WIDTH);
window_height = glutGet(WINDOW_HEIGHT);
glViewport(0, 0, window_width, window_height);
/* clear all pixels */
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
/* always set all projection parameters a new
* each rendering pass
*/
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, window_width, 0.0, window_height, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(X, Y, 0);
drawPolyLineFile("dino.dat");
/*
* SwapBuffers will flush the OpenGL queue indeed,
* but more importantly it brings the content from
* the back buffer to the front
*/
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y) {
float speed = 5.0f;
switch ( key ) {
case 'a':
X -= speed;
std::cerr<< X << std::endl;
break;
case 'd':
X += speed;
std::cerr<< X << std::endl;
break;
case 's':
Y -= speed;
std::cerr<< Y << std::endl;
break;
case 'w':
Y += speed;
std::cerr<< Y << std::endl;
break;
default:
break;
}
glutPostRedisplay();
}
/*
* Declare initial window size, position, and display mode
* (single buffer and RGBA). Open window with "hello"
* in its title bar. Call initialization routines.
* Register callback function to display graphics.
* Enter main loop and process events.
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (640, 640);
glutInitWindowPosition (100, 100);
glutCreateWindow ("hello");
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
try {
glutMainLoop();
} catch (std::runtime_error &err) {
std::cerr << err.what();
}
return 0;
}