glPushMatrix(); glTranslated(x, y, 0); //glTranslated(-0.8,0.3,0); pig();//小猪 glPopMatrix();为什么我的pig不会动
时间: 2024-11-18 18:17:24 浏览: 15
`glPushMatrix()` 和 `glPopMatrix()` 是OpenGL中的矩阵操作函数,它们用于保存和恢复当前的图形变换状态。当你在绘制之前调用 `glPushMatrix()`,会将当前的变换矩阵复制一份并压入栈中,然后对坐标系进行任何变换都不会影响到之前的矩阵。当你绘制完之后,调用 `glPopMatrix()` 会将先前保存的矩阵弹出,并恢复到该操作前的状态。
在你提供的代码片段中,`glTranslated(x, y, 0)` 是将绘图坐标系向右移动x单位、向上移动y单位,但同时没有指定任何缩放或旋转。所以每次调用 `glTranslated()` 都是在原点基础上增加平移,而 `glPopMatrix()` 回到了原始位置,这就导致了 "pig" 没有移动的感觉。
如果你想要 "pig" 真正随着代码的执行动态移动,你需要在每次移动后都调用 `glPopMatrix()` 取消之前的操作,然后再做下一次移动。例如:
```c++
glPushMatrix(); // 保存初始变换
glTranslated(x, y, 0); // 移动 pig
pig(); // 绘制
glPopMatrix(); // 回复到初始位置
// 下次移动
glTranslated(-0.8, 0.3, 0); // 新的移动
pig(); // 再次绘制
glPopMatrix(); // 保持上次移动效果
```
这样,"pig" 就会在每个移动命令后按照设定的位置变化了。
相关问题
CParasolidTestGLDoc* pDoc = GetDocument(); MakeCurrent(TRUE); if(m_firstDraw == TRUE) { m_firstDraw = FALSE; // Otherwise the first draw is a blank ! VERIFY_GL(glDrawBuffer(GL_FRONT_AND_BACK)); ReRender(); } else VERIFY_GL(glDrawBuffer(GL_BACK)); VERIFY_GL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); VERIFY_GL(glMatrixMode(GL_MODELVIEW)); VERIFY_GL(glPushMatrix()); VERIFY_GL(glTranslated( -pDoc->m_viewCentre.coord[0], -pDoc->m_viewCentre.coord[1], -pDoc->m_viewCentre.coord[2])); if(pDoc->m_nrenderGeoms != 0 || pDoc->m_nparts != 0) { VERIFY_GL(glCallList(m_partDisplaylist)); } VERIFY_GL(glFlush()); VERIFY_GL(glPopMatrix()); RenderAxis(0.0, 0.0); SwapBuffers(pDC->m_hDC); pDC->RealizePalette(); MakeCurrent(FALSE); VERIFY_GL(glViewport(0, 0, m_winWidth, m_winHeight)); SetViewVolume(); 翻译这段代码
这段代码是一个OpenGL的绘图函数,主要作用是在OpenGL窗口中绘制三维几何体。具体实现步骤如下:
1.获取文档对象(CParasolidTestGLDoc* pDoc)。
2.调用MakeCurrent(TRUE)函数将OpenGL渲染上下文设置为当前。
3.如果是第一次绘制,则将m_firstDraw标志设置为FALSE,并调用ReRender()函数重新渲染。
4.如果不是第一次绘制,则将绘制缓冲区设置为GL_BACK。
5.调用glClear()函数清除颜色缓冲区和深度缓冲区。
6.调用glMatrixMode()函数将当前矩阵模式设置为GL_MODELVIEW。
7.调用glPushMatrix()函数将当前矩阵保存到矩阵堆栈中。
8.调用glTranslated()函数将模型视图矩阵平移,以实现视角的变换。
9.如果有几何体或部件需要渲染,则调用glCallList()函数调用预先编译好的显示列表。
10.调用glFlush()函数将缓冲区的内容刷新到屏幕上。
11.调用glPopMatrix()函数从矩阵堆栈中弹出当前矩阵。
12.调用RenderAxis()函数绘制坐标轴。
13.调用SwapBuffers()函数交换前后缓冲区的内容,将绘制结果输出到屏幕。
14.调用RealizePalette()函数实现调色板的实现。
15.调用MakeCurrent(FALSE)函数将OpenGL渲染上下文设置为非当前。
16.调用glViewport()函数将视口大小设置为OpenGL窗口大小。
17.调用SetViewVolume()函数设置视景体。
GLfloat initX = 0, initY = 0; GLfloat oldx = 0, oldy = 0; int times = 0; bool gDrawline = false; void drawkoch(GLfloat dir, GLfloat len, GLint iter) { GLdouble dirRad = dir * 3.1415926 / 180.f; GLfloat newX = oldx + len * cos(dirRad); GLfloat newY = oldy + len * sin(dirRad); if (iter == 0) { glVertex2f(oldx, oldy); glVertex2f(newX, newY); oldx = newX; oldy = newY; } else { iter--; len = len / 3; drawkoch(dir, len, iter); dir += 60; drawkoch(dir, len, iter); dir -= 120; drawkoch(dir, len, iter); dir += 60; drawkoch(dir, len, iter); } } typedef GLfloat point2d[2]; int iter = 0; float snowAngle = 0; point2d p = { 960, 20 }; point2d anyline[2]; point2d pp; void CMFCGLSetupView::OnDraw(CDC* pDC) { CMFCGLSetupDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: add draw code for native data here wglMakeCurrent(pDC->m_hDC, m_hRC); oldx = initX; oldy = initY; glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, Cx, 0, Cy, -1000, 1000); switch (drawMode) { case 0: glTranslatef(400, 450, 0); glBegin(GL_LINES); glColor3f(0.0, 1.0, 0.0); drawkoch(0, 500, iter); glEnd(); break; case 1: glTranslatef(400, 450, 0); glPushMatrix(); glTranslated(250, -125 * sqrt(3), 0); glRotated(snowAngle, 0, 1, 0); glTranslated(-250, 125 * sqrt(3), 0); glBegin(GL_LINES); glColor3f(0.0, 1.0, 0.0); drawkoch(0, 500, iter); drawkoch(-120, 500, iter); drawkoch(-240, 500, iter); glEnd(); glPopMatrix(); break; case 2: if (gDrawline) { oldx = anyline[0][0]; oldy = anyline[0][1]; point2d v; v[0] = (anyline[1][0] - anyline[0][0]); v[1] = (anyline[1][1] - anyline[0][1]); float len = sqrt(v[0] * v[0] + v[1] * v[1]); v[0] /= len; v[1] /= len; point2d n = { 1, 0 }; float cosTheta = v[0] * n[0] + v[1] * n[1]; float angle = acos(cosTheta) * 180.f / PI; if (anyline[1][1] < anyline[0][1]) { angle = -angle; } glBegin(GL_LINES); drawkoch(angle, len, iter); glEnd(); } break; default: break; } glBegin(GL_POINTS); glVertex2f(pp[0], pp[1]); glEnd(); glFlush(); wglMakeCurrent(pDC->m_hDC, NULL); }
这段代码是使用OpenGL库绘制Koch曲线的实现。具体来说,这段代码定义了一个名为`drawkoch`的函数,该函数使用递归的方式绘制Koch曲线。在`OnDraw`函数中,根据不同的`drawMode`变量值,选择不同的绘制模式来绘制Koch曲线:
- 当`drawMode`为0时,绘制一个普通的Koch曲线;
- 当`drawMode`为1时,绘制一个Koch雪花;
- 当`drawMode`为2时,绘制用户自定义的线段。
其中,绘制Koch曲线和Koch雪花的实现方式相同,都是调用`drawkoch`函数来进行递归绘制。而绘制用户自定义线段的方式则需要先计算出线段的长度和方向,然后调用`drawkoch`函数来进行绘制。
此外,代码中还定义了一些全局变量,如`initX`、`initY`、`oldx`、`oldy`等,用于记录绘制Koch曲线时的初始点和当前绘制点的坐标。还有一些辅助函数,如计算角度和距离的函数等。
阅读全文