我尝试绘制一个带有纹理的矩形,但我得到的只是一个白色矩形。为什么?

发布于 2024-12-13 14:04:16 字数 2852 浏览 0 评论 0原文

我正在尝试使用一些 OpenGL。经过一段时间的尝试后,我能够画出彩色的几何形状。现在,我想在这些形状上添加纹理。

所以,我创建了一个纹理。看起来创建得不错。然后我尝试绘制它,但我得到的只是一个白色矩形。

该代码实际上分布在 NSOpenGLView 的三个方法中,但我将其全部放在一个代码块中以节省空间。

// ----- Set up OpenGL (this code is adapted from the NeHe OpenGL tutorial) -----

GLuint textureName = 0;
glEnable(GL_TEXTURE_2D);    
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

// ----- I load the image: (This code is adapted from some sample code from Apple) -----

NSImage *image = dataSource.image; // get the original image
NSBitmapImageRep* bitmap = [NSBitmapImageRep alloc];

[image lockFocus];
[bitmap initWithFocusedViewRect:
 NSMakeRect(0.0, 0.0, image.size.width, image.size.height)];
[image unlockFocus];

// Set proper unpacking row length for bitmap.
glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.pixelsWide);

// Set byte aligned unpacking (needed for 3 byte per pixel bitmaps).
if (bitmap.samplesPerPixel == 3) {
    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
}

// Generate a new texture name if one was not provided.
if (textureName == 0)
    glGenTextures (1, &textureName);
glBindTexture (GL_TEXTURE_2D, textureName);

// Non-mipmap filtering (redundant for texture_rectangle).
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,  GL_LINEAR);

// RGB 24 bit bitmap, or RGBA 32 bit bitmap
if(bitmap.samplesPerPixel == 3 || bitmap.samplesPerPixel == 4) {
    glTexImage2D(GL_TEXTURE_2D, 0,
                 bitmap.samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8,
                 bitmap.pixelsWide,
                 bitmap.pixelsHigh,
                 0,
                 bitmap.samplesPerPixel == 4 ? GL_RGBA : GL_RGB,
                 GL_UNSIGNED_BYTE,
                 bitmap.bitmapData);
}

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

[bitmap release];

// ----- Drawing code (This code is adapted from the NeHe OpenGL tutorial) -----

glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

if (textureName) {
    glBindTexture(GL_TEXTURE_2D, textureName);
    glBegin(GL_QUADS);
    {
        glTexCoord2f(1.0, 0.0); glVertex3f( 0.5, -0.5, 0.0);
        glTexCoord2f(1.0, 1.0); glVertex3f( 0.5,  0.5, 0.0);
        glTexCoord2f(0.0, 1.0); glVertex3f(-0.5,  0.5, 0.0);
        glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, -0.5, 0.0);
    }
    glEnd();
}

glFlush();

唉,我得到的只是在黑暗中看到一个具有预期大小的白色矩形。

我还尝试到处插入一些 glGetError() ,但似乎没有发生错误。

为什么我的纹理不显示?任何提示将不胜感激。

编辑:

如果我用 glEnable(GL_TEXTURE_2D)glDisable(GL_TEXTURE_2D) 包围绘图代码,则纹理绘制得很好。但我已经在设置代码中做到了这一点。为什么我还要再做一次?

I am trying to use a bit of OpenGL. After playing around with it for a while, I was able to draw colored geometric shapes. Now, I want to put a texture on these shapes.

So, I create a texture. It seems to be created alright. Then I try to draw it, but all I get is a white rectangle.

The code is actually spread over three methods of a NSOpenGLView, but I put it all in one code block here to save space.

// ----- Set up OpenGL (this code is adapted from the NeHe OpenGL tutorial) -----

GLuint textureName = 0;
glEnable(GL_TEXTURE_2D);    
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

// ----- I load the image: (This code is adapted from some sample code from Apple) -----

NSImage *image = dataSource.image; // get the original image
NSBitmapImageRep* bitmap = [NSBitmapImageRep alloc];

[image lockFocus];
[bitmap initWithFocusedViewRect:
 NSMakeRect(0.0, 0.0, image.size.width, image.size.height)];
[image unlockFocus];

// Set proper unpacking row length for bitmap.
glPixelStorei(GL_UNPACK_ROW_LENGTH, bitmap.pixelsWide);

// Set byte aligned unpacking (needed for 3 byte per pixel bitmaps).
if (bitmap.samplesPerPixel == 3) {
    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
}

// Generate a new texture name if one was not provided.
if (textureName == 0)
    glGenTextures (1, &textureName);
glBindTexture (GL_TEXTURE_2D, textureName);

// Non-mipmap filtering (redundant for texture_rectangle).
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,  GL_LINEAR);

// RGB 24 bit bitmap, or RGBA 32 bit bitmap
if(bitmap.samplesPerPixel == 3 || bitmap.samplesPerPixel == 4) {
    glTexImage2D(GL_TEXTURE_2D, 0,
                 bitmap.samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8,
                 bitmap.pixelsWide,
                 bitmap.pixelsHigh,
                 0,
                 bitmap.samplesPerPixel == 4 ? GL_RGBA : GL_RGB,
                 GL_UNSIGNED_BYTE,
                 bitmap.bitmapData);
}

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

[bitmap release];

// ----- Drawing code (This code is adapted from the NeHe OpenGL tutorial) -----

glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

if (textureName) {
    glBindTexture(GL_TEXTURE_2D, textureName);
    glBegin(GL_QUADS);
    {
        glTexCoord2f(1.0, 0.0); glVertex3f( 0.5, -0.5, 0.0);
        glTexCoord2f(1.0, 1.0); glVertex3f( 0.5,  0.5, 0.0);
        glTexCoord2f(0.0, 1.0); glVertex3f(-0.5,  0.5, 0.0);
        glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, -0.5, 0.0);
    }
    glEnd();
}

glFlush();

Alas, all I get is a white rectangle of the intended size in a see of blackness.

I also tried inserting a few glGetError()s here and there, but there seems to be no error happening.

Why does my texture not show up? Any hints would be greatly appreciated.

Edit:

The texture is drawn fine if I surround the drawing code with glEnable(GL_TEXTURE_2D) and glDisable(GL_TEXTURE_2D). But I did that in the set up code already. Why do I have to do it again?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请帮我爱他 2024-12-20 14:04:16

如果我用 glEnable(GL_TEXTURE_2D) 和 glDisable(GL_TEXTURE_2D) 包围绘图代码,则纹理绘制得很好。但我已经在设置代码中做到了这一点。

我本来会建议的,但你已经发现了。

为什么我必须再做一次?

因为OpenGL是一个状态机,实际上OpenGL中不存在“一次性初始化”之类的东西。可以随时启用和禁用功能。因此,推荐的做法是将所有 OpenGL 操作保留在显示例程中。这包括设置投影、启用所需的功能。

The texture is drawn fine if I surround the drawing code with glEnable(GL_TEXTURE_2D) and glDisable(GL_TEXTURE_2D). But I did that in the set up code already.

I would have suggested, but you found out already.

Why do I have to do it again?

Because OpenGL is a state machine and in fact there is no such thing like "one time initialization" in OpenGL. Functionality can be enabled and disabled at any time. So the recommended practice is to keep all OpenGL operation within the display routine. This includes setting the projection, enabling required functionality.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文