Хорошо, я пытаюсь воссоздать старую классическую ракетную команду, используя OpenGL в C ++.Это мой первый набег в OpenGL, хотя я чувствую себя довольно комфортно с C ++ на данный момент.
Я решил, что моей первой задачей было выяснить, как перемещать 2d объекты по экрану, казалось, это было бы довольно просто,Я создал два быстрых вызова методов для создания треугольников или четырехугольников:
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;
}
Квадрат определен как «фон» на данный момент и состоит из зеленого прямоугольника в нижней части экрана.Красный треугольник - это «объект», который я хочу переместить.При нажатии клавиши смещение сохраняется в указанном направлении.
Я пытался использовать 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;
Прекрасно работает для моих целей.У меня не было необходимости переводить матрицу, мне просто нужно было нарисовать элемент в другой позиции от одной сцены к другой.