Related
I have program in which the object (a triangle) follows the mouse as it moves around and rotates to the direction its moving. What do I have to do to make it so the object stays still, until I click it, drag it to a position and once I release the mouse, it starts to move to that position?
#include <GL/glut.h>
#include <math.h>
# define ANIMATION_STEP (1000/300)
# define PI 3.1415926535897932
struct Globals {
centre_x, centre_y, rotate;
float length;
float mouse_x, mouse_y, speed;
int animating;
} globals;
void init(void){
// Starting position of the triangle
globals.centre_x = 100;
globals.centre_y = 100;
globals.rotate = 0.0;
globals.mouse_x = 300.0;
globals.mouse_y = 300.0;
// Animation speed in pixels per second
globals.speed = 300.0;
// size of the triangle
globals.length = 27;
globals.animating = 1;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 1000.0, 0.0, 700.0);
}
void triangle(void){
glBegin(GL_POLYGON);
glVertex2f(0.5, 0.0);
glVertex2f(-0.5, -0.5);
glVertex2f(-0.5, 0.5);
glEnd();
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(globals.mouse_x, globals.mouse_y, 0.0);
glRotatef(globals.rotate, 0.0, 0.0, 1.0);
glScalef(globals.length, globals.length, 1.0);
triangle();
glFlush();
glutSwapBuffers();
}
float limit(float x, float min, float max){
if (x < min) {
x = min;
}
if (x > max) {
x = max;
}
return x;
}
void timer(int v){
// Computing elapsed time for smooth animation.
int time = glutGet(GLUT_ELAPSED_TIME);
float angle;
glutTimerFunc(ANIMATION_STEP, timer, time);
if (globals.animating) {
int delta_t = time - v;
float delta_x, delta_y, length, step_size;
// Compute vector from current location to mouse
delta_x = globals.mouse_x - globals.centre_x;
delta_y = globals.mouse_y - globals.centre_y;
// Compute length of the vector
length = sqrt (delta_x*delta_x + delta_y*delta_y);
// If the triangle is close to the mouse, then no motion is required.
step_size = globals.speed * delta_t / 1000.0;
if (length > step_size * 0.55) {
delta_x = delta_x / length;
delta_y = delta_y / length;
globals.centre_x += delta_x * step_size;
globals.centre_y += delta_y * step_size;
angle = atan2(delta_y, delta_x);
globals.rotate = angle * 180.0 / PI;
// Keep the triangle inside the world window.
globals.centre_x = limit(globals.centre_x, 0.0 + globals.length/2, 1000.0 - globals.length/2);
globals.centre_y = limit(globals.centre_y, 0.0 + globals.length/2, 700.0 - globals.length/2);
}
glutPostRedisplay();
}
}
void mousemotion(int x, int yc){
globals.mouse_x = x;
globals.mouse_y = 700 - yc;
glutPostRedisplay();
}
main(int argc, char** argv){
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1000, 700);
glutInitWindowPosition(10, 10);
glutDisplayFunc(display);
glutTimerFunc(ANIMATION_STEP, timer, 0);
glutPassiveMotionFunc(mousemotion);
init();
glutMainLoop();
return 0;
}
I have investigated processMouse() where if state == GLUT_DOWN then it records the current position and mouse press cordinates, but the best ive been able to get is that it immediately teleports to the mouse click. Can someone please explain what I would need to do to click on it, drag, release, then move to position?
in opengl, how to change mouse...
You don't. Mouse does not exist in OpenGL. Maybe you should change the question to "How to process mouse events in windows/GLUT/SDL/whatever-framework?" for which there are dozens of duplicates.
I am making a 3d project in OpenGL which contain a ground (drawn as line loops). The issue I have is when the project starts only a single line is drawn as shown in the next image:
When I resize or maximize the window then the actual ground gets displayed like this:
Any idea how to resolve this issue? I'm a beginner in OpenGL programming.
Here is the code :
void drawHook(void);
void timer(int);
void drawFlorr();
float L = 100;
const int screenWidth = 1000; // width of screen window in pixels
const int screenHeight = 1000; // height of screen window in pixels
float ww = 800;
float wh = 800;
float f = 520, n = 10.0;
static GLdouble ort1[] = { -200, 200, -33, 140 };
static GLdouble viewer[] = { 525, 25, -180 };
static GLdouble objec[] = { 525.0, 25, -350 };
float x, y = 0.0, z, z1;
float xmax = screenWidth - 200.0;
float zmax = screenWidth - 200.0;
float xmin, zmin;
float step = 5.0;
float fov = 80;
void myInit(void)
{
glClearColor(0.0,0.0,0.0,0.0); // background color is white
glPointSize(2.0); // a 'dot' is 2 by 2 pixels
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, screenWidth, 0.0, screenHeight);//dino window
glViewport(0, 0, screenWidth, screenHeight);
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(viewer[0], viewer[1], viewer[2], objec[0], objec[1], objec[2], 0, 1, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, 1.333, n, f);
glPointSize(2.0);
glMatrixMode(GL_MODELVIEW);
drawFlorr();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // set display mode
glutInitWindowSize(screenWidth, screenHeight); // set window size
glutInitWindowPosition(10, 10); // set window position on screen
glutCreateWindow("Dino Line Drawing"); // open the screen window
glutDisplayFunc(myDisplay); // register redraw function
myInit();
//glutTimerFunc(1,timer,1);
glutMainLoop(); // go into a perpetual loop
return 1;
}
void drawFlorr()
{
xmin = -100;
zmin = -100;
for (x = xmin; x < xmax; x += step)
{
for (z = zmin; z < zmax; z += step)
{
z1 = -z;
glBegin(GL_LINE_LOOP);
glVertex3f(x, y, z1);
glVertex3f(x, y, z1-step+1.0);
glVertex3f(x + step - 1.0, y, z1 - step + 1.0);
glVertex3f(x+step-1.0, y, z1);
glEnd();
}
}
}
Your code is broken in many ways:
Your myDisplay function uses whatever the current matrix mode is to set the view matrix on.
Initially, you leave the matrix mode as GL_PROJECTION in myInit()
These two together mean that for the first frame, you just use identity as MODELVIEW matrix, and just overwrite the projection matrix twice. After a resize, the frame ais drawn again, and your code does waht you probably intented to do.
However, there is more:
You do not have any resize handler, so your viewport will not change when you resize the window.
You are setting an ortho matrix initailly for the projection, although you are not planning to use it at all.
and, the most import point:
All of your code depends on deprecated functionality which is not even available in modern OpenGL at all. You should really not use this in 2016, but learn modern OpenGL instead (with "modern" meaning "only a decade old" here).
I am attempting to translate one circle independent of a separate, stationary circle, utilizing glTranslatef();. However, with my current, full code, each of my circles remains immobile. To investigate why this may be so, I have researched several answers, each comparable to those found here and here. Additionally, I read up on glLoadIdentity as well as the differences between GL_MODELVIEW and GL_PROJECTION, just to see if their details would offer any further clarification. I've also consulted the OpenGL API for the proper definitions of each of the above.
In the style of these solutions, I produced the following do...while loop:
do{
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, fb_width, fb_height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(0,1,0);
drawCircle(1280 * 0.50, 720 * 0.25,e[2]);
glPopMatrix();
glPushMatrix();
glTranslatef(0,0,0);
drawTarget(1280 * 0.50, 720 * 0.75,50);
glPopMatrix();
glfwSwapBuffers(w);
glfwPollEvents();
}
while (!glfwWindowShouldClose(w));
In this snippet, the drawCircle drawing remains stationary, but I would like for it to follow the written glTranslatef(0,1,0) instead. Is the stationary nature of the circle due to misplaced a glMatrixMode or glLoadIdentity, or perhaps due to the fact that they are being called within the do...while loop and the proper matrix is never really being utilized? I would appreciate any guidance you may have as to why the aforementioned and accepted answers are not functioning quite as well within my program.
For the sake of full transparency, here is the entirety of my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <math.h>
#include <stddef.h>
#include <stdbool.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLFWwindow *w;
int fb_width, fb_height;
static void error(int error, const char *desc)
{
fputs(desc, stderr);
}
static void key_callback(GLFWwindow *w, int key, int scancode, int action, int mods)
{
if ((key == GLFW_KEY_ESCAPE || key == GLFW_KEY_Q) && action == GLFW_PRESS)
glfwSetWindowShouldClose(w, GL_TRUE);
}
void drawCircle(float cx, float cy, float radius)
{
float num_segments = 360;
float theta = 2 * 3.1415926 / num_segments;
float c = cosf(theta);//precalculate the sine and cosine
float s = sinf(theta);
float t;
float x = radius;//we start at angle = 0
float y = 0;
glBegin(GL_TRIANGLE_FAN);
glColor3f(1, 0, 1);
for(int ii = 0; ii < num_segments; ii++)
{
glVertex2f(x + cx, y + cy);//output vertex
//apply the rotation matrix
t = x;
x = c * x - s * y;
y = s * t + c * y;
}
glEnd();
}
void drawTarget(float cx, float cy, float radius)
{
float num_segments = 360;
float theta = 2 * 3.1415926 / num_segments;
float c = cosf(theta);//precalculate the sine and cosine
float s = sinf(theta);
float t;
float x = radius;//we start at angle = 0
float y = 0;
glBegin(GL_LINE_LOOP);
glColor3f(1, 1, 1);
for(int ii = 0; ii < num_segments; ii++)
{
glVertex2f(x + cx, y + cy);//output vertex
//apply the rotation matrix
t = x;
x = c * x - s * y;
y = s * t + c * y;
}
glEnd();
}
int main(void)
{
int i;
float e[3] = {140,120,100};
float m[3] = {90,80,70};
float h[3] = {60,50,40};
glfwSetErrorCallback(error);
if (!glfwInit())
exit(EXIT_FAILURE);
w = glfwCreateWindow(1280, 720, "AxTest", NULL, NULL);
if (!w)
{
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(w);
glfwSetKeyCallback(w, key_callback);
glfwGetFramebufferSize(w, &fb_width, &fb_height);
do{
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, fb_width, fb_height, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(0,1,0);
drawCircle(1280 * 0.50, 720 * 0.25,e[2]);
glPopMatrix();
glPushMatrix();
glTranslatef(0,0,0);
drawTarget(1280 * 0.50, 720 * 0.75,50);
glPopMatrix();
glfwSwapBuffers(w);
glfwPollEvents();
}
while (!glfwWindowShouldClose(w));
glfwDestroyWindow(w);
glfwTerminate();
exit(EXIT_SUCCESS);
return 0;
}
The values for the vertex positions with which you draw your circles are in the order of hundreds (likely, because you want to address pixels as indicated by the values for the projection matrix). But glTranslates sees only a small number, so the shift is miniscule (one pixel) and hence you think nothing did happen. If you rewrite your code so that you don't specify the circle/target center by explicit modification of the vertex position offset it'd be clearer.
void drawCircle(float radius)
{
/* ... */
for(int ii = 0; ii < num_segments; ii++)
{
glVertex2f(x, y); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/* ... */
}
void drawTarget(float radius)
{
/* ... */
for(int ii = 0; ii < num_segments; ii++)
{
glVertex2f(x, y); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/* ... */
}
int main(void)
{
/* ... */
glPushMatrix();
glTranslatef(1280*0.50, 720*0.25, 0);
drawCircle(e[2]);
glPopMatrix();
glPushMatrix();
glTranslatef(1280 * 0.50, 720 * 0.25, 0);
drawTarget(50);
glPopMatrix();
/* ... */
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, fb_width, fb_height, 0, 0, 1);
You don't have to make the projection matrix at every loop, put it before the loop.
Then the error you have is surely due to :
glMatrixMode(GL_MODELVIEW);
// it miss glLoadIdentity() here
glPushMatrix();
glTranslatef(0,1,0);
I am trying to move a camera in a 3d space. So far I have had success in moving and rotating the camera using this code:
void specialKeyHandler(int key, int x, int y) {
float fraction = 0.05f;
switch (key) {
case GLUT_KEY_LEFT :
camAngle -= 0.01f;
lX = sin(camAngle);
lZ = -cos(camAngle);
break;
case GLUT_KEY_RIGHT :
camAngle += 0.01f;
lX = sin(camAngle);
lZ = -cos(camAngle);
break;
case GLUT_KEY_UP :
iX += lX * fraction;
iZ += lZ * fraction;
break;
case GLUT_KEY_DOWN :
iX -= lX * fraction;
iZ -= lZ * fraction;
break;
default:
break;
}
}
Of course I have these variables defined. lX, lY, lZ are for LookAt variables and iX, iY and iZ are for camera's eye.
The camera moves as required, but now I want to attach an object on the "camera's eye" which shall move with the camera. Just like a Weapon in a FPS game.
This is what I have for that:
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawEarth();
drawWalls();
glColor3f(255,0,0);
glPushMatrix();
glTranslatef(iX+0.05,iY, iZ-0.05);
glRotatef(camAngle, 0,1,0);
glutWireCone(0.005,0.1,20,20); // object to go with camera
glPopMatrix();
glutSwapBuffers();
}
This code currently does bind the object with the camera while moving up and down. But when I rotate the camera by pressing left and right keys, object stays there and camera moves on its own..
Any solution?
Here's the full opengl code, if anyone wants to run:
#include <GL/glut.h>
#include<iostream>
#include<math.h>
using namespace std;
void display(void);
void reshape(int, int);
void mouseHandler(int button, int state, int x, int y);
void keyBoardHandler(unsigned char c, int x, int y);
void specialKeyHandler(int key, int x, int y);
float angle = 0;
bool camDefault = true, perspectiveOrtho = true;
float iX =0 , iY = -0.8, iZ = 0, lX = 0, lY = -0.8, lZ = -1, uX = 0, uY = 1, uZ = 0;
float camAngle = 0;
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(512, 512);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow("FPS Camera");
glutDisplayFunc(display);
glutIdleFunc(display);
//look from negative x axis towards origin. with y on top
glutReshapeFunc(reshape);
glEnable(GL_DEPTH_TEST);
glClearColor(0,0,0,1);
glutMouseFunc(mouseHandler);
glutKeyboardFunc(keyBoardHandler);
glutSpecialFunc(specialKeyHandler);
glutMainLoop();
return 0;
}
void drawEarth() {
glColor3f(0,255,0);
glBegin(GL_QUADS);
glVertex3f(-1,-1,-1);
glVertex3f(-1,-1,1);
glVertex3f(1,-1,1);
glVertex3f(1,-1,-1);
glEnd();
}
void drawWalls() {
glColor3f(0,0,255);
glBegin(GL_QUADS);
glVertex3f(-1,-1,-1);
glVertex3f(-1,-1,1);
glVertex3f(-1,1,1);
glVertex3f(-1,1,-1);
glEnd();
glColor3f(0,234,255);
glBegin(GL_QUADS);
glVertex3f(-1,-1,1);
glVertex3f(-1,1,1);
glVertex3f(1,1,1);
glVertex3f(1,-1,1);
glEnd();
}
float unitVector(float dir, float x, float y, float z) {
float sumSqr = pow(x,2) + pow(y,2) + pow(z,2);
return dir / (sqrt(sumSqr));
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawEarth();
drawWalls();
glColor3f(255,0,0);
glPushMatrix();
glTranslatef(iX+0.05,iY, iZ-0.05);
glRotatef(camAngle, 0,1,0);
glutWireCone(0.005,0.1,20,20);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int width, int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90,1, 0.001, 1000);
gluLookAt(iX,iY,iZ,iX+lX,lY,iZ+lZ,uX,uY,uZ);
glMatrixMode(GL_MODELVIEW);
}
void updateLookAt() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (90, 1 ,0.001, 1000);
gluLookAt(iX,iY,iZ,iX+lX,lY,iZ+lZ,uX,uY,uZ);
glMatrixMode(GL_MODELVIEW);
}
void keyBoardHandler(unsigned char c, int x, int y) {
switch(c) {
case 'f': // go left
iX-=0.01;
lX -= 0.01;
cout<<endl<<"S pressed";
break;
case 's': // go right
iX += 0.01;
lX += 0.01;
break;
case 'e': // go up
iZ += 0.01;
lZ += 0.01;
break;
case 'd': // go down
iZ -= 0.01;
lZ -= 0.01;
break;
default:
break;
}
updateLookAt();
}
void mouseHandler(int button, int state, int x, int y) {
if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
if(camDefault) {
glLoadIdentity();
gluLookAt(-1,0,0,0.0,0.0,0.0,0.0,1,0);
camDefault = false;
}
else {
glLoadIdentity();
gluLookAt(0,0,0,0.0,0.0,0.0,0.0,1,0);
camDefault = true;
}
}
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(perspectiveOrtho) {
gluPerspective (90, 1 ,0.00001, 1000);
perspectiveOrtho = false;
}
else {
glOrtho(-1,1,-1,1, -1,100);
perspectiveOrtho = true;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if(camDefault)
gluLookAt(0,0,1,0.0,0.0,0.0,0.0,1,0);
else
gluLookAt(-1,0,0,0.0,0.0,0.0,0.0,1,0);
}
}
void specialKeyHandler(int key, int x, int y) {
float fraction = 0.05f;
switch (key) {
case GLUT_KEY_LEFT :
camAngle -= 0.01f;
lX = sin(camAngle);
lZ = -cos(camAngle);
break;
case GLUT_KEY_RIGHT :
camAngle += 0.01f;
lX = sin(camAngle);
lZ = -cos(camAngle);
break;
case GLUT_KEY_UP :
iX += lX * fraction;
iZ += lZ * fraction;
break;
case GLUT_KEY_DOWN :
iX -= lX * fraction;
iZ -= lZ * fraction;
break;
default:
break;
}
updateLookAt();
}
You have two problems.
The first problem is on your coordinates system.
When you apply :
glTranslatef(iX+0.05,iY, iZ-0.05);
You place the object at the camera position, and add an offset to see him. But this is in the world coordinates system. So when you rotate the camera, the object doesn't move cause it doesn't follow the camera's coordinates system.
You need to translate to the camera center, rotate the camera, then add the offset.
The second problem is on the rotation. Your "camAngle" variable is in radian, cause you use it with cos() and sin(). But in OpenGL, glRotate take the angle as a degree value. You need to convert this angle in angle : angle *= 180/PI. (180/PI ~= 57.2957795)
Here the corrected display function :
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(255,0,0);
glPushMatrix();
glTranslatef(iX,iY,iZ); // Translation to the camera center
glRotatef(-camAngle * 57.2957795, 0,1,0); // Rotate to correspond to the camera
glTranslatef(0.05,0,-0.05); // Offset to draw the object
glutWireCone(0.005,0.1,20,20);
glPopMatrix();
drawEarth();
drawWalls();
glutSwapBuffers();
}
I want to move triangle on plane.How will i do it.I am using opengl "glut" and also i want to keep co-ordinate position of triangle.first time it will start at point (0,0,-6) and then when i will press "a" this will move left and when i will press "d" this will move "right".I know the keyoperation definition in opengl of "w" and "s".But my main concern is with movment and knwoing of co-ordinate points.
Thankie
Use global variables to store your programs state. One of these states is the triangle position. Modify this variable in the keyboard handler, then call glutPostRedisplay. In the display function draw the scene according to the program's state.
Important hints: OpenGL is "merely" a sophisticated rasterizer API, which means it "lives for the moment", i.e. you just draw triangles with it, and after you sent the rendering command and they've been processed OpenGL has no "persistency" about the sent geometry and the only trace left are the changes in the framebuffer.
If what you're looking for is more along the lines of "I want to describe a scene consisting of geometric objects and those shall interact through some black box mechanism" you're looking for a so called scene graph, which OpenGL is not (but many scene graphs use OpenGL as a backend).
EDIT: Full example source code
#include <GL/gl.h>
#include <GL/glut.h>
#define ORTHO_SCALE 10.
GLfloat triangle_vertices[] = {
-0.5, 0.0,
0.5, 0.0,
0.0, 1.0
};
struct {
struct {
struct {
GLfloat x, y;
} pos;
GLfloat rot;
} triangle;
} sceneinfo;
void display(void);
void keyboard(unsigned char key, int x, int y);
void special(int key, int x, int y);
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("simple triangle test");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutMainLoop();
return 0;
}
void display(void)
{
GLuint win_width, win_height;
GLfloat win_aspect;
win_width = glutGet(GLUT_WINDOW_WIDTH);
win_height = glutGet(GLUT_WINDOW_HEIGHT);
win_aspect = (float)win_width/(float)win_height;
glViewport(0, 0, win_width, win_height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-win_aspect * ORTHO_SCALE,
win_aspect * ORTHO_SCALE,
-ORTHO_SCALE,
ORTHO_SCALE,
-1., 1.);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(sceneinfo.triangle.pos.x, sceneinfo.triangle.pos.y, 0.);
glRotatef(sceneinfo.triangle.rot, 0, 0, 1.);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, triangle_vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glPopMatrix();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y)
{
switch(key) {
case '+':
sceneinfo.triangle.rot += 2.;
break;
case '-':
sceneinfo.triangle.rot -= 2.;
break;
}
glutPostRedisplay();
}
void special(int key, int x, int y)
{
switch(key) {
case GLUT_KEY_LEFT:
sceneinfo.triangle.pos.x -= 0.2;
break;
case GLUT_KEY_RIGHT:
sceneinfo.triangle.pos.x += 0.2;
break;
case GLUT_KEY_UP:
sceneinfo.triangle.pos.y += 0.2;
break;
case GLUT_KEY_DOWN:
sceneinfo.triangle.pos.y -= 0.2;
break;
}
glutPostRedisplay();
}