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.