tutorial descargar actualizar opengl

descargar - opengl intel



¿Cómo inicializar eficientemente la textura con ceros? (4)

Necesito inicializar una textura OpenGL 2D con ceros.

¿Por qué? Represento esta textura con OpenCL. Aproximadamente, las etapas de renderizado son:

  1. Crear textura RGBA, inicializar con ceros (por lo que contiene píxeles negros transparentes)
  2. OpenCL: calcula el color de los píxeles donde algunos objetos son visibles y los escribe en esta textura
  3. OpenGL: agrega la asignación de entorno a los píxeles transparentes y muestra la imagen final

Por lo tanto, no es necesario pasar ningún 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 opción muy buena, aunque solo puedo pensar en una.

EDITAR: En realidad, quiero iniciar solo el componente alfa (RGB será sobrescrito de todos modos), pero dudo que esto facilite la situación.


  1. 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;

  2. usa Pixel Buffer para copiar datos de gpu, este método es más rápido y mejor

    yo. 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);


Hay varias formas 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 algo de tiempo entre cuando llama a esto y cuando OpenCL inicia su trabajo.

2: Adjuntarlo a un FBO y usar 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);

Parece que debería ser más rápido, ya que no hay CPU DMA GPU en marcha. Pero la unión y desvinculación de las OBF puede introducir ineficiencias. Por otra parte, puede que no. Perfíllo para estar seguro.

Tenga en cuenta que esto solo funciona para formatos de imagen que pueden usarse como objetivos de renderizado. Entonces no texturas comprimidas.

3: con 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 ser proporcionados por transferencias de píxeles estándar . Entonces no formatos comprimidos.



Tal vez pueda establecer la textura como el objetivo de representación para la primera pasada y dibujar una primitiva negra. Puede ser más rápido ya que no hay transferencia de memoria entre el ram y la tarjeta gráfica.