es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

GLSL: Accediendo al píxel de una textura 2D cargada mediante TEXTURE_BUFFER

Estoy realizando algunas pruebas para cargar una imagen a través de un GLTEXTUREBUFFER. Estoy atascado en la correcta dirección de los píxeles desde texelFetch. El objetivo es simplemente mostrar una textura R8.

Aquí es cómo creo el búfer:

sz = width*height*sizeof(uint8)
glGenBuffers( 1, &pbo );        
glBindBuffer( GL_TEXTURE_BUFFER, pbo );
glBufferStorage( GL_TEXTURE_BUFFER, sz, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT |GL_MAP_COHERENT_BIT );

Lo cargo a través de un memcpy, los datos son uint8.

Y finalmente lo enlazo a la textura GLTEXTUREBUFFER:

glBindTexture( GL_TEXTURE_BUFFER, texture );
glTexBuffer( GL_TEXTURE_BUFFER, GL_R8, pbo );

En este paso, simplemente dibujo un rectángulo y paso las coordenadas uv al fragment shader
la función de dibujo es:

El tamaño es obviamente 640*480:

uniform samplerBuffer texture;
in vec2 uv;
...
float f;
f =  640. * 480. * (uv.y) +  640. * (uv.x);
index = int(f);
color.r = texelFetch( texture, index )[0];

He intentado normalizar color.r ( / 255.f ) pero nada funciona. El comportamiento extraño es que si modifico la geometría de la ventana, la salida del shader cambia constantemente y en ciertas dimensiones puedo ver la textura. No entiendo eso porque mis coordenadas uv no cambian (regulares 0,1 1,1 … para un cuadrado simple).

Mi cálculo de indexación es incorrecto, es por eso que quería saber si alguien podría señalar el problema.

(He probado el shader con un GLTEXTURE2D regular, un GLPIXELUNPACK_BUFFER, un sampler2D y no hay problema).

EDIT 1:

He intentado pasar las dimensiones de la imagen como coordenadas uv.

uv_min = {0,0}
uv_max = {640,480}

y calcular el índice en el fragmento como:

int index = int( 640.*uv.y + 640.*uv.x)

sin éxito.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema está en el cálculo del índice en el fragment shader. Como la textura es un GL_TEXTURE_BUFFER con formato GL_R8, cada texel está representado por un solo byte (uint8), lo que significa que la función texelFetch devolverá un único valor uint. Por lo tanto, para acceder al texel en un índice específico, el cálculo del índice debería ser el siguiente:

    float f = float(width * int(uv.y * height) + int(uv.x * width));
    int index = int(f);
    color.r = texelFetch(texture, index)[0] / 255.0;
    

    Aquí, la variable f se utiliza para calcular el índice del texel, que luego se convierte a un valor entero y se pasa a la función texelFetch. El valor uint devuelto se accede en el primer índice (0) y se divide por 255.0 para normalizarlo.

    Además, como las coordenadas de la textura están normalizadas (de 0 a 1), es necesario multiplicarlas por el ancho y alto de la imagen para calcular el índice correcto.

    Ten en cuenta que para asegurarte de que las coordenadas de la textura se pasen correctamente al shader, la variable uv debería declararse como un vec2 con el calificador in, y las coordenadas de la textura correctas se deben pasar a la función de dibujo.

    in vec2 uv;
    
    glVertexAttribPointer(uvAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, uvBufferData);
    

    Con estos cambios, el GL_TEXTURE_BUFFER debería mostrar correctamente la textura R8.

Comments are closed.