- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我试图编写以下代码来绘制圆柱体。圆柱体是用 C++ 和 OpenGL 绘制的。学校给了我一个小工具,我可以用我自己的模型的 cpp 文件编译,然后可以用鼠标旋转模型。该工具不会影响我的模型的旋转,因为它适用于其他演示模型。但是,出于某种我不明白的原因,我无法在 Z 轴上旋转圆柱体以在水平 View 中查看它。因此,圆柱体只能在这些方向上旋转和观察:
为什么我不能旋转圆柱体以在这个方向看到它?下图是在 Photoshop 中手动旋转的,以说明模型无法旋转到的 View 方向:
我不明白为什么不能朝那个方向旋转,因为其他模型(其他人编写的)的演示可以在各个方向自由旋转。
这是我在 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 个垂直的基本单位 vector ,然后将它们向外扩展一个幅度值。我通过这个 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);
}
最佳答案
请问,为什么要通过重新计算顶点来旋转圆柱体?只需生成一个圆柱体模型一次,然后对模型 View 矩阵执行任何以下转换。另外我认为你会想要围绕 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 的调用。
从一些任意矩阵开始。顺便说一句,投影集在哪里(让我猜猜,在 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);
}
关于c++ - 为什么我的圆柱模型不能在 Z 轴上旋转?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7702140/
我是一名优秀的程序员,十分优秀!