想要一个OpenGL 2D示例(VC ++,绘制一个矩形)

时间:2011-05-04 02:11:51

标签: 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绘图API或者像Direct2D / DirectWrite这样的库?

2 个答案:

答案 0 :(得分:9)

我强烈建议您查看一些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绘图API,但只是忽略Z轴(或者只是使用Z轴确保精确度绘制在正确的深度,因此您可以绘制前景后的背景,因为背景的深度已设置,因此它位于前景后面)。希望这可以帮助。绝对花点时间看一些教程,一切都会变得清晰。

修改: 要设置用于2D绘图的OpenGL,您需要设置正交投影(我链接到的教程使用透视投影,抱歉没有提到)。这是我的一些代码的例子(在你创建窗口后,它应该在你的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中执行此操作,尽管来自GLUT的glutGet(GLUT_WINDOW_WIDTH)和glutGet(GLUT_WINDOW_HEIGHT)可能会工作,但我还没有测试过),然后再次使用更新的窗口大小调用glViewport和glOrtho。

同样,当窗口大小发生变化时,你必须使用外部库来找出 。我不确定你可以使用什么,虽然如果你碰巧使用SDL那么它可能会有一些事件处理(并且可能能够返回屏幕宽度和高度,如果glutGet不起作用)。

我希望这有帮助!

答案 1 :(得分:3)

感谢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);
}