OpenGL:如何移动2d对象而不替换整个场景? P> >我想用C++中的OpenGL重新创建旧的经典导弹指令。这是我第一次进入OpenGL,虽然在这一点上我觉得C++相当舒服。
我想我的第一个任务是弄清楚如何在屏幕上移动2d对象,这看起来相当简单。我创建了两个快速方法调用来生成三角形或四边形:OpenGL:如何移动2d对象而不替换整个场景? P> >我想用C++中的OpenGL重新创建旧的经典导弹指令。这是我第一次进入OpenGL,虽然在这一点上我觉得C++相当舒服。,c++,opengl,2d,C++,Opengl,2d,我想我的第一个任务是弄清楚如何在屏幕上移动2d对象,这看起来相当简单。我创建了两个快速方法调用来生成三角形或四边形: void makeTriangle(color3f theColor, vertex2f &p1, vertex2f &p2, vertex2f &p3, int &xOffset, int &yOffset) { //a triangle glBegin(GL_POLYGON);
void makeTriangle(color3f theColor, vertex2f &p1, vertex2f &p2, vertex2f &p3,
int &xOffset, int &yOffset)
{
//a triangle
glBegin(GL_POLYGON);
glColor3f(theColor.red, theColor.green, theColor.blue);
glVertex2f(p1.x, p1.y);
glVertex2f(p2.x, p2.y);
glVertex2f(p3.x, p3.y);
glEnd();
}
void makeQuad(color3f theColor, vertex2f &p1, vertex2f &p2, vertex2f &p3,
vertex2f &p4, int &xOffset, int &yOffset)
{
//a rectangle
glBegin(GL_POLYGON);
glColor3f(theColor.red, theColor.green, theColor.blue);
glVertex2f(p1.x, p1.y);
glVertex2f(p2.x, p2.y);
glVertex2f(p3.x, p3.y);
glVertex2f(p4.x, p4.y);
glEnd();
}
color3f和vertex2f是简单的类:
class vertex2f
{
public:
float x, y;
vertex2f(float a, float b){x=a; y=b;}
};
class color3f
{
public:
float red, green, blue;
color3f(float a, float b, float c){red=a; green=b; blue=c;}
};
这是我的主要文件:
#include <iostream>
#include "Shapes.hpp"
using namespace std;
int xOffset = 0, yOffset = 0;
bool done = false;
void keyboard(unsigned char key, int x, int y)
{
if( key == 'q' || key == 'Q')
{
exit(0);
done = true;
}
if( key == 'a' )
xOffset = -10;
if( key == 'd' )
xOffset = 10;
if( key == 's' )
yOffset = -10;
if( key == 'w' )
yOffset = 10;
}
void init(void)
{
//Set color of display window to white
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//Set parameters for world-coordiante clipping window
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-400.0,400.0,-300.0,300.0);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
color3f aGreen(0.0, 1.0, 0.0);
vertex2f pa(-400,-200);
vertex2f pb(-400,-300);
vertex2f pc(400,-300);
vertex2f pd(400,-200);
makeQuad(aGreen,pa,pb,pc,pd,xOffset,yOffset);
color3f aRed(1.0, 0.0, 0.0);
vertex2f p1(-50.0,-25.0);
vertex2f p2(50.0,-25.0);
vertex2f p3(0.0,50.0);
makeTriangle(aRed,p1,p2,p3,xOffset,yOffset);
glFlush();
}
int main(int argc, char** argv)
{
// Create Window.
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutCreateWindow("test");
// Some initialization.
init();
while(!done)
{
//display functions
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
// Start event loop.
glutMainLoop();
}
return 0;
}
据我所知,这破坏了翻译之前所做的任何更改。
我也尝试过在调用绘图之前更改x和y坐标的值,但这只会导致在将三角形保留在其原始位置之前出现短暂闪烁:
p1.x += xOffset;
p2.x += xOffset;
p3.x += xOffset;
p1.y += yOffset;
p2.y += yOffset;
p3.y += yOffset;
必须有一个简单的方法来做这件事,我只是忽略了它。有人能提个建议吗
编辑:
我的实际问题是,在第一次抽签后,我从未刷新过屏幕。我需要的是在我的主循环中指定一个空闲函数:
glutIdleFunc(IdleFunc);
其中实际的IdleFunc如下所示:
GLvoid IdleFunc(GLvoid)
{
glutPostRedisplay();
}
我不应该在绘图函数中使用glFlush()
,而应该使用glutSwapBuffers()
。通过这样做,我首先想到的代码是:
p1.x += xOffset;
p2.x += xOffset;
p3.x += xOffset;
p1.y += yOffset;
p2.y += yOffset;
p3.y += yOffset;
这对我来说很好。我不需要转换矩阵,我只需要从一个场景到下一个场景在不同的位置绘制元素。如果我正确阅读了您的代码,您只想向右旋转一个元素吗?如果是,请执行以下操作:
- 调用
glPushMatrix()代码>
- 然后做轮换
- 存储你旋转了多少次
- 然后绘制旋转的项目
- 然后调用
glPopMatrix()代码>
我还注意到您没有初始化Modelview矩阵。设置投影矩阵后,应初始化Modelview矩阵。您还需要确保将两个矩阵初始化为标识。最后,确保每次屏幕刷新时都初始化两个矩阵。要测试这一点,请在矩阵初始化上设置一个断点,并查看它是否仅被命中一次或每帧一次。如果您回答自己的问题,这就是解决方案:
glPushMatrix();
glTranslatef(xOffset,yOffset,0);
glBegin(GL_POLYGON);
glColor3f(theColor.red, theColor.green, theColor.blue);
glVertex2f(p1.x, p1.y);
glVertex2f(p2.x, p2.y);
glVertex2f(p3.x, p3.y);
glEnd();
glPopMatrix();
这将在绘制矩形时更改modelview矩阵,然后将modelview矩阵恢复到以前的状态。你真的试过了吗?怎么了?GL\u MODELVIEW是您需要的 从OpenGL常见问题解答2.1:
+1完全正确。这可能就是问题所在。我在代码中没有看到任何Modelview矩阵初始化。另外,我看到holtavolt将矩阵初始化放在openGL循环中,所以它每一帧都被初始化。我没有发现openGL网站上的文档非常有用。我不明白这些评论中的大多数是什么意思,谷歌搜索其中的大多数也不是很有启发性。我知道我的问题的答案在于Modelview矩阵和Push and Pop矩阵操作,但我似乎无法在我的原始解决方案中解决这些问题,或者如果我需要将整个问题抛出去,从头开始。好的-你可能想从这个NeHe OpenGL教程开始,它独立旋转两个对象,以使窗体向下:+1,我的想法正是如此。你能详细说明一下上面的代码有哪些地方不起作用吗?按照我的方式这样做不会导致任何转换发生。在回顾了joe_coolish和holtavolt在下面的回答之后,我认为我的错误在于没有初始化Modelview矩阵。然而,我仍然在努力寻找正确的方法,以及在代码中插入它的位置。
glPushMatrix();
glTranslatef(xOffset,yOffset,0);
glBegin(GL_POLYGON);
glColor3f(theColor.red, theColor.green, theColor.blue);
glVertex2f(p1.x, p1.y);
glVertex2f(p2.x, p2.y);
glVertex2f(p3.x, p3.y);
glEnd();
glPopMatrix();
program_entrypoint
{
// Determine which depth or pixel format should be used.
// Create a window with the desired format.
// Create a rendering context and make it current with the window.
// Set up initial OpenGL state.
// Set up callback routines for window resize and window refresh.
}
handle_resize
{
glViewport(...);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set projection transform with glOrtho, glFrustum, gluOrtho2D, gluPerspective, etc.
}
handle_refresh
{
glClear(...);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Set view transform with gluLookAt or equivalent
// For each object (i) in the scene that needs to be rendered:
// Push relevant stacks, e.g., glPushMatrix, glPushAttrib.
// Set OpenGL state specific to object (i).
// Set model transform for object (i) using glTranslatef, glScalef, glRotatef, and/or equivalent.
// Issue rendering commands for object (i).
// Pop relevant stacks, (e.g., glPopMatrix, glPopAttrib.)
// End for loop.
// Swap buffers.
}