2014-10-27 57 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