¿Cómo inicializar eficientemente la textura con ceros?
Necesito inicializar una textura OpenGL 2D con ceros.
¿Por qué? Renderizo esta textura con OpenCL. Aproximadamente, las etapas de renderizado son:
- Crear textura RGBA, inicializar con ceros (por lo que contiene píxeles negros transparentes)
- OpenCL: calcula el color de los píxeles donde algunos objetos son visibles y escríbelos en esta textura
- OpenGL: agregar mapeo de entorno a los píxeles transparentes y mostrar la imagen final
Por lo tanto, no necesito pasar cualquier dato de textura real a glTexImage2d
. Pero de acuerdo con la especificación, cuando paso data=NULL, la memoria de textura se asigna pero no se inicializa.
Asignar una memoria del lado del cliente llena de ceros y pasar a glTexImage2D
no es una muy buena opción, aunque solo se me ocurre una.
EDIT: En realidad quiero iniciar solo el componente alfa (RGB se anulará de todos modos), pero dudo que esto facilite la situación.
4 answers
Hay varias maneras de hacer esto:
1: Dado un ancho y una altura para una textura:
std::vector<GLubyte> emptyData(width * height * 4, 0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, &emptyData[0]);
Para obtener la máxima eficiencia, debe dejar algún tiempo entre cuando llame a esto y cuando OpenCL comience su trabajo.
2: Adjúntalo a un FBO y usa glClearBuffer.
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0); //Only need to do this once.
glDrawBuffer(GL_COLOR_ATTACHMENT0); //Only need to do this once.
GLuint clearColor[4] = {0, 0, 0, 0};
glClearBufferuiv(GL_COLOR, 0, clearColor);
Esto parece que debería ser más rápido, ya que no hay DMA CPU-GPU en marcha. Sin embargo, la vinculación y la desvinculación de las FBOS pueden introducir ineficiencias. Por otra parte, puede que no. Perfil a asegúrese.
Tenga en cuenta que esto solo funciona para formatos de imagen que se pueden usar como destinos de renderizado. Así que no texturas comprimidas.
3: Dados suficientes controladores, puede usar la nueva extensión ARB_clear_texture:
glClearTexImage(texture, 0, GL_BGRA, GL_UNSIGNED_BYTE, &clearColor);
Tenga en cuenta que esto solo funciona para formatos de imagen cuyos datos pueden proporcionarse mediante transferencias estándar de píxeles. Así que no formatos comprimidos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-29 14:03:12
Solo un aviso: La nueva extensión GL_ARB_clear_texture (núcleo en 4.4) aborda específicamente este problema.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-11 18:46:08
Tal vez pueda establecer la textura como el destino de renderizado para la primera pasada y dibujar una primitiva negra. Puede ser más rápido ya que no hay transferencia de memoria entre la ram y la tarjeta gráfica.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-25 18:36:47
-
glTexSubImage
está lleno de toda la imagen:GLfloat* pData = new GLfloat[1024*768*4]; memset(pData, 0x00, 1024*768*4*sizeof(GLfloat)); glBindTexture(GL_TEXTURE_2D, m_ImageTex); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 768, GL_RGBA, GL_FLOAT, pData); glBindTexture(GL_TEXTURE_2D, 0); delete pData;
-
Use Pixel Buffer para copiar datos de la gpu, este método es más rápido y mejor
I. init PBO
glGenBuffers(1, &m_PixelBuffer); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_PixelBuffer); glBufferData(GL_PIXEL_UNPACK_BUFFER, SCREEN_WIDTH*SCREEN_HEIGHT*4*sizeof(GLfloat), NULL, GL_STATIC_DRAW); GLfloat* pData = nullptr; pData = (GLfloat*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); memset(pData, 0x00, 1024*768*4*sizeof(GLfloat)); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
Ii.
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_PixelBuffer); glBindTexture(GL_TEXTURE_2D, m_ImageTex); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_RGBA, GL_FLOAT, NULL); glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-25 22:33:50