3

我有一个使用 SOIL 从 JPEG 图像加载纹理的功能。

到目前为止,我一直在使用该SOIL_load_image()函数加载纹理,然后使用glTexImage2D(参见下面的代码)将图像提供给 OpenGL。然而!我的纹理是颠倒的,所以我想SOIL_load_OGL_texture()改用 并提供SOIL_FLAG_INVERT_Y来翻转图像。不过,我的问题是,我在SOIL_load_OGL_texture()函数中遇到了未处理的异常。

代码几乎是文档中的复制粘贴,所以我不明白为什么会出现这个错误?

(注意:我可以在顶点着色器中反转纹理,但我想使用 SOIL。)

老办法

int width;
int height;

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);

image = SOIL_load_image(filename, &width, &height, 0, SOIL_LOAD_RGB);

if (image == NULL) {
    std::cout << "An error occurred while loading image." << std::endl;
    exit(EXIT_FAILURE);
}
std::cout << "Loaded first texture image" << std::endl;

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);

我现在正在尝试什么

GLuint image;

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);

image = SOIL_load_OGL_texture(
        filename,
        SOIL_LOAD_RGB,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_INVERT_Y
    );

if (image == 0)
    cerr << "SOIL loading error: '" << SOIL_last_result() << "' (" << "res_texture.png" << ")" << endl;

和错误

Unhandled exception at 0x0F5427FF (msvcr110d.dll) in AnotherTutorial.exe: 0xC0000005: Access violation reading location 0x00000000.
4

5 回答 5

1
void loadTexture(GLuint* texture, char* path){
    *texture = SOIL_load_OGL_texture(filename,
                                     SOIL_LOAD_AUTO,
                                     SOIL_CREATE_NEW_ID,
                                     SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_MULTIPLY_ALPHA
                                    );
    if(*textre == NULL){
        printf("[Texture loader] \"%s\" failed to load!\n", filename);
    }
}

void drawTexturedRect(int x, int y, int w, int h, GLuint texture){
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDepthMask(GL_FALSE);
    glDisable(GL_DEPTH_TEST);
    glBegin(GL_QUADS);
        glColor3f(255,255,255);
        glTexCoord2f(0,0);
        glVertex2f(x,y);
        glTexCoord2f(1,0);
        glVertex2f(x+w,y);
        glTexCoord2f(0,1);
        glVertex2f(x,y+h);
        glTexCoord2f(1,1);
        glVertex2f(x+w,y+h);
        glTexCoord2f(0,1);
        glVertex2f(x,y+h);
    glEnd();
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDisable(GL_BLEND);
}

And then you can do:

// At initialization
GLuint texture;
loadTexture(&texture, "filename.png");

// Drawing part
drawTexturedRect(25,25,256,256,texture);

This is what I personally use, and it works perfectly. I'm using Visual Studio 2012 combined with SDL and SOIL.

于 2013-09-30T11:48:09.107 回答
1

似乎没有使用 SOIL 的答案,所以我将发布我的解决方案:

在顶点着色器中,我这样做:

Texcoord = vec2(texcoord.x, 1.0-texcoord.y);
gl_Position = proj * view * model * vec4( position, 1.0 );

1.0-texcoord.y 反转图像的 y 轴。不是一个干净的解决方案,但它有效。

于 2013-06-05T15:00:39.310 回答
0

基本上,在命令中

SOIL_load_image(filename, &width, &height, 0, SOIL_LOAD_RGB);

您传递的 0 (NULL) 是指向库设置的通道的指针,因此,当然,当库尝试访问它时,您有:

AnotherTutorial.exe 中 0x0F5427FF (msvcr110d.dll) 处未处理的异常:0xC0000005:访问冲突读取位置 0x00000000

尝试声明一个变量并使用它:

int channels;
SOIL_load_image(filename, &width, &height, &channels, SOIL_LOAD_RGB);
于 2015-02-05T15:34:14.220 回答
0

SOIL_load_image将返回unsigned char*是,数组保存您的图像数据。

然后,您通常会将这些数据提供给glusing glGenerateTextures,分配纹理 ID,调用glTexImage2D.

SOIL_load_OGL_texture返回一个纹理 id,所以你可以这样做:

texture[0] = SOIL_load_OGL_texture(...)

如果您的目标是加载纹理 0、1、2。

至于反转 y,最简单且无重量的解决方案是将纹理坐标翻转到 中glTexCoord,但这取决于您在做什么。如果您将资源加载为一次性操作或类似操作,它不会受到伤害,除了一些启动时间可能不值得一提。但是,如果您在需要时通过主循环动态加载资源,则反转 y 标志(以及任何标志)可能会因为整个程序中的额外处理而损害性能。

使用的一大优势SOIL_load_image是您可以SOIL_load_OGL_texture从不提供的原始图像中检索宽度、高度和通道号。

如果它有帮助,SOIL_load_OGL_texture在将 RGB 图像加载为 RGB 时会在一段时间后崩溃,但在 RGB 上一直运行良好SOIL_LOAD_RGBA,这可能会解决您的问题。

我仍然发现它更容易使用SOIL_load_image. 我希望这会有所帮助。还要检查随土壤一起提供的 SOIL 源代码,看看发生了什么。

于 2013-12-27T01:53:06.960 回答
0

上述解决方案都不适合我。我刚才也有同样的问题,像下面这样:

SOIL_load_OGL_texture Unhandled exception at xxxxxx (msvcr120d.dll)

http://www.idevgames.com/forums/thread-10281.html阅读解决方案后,我将路径从“相对路径”更改为“绝对路径”。

顺便说一句,由于我是中国人,我需要确保路径是全英文的,没有非 ascii 字符。

例如:

我将我的代码从

SOIL_load_OGL_texture("my_texture.bmp",
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_MULTIPLY_ALPHA
        );

SOIL_load_OGL_texture("D:\temp_20160926\ConsoleApplication20\ConsoleApplication19\my_texture.bmp",
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_MULTIPLY_ALPHA
        );

它完美地解决了我的问题。

我认为这是 SOIL 中的错误/限制。但是你可以像我在这里做的那样通过特定的绝对路径来避免这种情况。

希望它也能帮助你。

于 2016-11-01T16:34:51.047 回答