Хотите пример OpenGL 2D (VC ++, нарисуйте прямоугольник)

Я хочу создать высокопроизводительную 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 API-интерфейс для 2D-рисования или библиотека, такая как Direct2D / DirectWrite?


person Zach    schedule 04.05.2011    source источник


Ответы (2)


Я настоятельно рекомендую вам ознакомиться с некоторыми руководствами по 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 не имеет API для 2D-рисования, но с ним легко делать 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 не работает).

Надеюсь, это поможет!

person SuperMaximo93    schedule 04.05.2011
comment
Спасибо за ответ и ссылку на руководство. Однако проблема в том, что я не знаю, как настроить OpenGL для 2D-рисования, особенно как обеспечить размер прямоугольника в пикселях. (1) В учебнике все значения вершин выглядят как 0.5f, 1.0f. Но я хочу, чтобы они были в пикселях, например, 100, 200. (2) В учебнике размеры рисунков меняются при изменении размера окна. Я хочу, чтобы все рисунки оставались своего размера (в пикселях) независимо от того, как изменяется окно. Не могли бы вы дать еще несколько советов? - person Zach; 04.05.2011
comment
Обратите внимание, что glPushMatrix и его друзья устарели в OpenGL 3.1. - person anatoly techtonik; 07.12.2012

Спасибо SuperMaximo93. Я наконец-то заставил свой код работать. Вот мой код изменения размера окна. Функция ниже вызывается в обработчике WM_SIZE.

void OpenGlWindow::Resize(HWND hwnd)
{
    // Get new window size
    RECT rect;
    int width, height;

    GetClientRect(hwnd, &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);
}
person Zach    schedule 05.05.2011