2014-10-27 36 views
2

我试图用DevIL加载图像,然后创建一个纹理。我有一个名为Texture的类,我在构造函数中完成了所有这些工作。一个有效的上下文已经创建。我在第一次致电glTextureParameteri()时遇到了访问冲突,所以我猜想纹理没有正确绑定。我只看到没有理由为什么它不会绑定。使用OpenGL和DevIL调用glTextureParameteri时的访问冲突

这里的构造函数:

Texture::Texture(const std::string& filename){ 
//DevIL handle for the image 
unsigned int ilID; 

ilGenImages(1, &ilID); 

ilBindImage(ilID); 

ilEnable(IL_ORIGIN_SET); 
ilOriginFunc(IL_ORIGIN_LOWER_LEFT); 

if (!ilLoad(IL_BMP, (ILstring)filename.c_str())){ 
    DebugUtility::gl_log_err("Failed to load image &s\n", filename.c_str()); //Just function that prints to log file 
    return; 
} 
ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); 

glGenTextures(1, &texture); 

//"texture" is global GLuint 
glBindTexture(GL_TEXTURE_2D, texture); 

//LINE BELOW CAUSES ACCESS VIOLATION! 
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 

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

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 
    ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 
    0, GL_RGBA, GL_UNSIGNED_BYTE, ilGetData()); 

ilDeleteImages(1, &ilID); 
//Again, prints to log file 
DebugUtility::gl_log("Succefully loaded and created texture %s", filename.c_str()); 
} 

ilLoad返回true,因为不执行,如果块中的代码。这里是错误(我正在使用Visual Studio 2013):

projectSDL.exe中0x74E1CB49未处理的异常:0xC0000005:执行位置0x00000000的访问冲突。

回答

4

功能glTextureParameteri()是一个扩展,尝试使用glTexParameteri()和结合活性纹理单元glActiveTexture(GL_TEXTURE0)glTextureParameteri()也期望纹理ID,而不是目标。

+0

'glTextureParameter()'在OpenGL 4.5中是标准的。我希望人们第一次看到它时会把它和glTexParameter()混淆起来。有时你想知道OpenGL中的API设计选择...... – 2014-10-27 15:14:01

+0

工作!事实上,容易搞砸那些功能... – Heiski 2014-10-27 15:17:33

2

glTextureParameter()是OpenGL 4.5的新入门点。它是被称为直接状态访问的家庭的一部分(通常由缩写DSA提及)。在4.5中升级到核心功能之前,它在EXT_direct_state_access扩展中定义。

这个想法是,你可以修改对象的状态而不绑定它们。这可以通过减少API调用和驱动程序开销来提高效率。

这些新的入口点采取对象名称作为第一个参数,相比于相应的年龄较大的入口点,这需要目标作为第一个参数。在你的情况,你要么必须使用旧的切入点:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 

(注意Tex代替Texture),或通过纹理名作为第一个参数,而不必首先绑定质地:

glTextureParameteri(texture, GL_TEXTURE_WRAP_S, GL_REPEAT); 

[警告,这一段是根据意见和可能引起争议不幸的是,进行的方式,使他们很容易混淆与以前的入口点定义的入口点。虽然OpenGL从来没有被设计成特别对程序员友好,但我预测会有更多的人被这些新的入口点绊住,这些入口点与现有的名称非常相似,并且具有相同的签名。它看起来像一个非常不幸的API设计给我。

+0

那么,女巫一个更好用? Tex如果只进行一次调用就可以进行多个调用和纹理? – Heiski 2014-10-27 18:15:10

+1

我可能会坚持使用'glTexParameter()',除非您有充分的理由相信您需要使用DSA才能达到您的性能目标。主要是因为OpenGL 4.5规范在几个月前才发布,所以对它的支持将不会被广泛使用。很大程度上限制哪些机器可以运行您的代码似乎并不值得,除非您严格依赖这些最新功能。 – 2014-10-27 22:33:30