[英]Loading texture using SOILs OGL function and OpenGL
我有一个使用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.
似乎没有使用SOIL的答案,所以我将发布我的解决方案:
在顶点着色器中我做:
Texcoord = vec2(texcoord.x, 1.0-texcoord.y);
gl_Position = proj * view * model * vec4( position, 1.0 );
1.0-texcoord.y反转图像的y轴。 不是一个干净的解决方案,但它的工作原理。
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);
}
然后你可以这样做:
// At initialization
GLuint texture;
loadTexture(&texture, "filename.png");
// Drawing part
drawTexturedRect(25,25,256,256,texture);
这是我个人使用的,它完美无缺。 我正在使用Visual Studio 2012结合SDL和SOIL。
SOIL_load_image
将返回unsigned char*
yes,包含图像数据的数组。
然后你通常会使用glGenerateTextures
将这些数据提供给gl
,分配纹理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但在使用SOIL_LOAD_RGBA
一直正常工作时会崩溃,这可能会解决您的问题。
我仍然觉得使用SOIL_load_image
更容易。 我希望这有助于此。 还要检查土壤附带的SOIL源代码,看看发生了什么。
基本上,在命令中
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);
以上解决方案都不适合我。 我刚才遇到同样的问题,如下所示:
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中的错误/限制。 但是你可以通过像我这里所做的具体绝对路径来避免这种情况。
希望它也可以帮到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.