openGL - Save Complex Rendering in Memory for Future Restore

1

I'm developing a c ++ application using opengl, but my knowledge in c ++ and opengl is limited, especially in the latter.

I need to create a board similar to that of xadres, however for each execution of the program the size of the board will probably be different, arriving for example at 1000x1000 houses (not always quadric, can be rectangular also 1000x600). Each of these homes I render on screen using GL_QUADS is texturing with a .PNG image (some with alpha channel). The board is different for each program execution, but STATIC after it is created , that is, its appearance does not change during execution, but there are objects in the order 10% of the amount of houses that are dynamic . So if the board has 1000x1000 houses, there are 100 dynamic elements moving on it.

Consider that the function " DrawTabule (int W, short H) {} " works perfectly, and is able to render the board completely on screen. In this function, to render the board I use the for command. I need to change the dynamic elements at least 24 times per second, at least, similar to a video. For this I'm using glutTimerFunc and glutPostRedisplay . That is, upgrade at a rate of 41 millis (minimum).

The problem is that from a 82x82 tray, the program is unable to run 24 screen updates per second.

What I need is in the start of the program, render the board once only , and save it in memory. So the draw function provided in glutDisplayFunc (draw); would not create the board every time, but would only restore its original (initial) state by drawing only the dynamic elements on it, significantly reducing the need for processing , and improving PERFORMANCE . I believe this would ensure the ability to upgrade every 41 millis ().

Example:

bool background = false;

void desenhar(){
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);                   // Black and opaque    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     // Clear the color buffer (background)           

    glMatrixMode(GL_MODELVIEW);                             // To operate on Model-View matrix
    glLoadIdentity();  

    // SE AINDA NAO CRIOU O TABULEIRO CRIE
    if (!background){
        DesenharTabuleiro(qtdW(), qtdH());

        // AGORA SALVE A IMAGEM DO TABULEIRO NA MEMÓRIA
        // ISSO QUE NAO SEI COMO FAZER
        SalvarRenderizacaoNaMemoria();

        background = true;
    }else
        // ESTA FUNCÃO DEVERIA PEGAR A IMAGEM JÁ CRIADA 
        // E ARMAZENADA NA MEMÓRIA, E EXIBIR NA TELA
        // SEM A NECESSIDADE DE RECRIAR CADA UM DOS QUADS
        RestarurasBackground();

    /*
     * AGORA REDESENHA TODOS OBJETOS DINAMICOS
     */
}


// DEVERIA SER EXECUTADO A CADA 41 MILLIS, SEM ATRAZO
void Timer(int value) {
    glutPostRedisplay();          //REDESENHA O CENARIO
    glutTimerFunc( 41, Timer, 0); // PROGRAMA A PROXIMA ATUALIZACAO DE TELA
}


int main(int argc, char** argv) {
    glutInit(&argc, argv);                                                                              // Initialize GLUT  
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH );  // Set double buffered mode
    glutCreateWindow("OpenGL Setup Test");                                              // Create a window with the given title

    glewInit();

    glutInitWindowSize(Tela.width, Tela.height);        // Set the window's initial width & height          
    glutInitWindowPosition(0, 0);                       // Position the window's initial top-left corner
    glutFullScreen();                                   // Exibe em tela cheia      

    glutDisplayFunc(desenhar);                          // Register display callback handler for window re-paint        
    glutTimerFunc( 41, Timer, 0);             // First timer call immediately   

    glEnable(GL_DEPTH_TEST);  
    glEnable(GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);             

    glutMainLoop();                 // LOOP PROCESSADOR DE EVENTOS  
}

Possible Solution - FrameBuffer - Does not work!

I tried to save the board in memory through FrameBuffer , but I confess that I could not understand its operation, and not even how to restore the image after saving.

The code below is real, and has no effect (the screen turns black):

GLuint  fBuffer, // FRAME BUFFER
        tBuffer, // TEXTURE BUFFER
        rBuffer; // RENDER BUFFER

GLenum dBuffer[1];  

// ESTA FUNCÃO DEVERIA CRIAR O TABULEIRO E SALVÁ-LO NA MEMÓRIA
// ISSO PARECE NÃO FUNCIONAR        
bool gerarESalvarPlanta(){
    bool retorno = false;

    printf("\r\nRenderizando planta... ");  

    // ##########################################################################
    // CRIA OBJETOS PARA BUFFER
    fBuffer = 0;
    glGenFramebuffers(1, &fBuffer);     

    rBuffer = 0;
    glGenRenderbuffers(1, &rBuffer);        

    tBuffer = 0;
    glGenTextures(1,      &tBuffer);        

    dBuffer[0] = GL_COLOR_ATTACHMENT0;
    glDrawBuffers (1, &fBuffer);        

    // ATIVA O OBJETOS CRIADOS
    glBindFramebuffer(  GL_FRAMEBUFFER,   fBuffer);          
    glBindTexture(      GL_TEXTURE_2D,    tBuffer);    
    glBindRenderbuffer( GL_RENDERBUFFER,  rBuffer);  


    // ##########################################################################      
    // CRIA A IMAGEM EM BRANCO DO TAMANHO DO MAPA
    glTexImage2D(
        GL_TEXTURE_2D, 
        0,
        GL_RGB, 
        W(), 
        H(), 
        0,
        GL_RGB, 
        GL_UNSIGNED_BYTE, 
        NULL
    );

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //GL_NEAREST

    // VINCULA A TEXTURA AO BUFFER  
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, tBuffer);  
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tBuffer, 0);  


    // ##########################################################################      
    // DIMENCIONA O RENDER
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, W(), H());  

    // VINCULA O RENDER AO BUFFER
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rBuffer);  


    // VERIFICA POR ERROS
    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);  

    if (status == GL_FRAMEBUFFER_COMPLETE){
        // PRINTA OK
        printf("[OK]\r\n");  

        retorno = true; 
    }else{  
        std::cout << "[FALHA : " << status ;
        std::cout << " | GlError : " << glGetError() << "]" << std::endl;  
        return false;
    }    


    // AQUI EH ONDE EU RENDERIZO AS CENTENAS DE GL_QUADS
    // DO TABULEIRO, ESSA FUNCAO ESTA FUNCIONANDO PERFEITAMENTE
    // POR ISSO EU NÃO A REPRODUZO AQUI
    DesenharTabuleiro(qtdW(), qtdH());

    // DESATIVA
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);  
    glBindFramebuffer(GL_FRAMEBUFFER, 0);  

    return retorno;
}

/*
 * DESENHA UM QUADRADO/RETÂNGULO
 * O OBJETIVO DESTA FUNÇÃO E REDESENHAR NA TELA A IMAGEM DO
 * TABULEIRO DESENHADO NO INICIO DO PROGRAMA E ARMAZENADA
 * NO BUFFER
 * >> ISSO NAO FUNCIONA
 */
void buildQuadradoBufferText(float x, float y, float w, float h, float qW = 2, float qH = 2){
    glEnable(GL_TEXTURE_2D);      

    glBindTexture(GL_TEXTURE_2D, tBuffer);         
    glBindFramebuffer(GL_FRAMEBUFFER, fBuffer);        

    glBegin(GL_QUADS);

        glTexCoord2f(0, qH);
        glVertex2f( x   , y   );

        glTexCoord2f(qW, qH);    
        glVertex2f( x+w , y   );    

        glTexCoord2f(qW, 0);    
        glVertex2f( x+w , y-h );     

        glTexCoord2f(0  , 0);    
        glVertex2f( x   , y-h );

    glEnd();

    glDisable(GL_TEXTURE_2D);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);  
    glBindTexture(GL_TEXTURE_2D, 0);
}   

I kindly ask you to provide a practical example .

Thanks in advance for any help.

    
asked by anonymous 04.10.2016 / 11:46

0 answers