简体   繁体   中英

Using glut, how do I make it so I can move an object around in a scene by clicking and dragging it around?

I have written a program that creates a room that currently contains a triangle. I want to make more objects like this triangle, but I also want to add functionality that allows me to move the objects by clicking on them and dragging them. I am thinking the best way would be to create some sort of template/prototype etc. etc. that has the geometric data passed via a constructor but has a function for moving it around by mouse, but I am unsure if I have it right, and I am not entirely sure about what I actually need to do to get this working like that. Here is my current code, it allows rotation of scene using direction keys, but I am unsure how to make it so I can click on an object and drag it at this point (I have the beginnings of something I was trying for this commented out because I don't think it would work, but if it will let me know how):

#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include <stdlib.h>
#include <GL/glut.h>


void display();
void viewButtons();

//const double ZoomSTEP = 0.2;
//const double zoomFactor = 1.03;
double rotationY = 0;
double rotationX = 0;
// Mouse positions, normalized to [0,1].
//double xMouse = 0.5;
//double yMouse = 0.5;

//GLdouble startView = 2.0;

void display()
{
//Clear the screen and clear z-buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset transformations
glLoadIdentity();

// Rotate when user changes rotate_x and rotate_y
glRotatef(rotationX, 1.0, 0.0, 0.0);
glRotatef(rotationY, 0.0, 1.0, 0.0);
glBegin(GL_POLYGON);
//Vertices and colors
glColor3f(1.0, 0.0, 0.0);     
glVertex3f(0.5, -0.5, 0.5);      // P1 is red
glColor3f(0.0, 1.0, 0.0);    
glVertex3f(0.5, 0.5, 0.5);      // P2 is green
glColor3f(0.0, 0.0, 1.0);     
glVertex3f(-0.5, 0.5, 0.5);      // P3 is blue
glColor3f(1.0, 0.0, 1.0);     
glVertex3f(-0.5, -0.5, 0.5);      // P4 is purple

glEnd();

/*// White side - BACK
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 1.0);
glVertex3f(0.5, -0.5, 0.5);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(-0.5, -0.5, 0.5);
glEnd();*/

// Purple side - RIGHT
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 1.0);
glVertex3f(0.5, -0.5, -0.5);
glVertex3f(0.5, 0.5, -0.5);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(0.5, -0.5, 0.5);
glEnd();

// Green side - LEFT
glBegin(GL_POLYGON);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(-0.5, -0.5, 0.5);
glVertex3f(-0.5, 0.5, 0.5);
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f(-0.5, -0.5, -0.5);
glEnd();

// Blue side - TOP
glBegin(GL_POLYGON);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.5, 0.5, 0.5);
glVertex3f(0.5, 0.5, -0.5);
glVertex3f(-0.5, 0.5, -0.5);
glVertex3f(-0.5, 0.5, 0.5);
glEnd();

// Red side - BOTTOM
glBegin(GL_POLYGON);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(0.5, -0.5, -0.5);
glVertex3f(0.5, -0.5, 0.5);
glVertex3f(-0.5, -0.5, 0.5);
glVertex3f(-0.5, -0.5, -0.5);
glEnd();

glBegin(GL_POLYGON);
glColor3f(0.5, 0.6, 0.3);
glVertex3f(0.3, 0.1, 0.5);
glVertex3f(0.4, 0.1, 0.5);
glVertex3f(0.2, -0.2, 0.1);
glEnd();

glFlush();
glutSwapBuffers();


}

void viewButtons(int button, int x, int y)
{
if (button == GLUT_KEY_RIGHT)
    rotationY += 5;

else if (button == GLUT_KEY_LEFT)
    rotationY -= 5;

else if (button == GLUT_KEY_UP)
    rotationX += 5;

else if (button == GLUT_KEY_DOWN)
    rotationX -= 5;

//update display
glutPostRedisplay();
}

int main(int argc, char **argv) {

// init GLUT and create window

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

glutInitWindowPosition(100, 100);
glutInitWindowSize(720, 640);
glutCreateWindow("Room with objects");

// register callbacks
glutDisplayFunc(display);
glutSpecialFunc(viewButtons);
glEnable(GL_DEPTH_TEST);
// enter GLUT event processing cycle
glutMainLoop();

return 1;
}

If you want to transpose/rotate/scale an arbitrary object the template for this is something like this:

  1. save your current world matrix (you can do that using glPushMatrix)
  2. translate you object to the position you want (using glRotate/glTranslate/glScale)
  3. draw you object (the glBegin/glEnd part)
  4. retrieve your old matrix (if you pushed it to the stack use glPopMatrix)

Repeat this process for every drawable object in your scene.

When manipulating objects you might define one matrix for each object so that you can manipulate them independently. You would then compute the matrices for each object yourself (have a look into glm - a neat framework for doing exactly such things) and then instead of step 2. use glMultMatrix and set you own matrix.

Also, you are using legacy openGL code, so I'am guessing you are learning right now how things work out. My suggestion is instead of learning the old stuff: Have a look into glsl shader programming, vertexbufferobjects and all the good stuff that is beyond opengl 1.4 there are some really good tuts out there http://www.opengl-tutorial.org/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM