2015-06-14 84 views
0

我想用C++編寫一個簡單的遊戲,使用OpenGL進行圖形編程。在我的遊戲中,我有作爲白色方塊呈現在屏幕上的對象。我希望能夠將圖像作爲紋理綁定到這些對象,以便我可以在屏幕上呈現圖像而不是白色方塊。對圖像的格式沒有限制,但我一直在使用.png或.bmp進行測試。無法渲染四維紋理

我的一個對象類Character.h存儲名爲_texture的GLuint *成員變量和名爲_data(分別作爲圖像句柄和像素數據)的無符號char *成員變量。內Character.h是這個函數意味着將圖像結合作爲紋理的字符對象:

void loadTexture(const char* fileName) 
    { 
     /* read pixel data */ 
     FILE* file; 
     file = fopen(fileName, "rb"); 
     if (file == NULL) {cout << "ERROR: Image file not found!" << endl;} 
     _data = (unsigned char*)malloc(_dimension * _dimension * 3); 
     fread(_data, _dimension * _dimension * 3, 1, file); 
     fclose(file); 
     /* bind texture */ 
     glGenTextures(1, &_texture); // _texture is a member variable of type GLuint 
     glBindTexture(GL_TEXTURE_2D, _texture); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _dimension, _dimension, 0, GL_RGB, GL_UNSIGNED_BYTE, _data); // _dimension = 64.0f. 
    } 

一旦圖像被綁定,我然後嘗試使與該功能角色對象(這是一個靜態函數在一個單獨的類中找到):

static void drawTexturedRectangle(float x, float y, float w, float h, GLuint texture, unsigned char* data) 
    { 
     /* fractions are calculated to determine the position onscreen that the object is drawn at */ 
     float xFraction = (x/GlobalConstants::SCREEN_WIDTH) * 2; 
     float yFraction = (y/GlobalConstants::SCREEN_HEIGHT) * 2; 
     float wFraction = (w/GlobalConstants::SCREEN_WIDTH) * 2; 
     float hFraction = (h/GlobalConstants::SCREEN_HEIGHT) * 2; 
     glEnable(GL_TEXTURE_2D); 
     glClear(GL_COLOR_BUFFER_BIT); 
     glBindTexture(GL_TEXTURE_2D, texture); 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data); 
     glPushMatrix(); 
     glEnable(GL_BLEND); 
     glBegin(GL_QUADS); 
     glTexCoord2f(0.0f, 0.0f); glVertex2f(xFraction, yFraction); // bottom left corner 
     glTexCoord2f(0.0f, 1.0f); glVertex2f(xFraction, yFraction + hFraction); // top left corner 
     glTexCoord2f(1.0f, 1.0f); glVertex2f(xFraction + wFraction, yFraction + hFraction); // top right corner 
     glTexCoord2f(1.0f, 0.0f); glVertex2f(xFraction + wFraction, yFraction); // bottom right corner 
     glEnd(); 
     glDisable(GL_BLEND); 
     glPopMatrix(); 
    } 

不管我有多麼混亂圍繞這個問題,我似乎無法讓我的程序做比呈現純白色的廣場上也沒有質感其他任何東西。我已經檢查過以確保變量文件,_texture,_dimension和_data都包含值。任何人都可以發現我可能做錯了什麼?

+0

我不認爲這是你的問題的原因,但你不應該叫'glTexImage2D'要繪製紋理每一次 - 你怎麼稱呼它一次,加載紋理時。之後,您可以丟棄客戶端內存中的數據,因爲您已將其交給OpenGL,後者將對其進行管理,並且您只需再次綁定紋理即可告知OpenGL您想使用它。 – orost

+0

我不知道其他代碼,但在調用loadTexture()函數之前,請確保您有一個'glEnable(GL_TEXTURE_2D);'調用。 – aslg

回答

0

我不認爲你可以只輸入一個原始文件到glTexImage2D,除非你存儲紋理文件的格式(你可能不會)。 glTexImage2D需要一個巨大的數組字節(代表紋理顏色),但文件格式通常不會像這樣保存圖像。即使bmp也有一些標題信息。

使用像Devil或SOIL的第三方圖像加載器庫來加載您的紋理!這些庫可以將最常見的圖像文件格式(png,jpg,tga,...)轉換爲可以輸入到OpenGL的字節流!

附註: 調用glTexImage2D(...,data)後,數據內容被複制到GPU內存(VRAM)中。從這一點開始,你只需要使用它的id來綁定紋理,因爲它已經在VRAM中了。在每個幀中調用glTexImage2D()會將每幀中的整個紋理重新上傳到vram中,從而導致較大的性能損失。

+0

非常感謝agnu17!我用它來使用SOIL。 loadTexture方法簡單地變爲:_texture = SOIL_load_OGL_texture(fileName,SOIL_LOAD_AUTO,SOIL_CREATE_NEW_ID,SOIL_FLAG_INVERT_Y);我讀過這可能只適用於8位.png出於任何原因。 – tomdunkle0