0

我正在尝试构建一个简单的OpenGL使用测试Tao.Framework。我需要画一个有纹理的正方形。到目前为止,我来到了这个:

private void simpleOpenGlControl1_Paint(object sender, PaintEventArgs e)
{
    simpleOpenGlControl1.InitializeContexts();

    Gl.glClearColor(0f, 0f, 0f, 0f);
    Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
    Gl.glOrtho(-1, 2, -1, 2, 1, -1);

    // Open image
    var fileName = @"C:\mypath\image.bmp";
    var bmp = new Bitmap(fileName);
    var bmpData = bmp.LockBits(
        new Rectangle(0, 0, bmp.Width, bmp.Height),
        ImageLockMode.ReadOnly,
        PixelFormat.Format24bppRgb);

    // Texture
    Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, (int)Gl.GL_RGB8,
        bmp.Width, bmp.Height, 0, Gl.GL_BGR_EXT,
        Gl.GL_UNSIGNED_BYTE, bmpData.Scan0);

    Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0);

    // Draw a square.
    Gl.glBegin(Gl.GL_POLYGON);
        Gl.glVertex2f(0, 0);
        Gl.glVertex2f(0, 1);
        Gl.glVertex2f(1, 1);
        Gl.glVertex2f(1, 0);
    Gl.glEnd();
}

正方形以预期的形状渲染,但没有纹理。我是新来的OpenGL,甚至更多Tao.Framework。我该如何解决?或者如何正确添加纹理?

编辑在@jp
的帮助下,我正在尝试这个:

    //...
    Gl.glEnable(Gl.GL_TEXTURE_2D);

    // Draw a square.
    Gl.glBegin(Gl.GL_POLYGON);

    Gl.glTexCoord2f(0, 0); Gl.glVertex2f(0, 0);
    Gl.glTexCoord2f(0, 1); Gl.glVertex2f(0, 1);
    Gl.glTexCoord2f(1, 1); Gl.glVertex2f(1, 1);
    Gl.glTexCoord2f(1, 0); Gl.glVertex2f(1, 0);

    Gl.glEnd();

但广场保持没有纹理。

4

1 回答 1

4

你至少想念

GL.Enable(GL.TEXTURE2D);

默认情况下未启用。

您还必须通过调用生成一个新的纹理槽:

int texID;
Gl.glGenTextures(1, texID); //where 1 is the count, and texID a new texture slot in the gpu

然后您必须绑定将应用所有进一步操作的纹理槽。

Gl.glBindTexture(Gl.GL_TEXTURE_2D, texID);

注意调用 Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0); 禁用当前纹理。

现在所有进一步的操作都指向该纹理,现在您可以通过调用将位图数据传递到该纹理槽:

Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, (int)Gl.GL_RGB8,
    bmp.Width, bmp.Height, 0, Gl.GL_BGR_EXT,
    Gl.GL_UNSIGNED_BYTE, bmpData.Scan0);

如果你想设置一些纹理参数,比如 texGen 和钳位,还有很多其他的东西,你可以在这里做,例如:

Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);

您的顶点声明还应该包含一些纹理坐标,或者您必须将纹理坐标生成设置为活动状态。

    GL.TexCoord(0,1); Gl.glVertex2f(0, 0);
    GL.TexCoord(0,0); Gl.glVertex2f(0, 1);
    GL.TexCoord(1,0); Gl.glVertex2f(1, 1);
    GL.TexCoord(1,1); Gl.glVertex2f(1, 0);

如果您希望自动生成这些坐标,您可以省略 GL.TexCoord 调用并通过以下方式启用它:

Gl.glEnable(Gl.GL_TEXTURE_GEN_S); //enable texture coordinate generation
Gl.glEnable(Gl.GL_TEXTURE_GEN_T);

Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP);

不要忘记解锁您的位图数据(即使垃圾收集器是必须的):

bmp.Unlock(bmpData);
于 2014-03-24T17:27:30.513 回答