#opengl #2d
#opengl #2d
Вопрос:
Я хочу создать высокопроизводительную 2D-программу.
Я использую VC 2008. Предположим, я создал главное окно. Что я хочу, так это нарисовать красный прямоугольник (вверху слева: 10,20, внизу справа: 200, 300) в клиентской области главного окна, подобно тому, что делает fillRect () API, но с использованием OpenGL.
void InitOpenGL(HWND hwnd)
{
.... // What should I do?
// Only for 2D drawing, and the (0,0) should be the top left point.
}
// the function below will be called in the WM_PAINT handler
void DrawRectWithOpenGL(RECT* pRect)
{
.... // What should I do?
}
EDIT1: Есть ли в OpenGL 2D drawing API или библиотека, подобная Direct2D / DirectWrite?
Ответ №1:
Я настоятельно рекомендую вам взглянуть на некоторые руководства по OpenGL (http://nehe.gamedev.net / хороший сайт, он расскажет вам все, что вам нужно знать), но предполагая, что у вас в коде правильно настроен OpenGL, вы бы сделали что-то подобное в вашей функции DrawRectWithOpenGL (я не программист на C , но я думаю, что мой код выглядит правильно для C ):
void DrawRectWithOpenGL(RECT* pRect)
{
glPushMatrix(); //Make sure our transformations don't affect any other transformations in other code
glTranslatef(pRect->x, pRect->y, 0.0f); //Translate rectangle to its assigned x and y position
//Put other transformations here
glBegin(GL_QUADS); //We want to draw a quad, i.e. shape with four sides
glColor3f(1, 0, 0); //Set the colour to red
glVertex2f(0, 0); //Draw the four corners of the rectangle
glVertex2f(0, pRect->h);
glVertex2f(pRect->w, pRect->h);
glVertex2f(pRect->w, 0);
glEnd();
glPopMatrix();
}
В OpenGL нет 2D drawing API, но в нем легко выполнять 2D-операции, просто игнорируя ось Z (или просто используя ось Z, чтобы убедиться, что спрайты нарисованы на правильной глубине, т. Е. Чтобы вы могли нарисовать фон после переднего плана, потому что глубина фона установлена так, чтобы он находился за передним планом). Надеюсь, это поможет. Определенно найдите время, чтобы посмотреть несколько руководств, и все станет ясно.
РЕДАКТИРОВАТЬ: Для настройки OpenGL для 2D-рисования вам необходимо настроить ортографическую проекцию (в руководствах, на которые я ссылался, используется перспективная проекция, извините, что не упомянул об этом). Вот пример части моего кода, который делает это (который должен быть где-то в вашей функции InitOpenGL, после того, как вы создали свое окно):
glClearColor(0.0, 0.0, 0.0, 0.0); //Set the cleared screen colour to black
glViewport(0, 0, screenwidth, screenheight); //This sets up the viewport so that the coordinates (0, 0) are at the top left of the window
//Set up the orthographic projection so that coordinates (0, 0) are in the top left
//and the minimum and maximum depth is -10 and 10. To enable depth just put in
//glEnable(GL_DEPTH_TEST)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, screenwidth, screenheight, 0, -10, 10);
//Back to the modelview so we can draw stuff
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); //Clear the screen and depth buffer
Итак, с инициализацией все в порядке. Вы должны иметь возможность использовать значения типа 100 и 200 и корректно отображать их на экране, т. Е. координаты указаны в пикселях.
Чтобы обработать изменения размера окна, что вам нужно сделать, это определить размер окна (используя внешнюю библиотеку. Я не уверен, что вы можете сделать это в OpenGL, хотя glutGet (GLUT_WINDOW_WIDTH) и glutGet (GLUT_WINDOW_HEIGHT) из GLUT могли бы работать, но я это не тестировал), а затем снова вызвать glViewport и glOrtho с обновленным размером окна.
Опять же, вам пришлось бы использовать внешнюю библиотеку, чтобы точно узнать, когда изменится размер окна. Я не уверен, что вы могли бы использовать, хотя, если вы используете SDL, для этого может потребоваться некоторая обработка событий (и, возможно, удастся вернуть ширину и высоту экрана, если glutGet не работает).
Я надеюсь, что это поможет!
Комментарии:
1. Спасибо за ваш ответ и ссылку на руководство. Однако проблема в том, что я не знаю, как настроить OpenGL для 2D-рисования, особенно как убедиться, что размер прямоугольника указан в пикселях. (1) В руководстве все значения вершин выглядят как 0.5f, 1.0f. Но я хочу, чтобы они были в пикселях, например, 100, 200. (2) В руководстве размеры рисунков меняются при изменении размера окна. Я хочу, чтобы все рисунки сохраняли свой размер (в пикселях) независимо от того, как меняется окно. Не могли бы вы, пожалуйста, дать больше советов?
2. Обратите внимание, что glPushMatrix и friends устарели в OpenGL 3.1
Ответ №2:
Спасибо SuperMaximo93. Я наконец заставил свой код работать. Вот мой код, в котором изменен размер окна. Приведенная ниже функция вызывается в обработчике WM_SIZE.
void OpenGlWindow::Resize(HWND hwnd)
{
// Get new window size
RECT rect;
int width, height;
GetClientRect(hwnd, amp;rect);
width = rect.right;
height = rect.bottom;
glClearColor(0.0, 0.0, 0.0, 0.0); //Set the cleared screen colour to black
glViewport(0, 0, width, height); //This sets up the viewport so that the coordinates (0, 0) are at the top left of the window
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//Back to the modelview so we can draw stuff
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(180, 1.0f, 0, 0);
glTranslatef(-1.0f, -1.0f, 0);
glScalef(2.0f/width, 2.0f/height, 1);
glTranslatef(2.0f, 2.0f, 0);
}