2012-02-14 82 views
1

爲了使我的迷宮類型遊戲更快,我決定將我的拖動球放入紋理中,因爲我必須爲每個房間繪製一次,並且我將它繪製爲凹多邊形使用模板緩衝區需要比使用紋理更多的時間。問題是,自從遊戲開始以來渲染第三幀時,我正在從後臺緩衝區中正確地獲取紋理,並且我的問題是,爲什麼它是這樣?在OpenGL中將緩衝區內容填充到紋理中

當我從口渴的框架使用紋理時,我具有純白色的紋理,所以它裏面沒有任何東西。當我使用第二幀的紋理時,我只有所需紋理的黑色背景,而當我從第三幀取紋理時,則具有所需的紋理。對於幀計數,我使用「drawTexture」函數內的靜態變量「done」。從第一幀

複製:

enter image description here

從第三幀複製(期望的結果)::

enter image description here

從第二幀

enter image description here

複製

void DrawBall::drawTexture(float imageD) { 
    static int done = 0; 

    if (done < 3) { 
     drawToTexture(imageD); 
     done++; 
    } 

    glEnable(GL_TEXTURE_2D); 
    glBindTexture (GL_TEXTURE_2D, texture); 

    glColor3f(1, 1, 1); 
    glBegin (GL_QUADS); 
     glTexCoord2f (0.0, 0.0); glVertex3f (0.0, 0.0, -imageD);  
     glTexCoord2f (1.0, 0.0); glVertex3f (5.0, 0.0, -imageD); 
     glTexCoord2f (1.0, 1.0); glVertex3f (5.0, 5.0, -imageD);  
     glTexCoord2f (0.0, 1.0); glVertex3f (0.0, 5.0, -imageD); 
    glEnd(); 

    glDisable(GL_TEXTURE_2D); 
} 

void DrawBall::drawToTexture(float imageD) { 
    int viewport[4]; 
    glGetIntegerv(GL_VIEWPORT, (int*) viewport); 

    int textureWidth = 64; 
    int textureHeight = 64; 

    texture = genEmptyTexture(textureWidth, textureHeight); 

    glViewport(0, 0, textureWidth, textureHeight); 
    glMatrixMode(GL_PROJECTION);        
    glLoadIdentity();          
    gluPerspective(45.0f, 1, 1, 100); 
    glMatrixMode(GL_MODELVIEW);       
    glLoadIdentity();          

    /* 
     This function calculates the vertexes for the ball 
     inside a vector<vector<float>> variable "test" 
    */ 
    _calculateCircleVertexes(0.0f, 0.0f, -2.0f, 0.249f, &test, 20); 

    _displayBall(&test, 0.0f, 0.0f, 0.5f, -2.0f, &*smallBallColor); 

    glBindTexture(GL_TEXTURE_2D, texture); 
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, textureWidth, textureHeight, 0); 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 

    glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); 
    glMatrixMode(GL_PROJECTION);  
    glLoadIdentity();    
    gluPerspective(45.0f, (GLfloat)viewport[2]/(GLfloat)viewport[3], 1.0f, imageD + 10.0f); 
    glMatrixMode(GL_MODELVIEW);  
    glLoadIdentity(); 
} 

GLuint DrawBall::genEmptyTexture(unsigned int width, unsigned int height) { 
    GLuint txtIndex; 

    glGenTextures(1, &txtIndex);          
    glBindTexture(GL_TEXTURE_2D, txtIndex);       

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, 
    GL_RGB, GL_UNSIGNED_BYTE, NULL);        

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 

    return txtIndex; 
} 

void DrawBall::_displayBall(vector<vector<GLfloat>> *vertexes, GLfloat x, GLfloat y 
         , GLfloat imageW, GLfloat imageD, color *color) { 
    glTranslatef(x, y, imageD); 

    glClearStencil(0); 
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
    glEnable(GL_STENCIL_TEST); 
    glStencilFunc(GL_NEVER, 0, 1); 
    glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT); 

    glBegin(GL_POLYGON); 
     vector<vector<GLfloat>>::iterator it = vertexes->begin(); 
     for (; it != vertexes->end(); it++) { 
      glVertex3f((*it)[0], (*it)[1], 0.0f); 
     } 
    glEnd(); 

    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
    glStencilFunc(GL_EQUAL, 1, 1); 
    glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); 

    glColor3f(color->r, color->g, color->b); 
    glBegin(GL_QUADS); 
     glVertex3f(-(imageW/2.0f), -(imageW/2.0f), 0.0f); 
     glVertex3f((imageW/2.0f), -(imageW/2.0f), 0.0f); 
     glVertex3f((imageW/2.0f), (imageW/2.0f), 0.0f); 
     glVertex3f(-(imageW/2.0f), (imageW/2.0f), 0.0f); 
    glEnd(); 

    glDisable(GL_STENCIL_TEST); 

    glTranslatef(x, y, -imageD); 
} 

回答

0

好吧,Datenwolf,謝謝你的建議,你可能是對的,但我只想盡量少用先進的東西,我發現我的錯誤。在第二幀之前我沒有得到期望的結果,因爲我還沒有啓用模板測試。在第一幀之前,我沒有得到期望的結果,因爲在窗口創建中,Windows發送了WM_SIZE消息,並且在其中有繪製消息,但那時OpenGL還沒有正確設置。

2

對於渲染到紋理操作,您不應該使用窗口framebuffer(它包括後臺緩衝區和前臺緩衝區)。它只是輕鬆打破(你已經體驗過它)。取而代之,使用所謂的幀緩衝對象,紋理作爲渲染目標。