2011-09-11 12 views
5

Recibí una segfault cuando traté de cargar una imagen de 771x768.glTexImage2D Segfault relacionado con el ancho/alto

Probé con una imagen de 24x24 y 768x768 y funcionó, no hay problema.

¿Se espera esto? ¿Por qué no simplemente falla con gracia con un error GL?

La falla de segmentación se produce en la llamada glTexImage2D. Estoy cargando un archivo binario de PPM, por lo que está empaquetado a 24 bits por píxel. Este número impar combinado con una dimensión impar probablemente produzca una estructura alineada no de 4 bytes (o incluso de 2 bytes) (y hacer referencia fuera de mi memoria intermedia asignada lo suficiente puede ser la causa del error, pero gdb no me muestra una memoria dirección (que podría usar para averiguar si esto es lo que lo causa)).

glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, dataptr); 
// in this specific case of failure, width = 771, height = 768, 
// dataptr contains 1776384 bytes of binary RGB image data (771*768*3 = 1776384) 
+2

¿Dónde se produce la segfault? ¿Cómo se ve tu código? – Goz

+0

pregunta actualizada con algunos detalles. Creo que tengo una idea sobre lo que salió mal. Necesita probar más –

+0

Sin embargo, todavía no hay código. – Goz

Respuesta

14

Este número impar combinada con una dimensión extraña probablemente produce una no-4-byte (o incluso de 2 bytes) alineado estructura (y haciendo referencia fuera de mi búfer asignado exactamente lo suficiente puede ser la causa del error

Esta es probablemente la causa. Afortunadamente puede establecer la alineación OpenGL utiliza datos de píxeles de lectura. Justo antes de llamar a glTexImage…(…) do

glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); 
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); 
+0

Esto hizo el truco. –

+0

¿Hay algún enlace donde pueda leer más sobre la estructura alineada de 4/2 bytes? –

+1

@BenediktBock: no hay mucho para eso. La alineación n solo significa que el inicio de un conjunto particular de datos (una fila de píxeles, un píxel en sí mismo) ocurre, así que comience en una dirección de memoria que sea un múltiplo entero de n. La mayoría de las arquitecturas de CPU tienen ciertas restricciones de alineación que se deben seguir; por ejemplo, ARM de 32 bits quiere que todo esté alineado a 16 bit = 2 byte o 32 bit = 4 byte boundaries (dependiendo de la versión de la arquitectura ARM). Las CPU Intel pueden hacer operaciones atómicas solo a 4 bytes de alineación. Por lo tanto, encontrará formatos de estructura que alinean los datos a algunos n = 2, 4 u 8 para simplificar las cosas. – datenwolf

1

He leído esto en los foros de OpenGL:

width must be 2^m + 2(border) for some integer m. 
height must be 2^n + 2(border) for some integer n. 

(source)

yo encontramos este que creo que aclara lo que está sucediendo:

1. What should this extension be called? 

    STATUS: RESOLVED 

    RESOLUTION: ARB_texture_non_power_of_two. Conventional OpenGL 
    textures are restricted to size dimensions that are powers of two. 

de GL_ARB_texture_non_power_of_two

+0

Esto es relevante solo para OpenGL-1.x. Dado que los tamaños de textura arbitrarios OpenGL-2.x están permitidos. – datenwolf

+0

Desde que resolví el problema, escribí una pequeña prueba que itera a través de todas las permutaciones de pares de números enteros desde 64 hasta 1024, cargando una textura con esas dimensiones. (por ejemplo, 64x64, 64x65 ... 64x1024, 65x64, ...), hasta el momento casi ha llegado a la mitad de las 921,600 resoluciones posibles en este conjunto. No se bloquea, y aún no hay segfaults. Entonces, sí, la implementación de OpenGL que estoy ejecutando parece acomodar tamaños de textura arbitrarios, y puedo responder por ello porque he cargado más de 500 mil diferentes. –

Cuestiones relacionadas