为什么我的气缸模型不能在Z轴上旋转?

时间:2011-10-09 07:47:42

标签: c++ opengl

我试图编写以下代码来绘制圆柱体。使用OpenGL在C ++中绘制圆柱体。我给了学校一个小工具,我可以用我自己的模型的cpp文件编译,然后用鼠标旋转模型。该工具不会影响我的模型的旋转,因为它适用于其他演示模型。但是,由于某些我不明白的原因,我无法在Z轴上旋转圆柱体以在水平视图中看到它。因此,圆柱体只能在这些方向上旋转和看到:

enter image description here

为什么我无法旋转气缸以朝这个方向看?在Photoshop中手动旋转下面的图像,以说明模型无法旋转到的视图方向:

enter image description here

我不明白不在那个方向旋转的原因是什么,因为为其他模型显示的演示(由他人编写)可以在所有方向自由旋转。

这是我在mymodel.cpp中尝试编写的代码:

void drawCylinderObject() {
    float topRadius = 5;
    float bottomRadius = 5;
    float height = 10;
    int numOfPolygons = 50;
    float basisvec1[3] = {1, 0, 0};
    float basisvec2[3] = {0, 0, -1};
    float topPosition[3] = {0, height/2.0, 0};
    float bottomPosition[3] = {0, -height/2.0, 0};


    for(int i=0; i<numOfPolygons; i++) {
        float angle1 = (float)i/(float)numOfPolygons*2.0*M_PI;
        float angle2 = ((float)i+1.0)/(float)numOfPolygons*2.0*M_PI;
        vector<float> point1(3), point2(3), point3(3), point4(3);
        for(int j=0; j<3; j++) {
            point1[j] = topPosition[j] + topRadius * cos(angle1) * basisvec1[j] + topRadius * sin(angle1) * basisvec2[j];
        }


        for(int j=0; j<3; j++) {
            point2[j] = bottomPosition[j] + bottomRadius * cos(angle1) * basisvec1[j] + bottomRadius * sin(angle1) * basisvec2[j];

        }

        for(int j=0; j<3; j++) {
            point3[j] = bottomPosition[j] + bottomRadius * cos(angle2) * basisvec1[j] + bottomRadius * sin(angle2) * basisvec2[j];
        }

        for(int j=0; j<3; j++) {
            point4[j] = topPosition[j] + topRadius * cos(angle2) * basisvec1[j] + topRadius * sin(angle2) * basisvec2[j];
        }

        float crossvec1[3] = {point4[0]-point1[0], point4[1]-point1[1], point4[2]-point1[2]};
        float crossvec2[3] = {point2[0]-point1[0], point2[1]-point1[1], point2[2]-point1[2]};
        float normalVector1[3];

        crossProduct(crossvec2, crossvec1, normalVector1);

        glBegin(GL_POLYGON);

        glNormal3fv(normalVector1);

        glVertex3f(point1[0], point1[1], point1[2]);
        glVertex3f(point2[0], point2[1], point2[2]);
        glVertex3f(point3[0], point3[1], point3[2]);
        glVertex3f(point4[0], point4[1], point4[2]);

        glEnd();
    }
}

我所覆盖的功能就像这样,也在mymodel.cpp

void CRenderView::drawScene()
{
    //calls the above function
    drawCylinderObject();
}

我所做的基本上只是定义2个垂直基础单位向量,然后用幅度值向外扩展它们。然后我循环这个360度来绘制多边形以形成圆柱体。但这种绘图方式不允许我自由旋转模型有什么不对?

修改

以下是该工具如何绘制场景的代码的一部分。不知何故,该工具有很多类。它的大多数类只是设置工具的GUI,然后绘制它的唯一部分是CRenderView.cpp下面的那个:

void CRenderView::OnPaint() 
{
    // Device context for painting
    CPaintDC dc(this); 

    // Model is stored in Document
    CToolDoc *pDoc = (CToolDoc *)GetDocument();
    ASSERT_VALID(pDoc);

    // Useful in multidoc templates
    HWND hWnd = GetSafeHwnd();
    HDC hDC = ::GetDC(hWnd);
    wglMakeCurrent(hDC,m_hGLContext);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glClearColor(m_ClearColorRed,m_ClearColorGreen,m_ClearColorBlue,1.0f);

    glPushMatrix();

    // Position / translation / scale
    glTranslated(m_xTranslation,m_yTranslation,m_zTranslation);
    glRotatef(m_xRotation, 1.0, 0.0, 0.0);
    glRotatef(m_yRotation, 0.0, 1.0, 0.0);
    glScalef(m_xScaling,m_yScaling,m_zScaling);

    // Start rendering...
    drawScene();

    glPopMatrix();

    // Double buffer
    SwapBuffers(dc.m_ps.hdc);
}

protected:
    void drawScene();

void CRenderView::OnMouseMove(UINT nFlags, 
                                                            CPoint point) 
{
    if(m_LeftButtonDown)
    {
        m_yRotation -= (float)(m_LeftDownPos.x - point.x)/3.0f;
        m_xRotation -= (float)(m_LeftDownPos.y - point.y)/3.0f;
        m_LeftDownPos = point;
        InvalidateRect(NULL,FALSE);
    }
    CView::OnMouseMove(nFlags, point);
}

1 个答案:

答案 0 :(得分:1)

请问,为什么通过重新计算顶点来旋转圆柱?只需生成一次的圆柱模型,然后在模型视图矩阵上执行以下任何变换。另外我想你想要围绕Z旋转,而不是Y.

<强>更新

该“工具”似乎是“MFC OpenGL CView”教程的略微扩展版本。 * *呸

我看到的最大问题是,CRenderView :: OnPaint函数是由不知道如何正确使用OpenGL的人编写的。

void CRenderView::OnPaint() 
{
    // Device context for painting
    CPaintDC dc(this); 

    // Model is stored in Document
    CToolDoc *pDoc = (CToolDoc *)GetDocument();
    ASSERT_VALID(pDoc);

    // Useful in multidoc templates
    HWND hWnd = GetSafeHwnd();
    HDC hDC = ::GetDC(hWnd);
    wglMakeCurrent(hDC,m_hGLContext);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
    glClearColor(m_ClearColorRed,m_ClearColorGreen,m_ClearColorBlue,1.0f);

glClearColor 必须 glClear之前调用,因为它设置了将在glClear调用上应用的值。这样,它将在下一帧的glClear调用上工作,或者根本不工作。

    glPushMatrix();

推送哪个矩阵?这没有调用glMatrixMode。

从一些任意矩阵开始。 BTW在哪里是投影集(让我猜一下,在OnSize处理程序中,对吗?)。

    // Position / translation / scale
    glTranslated(m_xTranslation,m_yTranslation,m_zTranslation);
    glRotatef(m_xRotation, 1.0, 0.0, 0.0);
    glRotatef(m_yRotation, 0.0, 1.0, 0.0);

您确认要围绕Z轴旋转。那你为什么不在这里呢?这里只有X和Y的旋转。问题是:你在这里使用的是欧拉角,它有一些讨厌的属性,并且被3D图形人员所厌恶。更好地使用四元数来表示旋转(只是一个建议)。

    glScalef(m_xScaling,m_yScaling,m_zScaling);

    // Start rendering...
    drawScene();

    glPopMatrix();

    // Double buffer
    SwapBuffers(dc.m_ps.hdc);
}