c++ - 使用 3d 对象为图形正确设置坐标

标签 c++ visual-c++ opengl graphics 3d

我在进行此修改时遇到了困难。我想添加 2 个实体(这里称为手指)在一起,以便它们可以在按下“o”或“c”键时打开和关闭。我无法获得正确的坐标,因此可以将它们放在靠近绿色物体的地方。所以它看起来像一只有 2 个手指的手。

这是指向所需输出的链接 http://www.tinyuploads.com/gallery/view/zO6rYg

#include <cstdlib>
#include <cmath>
#include <vector>
#include <iostream>
#ifdef __APPLE__
#include <GLUT/glut.h>
//#include <gl.h>
//#include <glut.h>
#else
#  include <GL/glut.h>
#endif
using namespace std;
#define ESC 27
static GLfloat red[]={1,0,0}, green[]={0,1,0}, blue[]={0,0,1};
static int shoulder=0, elbow=0, finger1 = 0, finger2 = 0;
static int xrot=0, yrot=0, zrot=0;
static GLfloat xshift=-1.0, yshift=0.0, zoom=-3.0;

/* some basic GL initialization */
void init()
{
    glClearColor(1.0,1.0,1.0,0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
}

/* The display callback */
/* Put the "fingers" code somewhere in this function*/
void draw_stuff()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0.0,0.0,-5.0);
    glPushMatrix();
    glTranslatef(xshift,yshift,zoom);
    glRotatef((GLfloat)xrot,1.0,0.0,0.0);
    glRotatef((GLfloat)yrot,0.0,1.0,0.0);
    glRotatef((GLfloat)zrot,0.0,0.0,1.0);

    glColor3fv(red);
    glPushMatrix();
    glTranslatef(-1.0,0.0,0.0);
    glRotatef((GLfloat)shoulder,0.0,0.0,1.0);
    glTranslatef(1.0,0.0,0.0);
    glPushMatrix();
    glScalef(2.0,0.4,1.0);
    glutSolidCube(1.0);
    glPopMatrix();

    glColor3fv(green);
    glTranslatef(1.0,0.0,0.0);
    glRotatef((GLfloat)elbow,0.0,0.0,1.0);
    glTranslatef(1.0,0.0,0.0);
    glPushMatrix();
    glScalef(2.0,0.4,1.0);
    glutSolidCube(1.0);
    glPopMatrix();

    glColor3fv(blue);
    glTranslatef(1.0,0.2,0.0);
    glRotatef((GLfloat)finger1,0.0,0.0,1.0);
    glRotatef((GLfloat)finger2,0.0,0.0,1.0);
    glTranslatef(1.0,0.0,0.0);
    glPushMatrix();
    glScalef(2.0,0.4,1.0);
    glutSolidCube(0.25);
    glPopMatrix();

    glColor3fv(blue);
    glTranslatef(-1.0,0.0,1.0);
    glRotatef((GLfloat)finger1,0.0,0.0,1.0);
    glRotatef((GLfloat)finger2,0.0,0.0,1.0);
    glTranslatef(1.0,0.0,0.0);
    glPushMatrix();
    glScalef(2.0,0.4,1.0);
    glutSolidCube(0.25);
    glPopMatrix();

    glPopMatrix();
    glPopMatrix();
    glutSwapBuffers();
}

/* the window-reshape callback */
void reshape(int w, int h)
{
    GLfloat myFov = 65.0, myNear = 1.0, myFar = 30.0;
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(myFov,(GLfloat)w/(GLfloat)h, myNear, myFar);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

/* The basic keyboard controls, callback for glutKeyboardFunc() */
void kb(unsigned char key, int x, int y)
{
    switch(key)
    {
        case 's':
            shoulder=(shoulder+5)%360;
            glutPostRedisplay();
            break;
        case 'S':
            shoulder=(shoulder-5)%360;
            glutPostRedisplay();
            break;
        case 'e':
            elbow=(elbow+5)%360;
            glutPostRedisplay();
            break;
        case 'E':
            elbow=(elbow-5)%360;
            glutPostRedisplay();
            break;

        case 'C' |'c':
            /* close the "hand" */
            finger1=(finger1+5)%360;
            finger2=(finger2+5)%360;
            glutPostRedisplay();
            break;
        case 'O' | 'o':
            /* open the "hand" */
            finger1=(finger1-5)%360;
            finger2=(finger2-5)%360;
            glutPostRedisplay();
            break;
        case 'x':
            xshift+=.25;
            glutPostRedisplay();
            break;
        case 'X':
            xshift-=.25;
            glutPostRedisplay();
            break;
        case 'y':
            yshift+=.25;
            glutPostRedisplay();
            break;
        case 'Y':
            yshift-=.25;
            glutPostRedisplay();
            break;
        case 'r':
        case 'R':
            xrot=yrot=zrot=shoulder=elbow=0;
            xshift=-1.0;
            yshift=0.0;
            zoom=-3.0;
            glutPostRedisplay();
            break;
        case 'z':
            zrot=(zrot-1)%360;
            glutPostRedisplay();
            break;
        case 'Z':
            zrot=(zrot+1)%360;
            glutPostRedisplay();
            break;
        case ESC:
            exit(0);
            break;
        default:
            break;
    }
}

/* The "special" keyboard controls, callback for glutSpecialFunc() */
void skb(int key, int x, int y)
{
    switch(key)
    {
        case GLUT_KEY_UP:
            zoom+=1;
            glutPostRedisplay();
            break;
        case GLUT_KEY_DOWN:
            zoom-=1;
            glutPostRedisplay();
            break;
        case GLUT_KEY_RIGHT:
            yrot=(yrot-1)%360;
            glutPostRedisplay();
            break;
        case GLUT_KEY_LEFT:
            yrot=(yrot+1)%360;
            glutPostRedisplay();
            break;
        case GLUT_KEY_PAGE_UP:
            xrot=(xrot-1)%360;
            glutPostRedisplay();
            break;
        case GLUT_KEY_PAGE_DOWN:
            xrot=(xrot+1)%360;
            glutPostRedisplay();
            break;
        default:
            break;
    }
}


void printInteraction(void)
{


    cout << "s/S:   Positive/negative shoulder rotation" << endl;
    cout << "e/E:   Positive/negative elbow rotation" << endl
    << "O/C:    Open/Close the hand -- YOU GET TO IMPLEMENT THIS" << endl
    << "x/X:    Positive/negative X-axis shift of the model" << endl
    << "y/Y:    Positive/negative Y-axis shift of the model" << endl
    << "UP/DOWN ARROWS: (zoom) Z-axis shift of the model" << endl
    << "LEFT/RIGHT ARROWS:  Y-axis rotations" << endl
    << "PAGE UP/DOWN:   X-axis rotations" << endl
    << "ESC:    exit" << endl;
}

int main(int argc, char **argv)
{
    int winWidth = 800, winHeight = 600, winPosX = 100, winPosY = 100; // OpenGL window
    printInteraction();
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(600,400);
    glutInitWindowPosition(0,0);
    glutCreateWindow("window");
    init();
    glutDisplayFunc(draw_stuff);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(kb);
    glutSpecialFunc(skb);
    glutMainLoop();
    return 0;
}

最佳答案

您的 glPush/PopMatrix() 调用序列显示您的模型中缺少层次结构。

它应该是这样的(我缩进了伪代码来说明发生了什么):

glPushMatrix();
  // do stuff to position shoulder
  // draw shoulder
  glPushMatrix();
    // do stuff to position elbow
    // draw elbow
    glPushMatrix();
      // do stuff to position finger1
      // draw finger1
    glPopMatrix();
    glPushMatrix();
      // do stuff to position finger2
      // draw finger2
    glPopMatrix();
  glPopMatrix(); // elbow
glPopMatrix(); // shoulder

希望对您有所帮助。

关于c++ - 使用 3d 对象为图形正确设置坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15665934/

相关文章:

c++ - new 和 malloc 返回 NULL 指针,为什么?

C++ 编译器错误 C2679 : binary '=' : no operator found

c++ - 在 OpenGL 3+ 中纹理球体

c++ - 使用 openGL 的常规窗口屏幕捕获

c++ - 导出制造商、符号可见性……?

c++ - openGL:带着色器的线条

c++ - 多态继承不覆盖基类方法

c++ - 复制 MPI_Win?

c++ - target_include_directories 如何工作 cmake 如何包含本地库 <path/lib.h>

visual-c++ - 视觉 C++ : convert int into string pointer