gpt4 book ai didi

c++ - OpenGL:如何在不移动整个场景的情况下移动二维对象?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:48:36 24 4
gpt4 key购买 nike

好吧,我正在尝试使用 C++ 中的 OpenGL 重新创建经典的 Missile Command。这是我第一次涉足 OpenGL,尽管此时我对 C++ 感到相当满意。

我认为我的第一个任务是弄清楚如何在屏幕上移动二维对象,这看起来相当简单。我创建了两个快速方法调用来制作三角形或四边形:

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();
}

color3fvertex2f 是简单的类:

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;
}

暂时将四边形定义为“背景”,它仅由屏幕底部的一个绿色矩形组成。红色三角形是我要移动的“对象”。在按键时,将在指示的方向上保存一个偏移量。

我试过使用 glTranslatef(xOffset,yOffset,0); 但问题是它移动了屏幕上的两个元素,而不仅仅是红色三角形。我试图将整个调用放在 push 和 pop 矩阵操作之间绘制三角形:

PushMatrix();
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();
PopMatrix();

据我所知,这破坏了翻译之前所做的任何更改。我也试过在调用绘图之前只更改 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;

对我来说效果很好。我不需要平移矩阵,我只需要在一个场景到下一个场景的不同位置绘制元素。

最佳答案

GL_MODELVIEW 是您所需要的。

来自 OpenGL 常见问题解答,2.1:http://www.opengl.org/resources/faq/technical/gettingstarted.htm

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.
}

关于c++ - OpenGL:如何在不移动整个场景的情况下移动二维对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5643930/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com