Formatos internos de textura OpenGL 2 GL_RGB8I, GL_RGB32UI, etc.

Estoy reescribiendo una gran parte de mi código de texturas. Me gustaría poder especificar ciertos formatos internos: GL_RGB8I, GL_RGB8UI, GL_RGB16I, GL_RGB16UI, GL_RGB32I y GL_RGB32UI. Estos tokens no existen en OpenGL 2.

Al especificar estos formatos internos como argumentos para glTexImage2D, la textura falla (la textura aparece como blanca). Cuando busco errores, obtengo [EDIT:] 1282 (“operación no válida”). Supongo que esto significa que OpenGL todavía está usando OpenGL 2 para glTexImage2D, por lo que la llamada está fallando. Obviamente, necesitará usar una versión más nueva para tener éxito. Los mensajes como GL_RGB, GL_RGBA y (curiosamente) GL_RGB32F, GL_RGBA32F funcionan como se esperaba.

Configuré para usar GLEW o GLee para extensiones. Puedo usar las llamadas a OpenGL 4 sin ningún problema en otros lugares (por ejemplo, glPatchParameteri, glBindFramebuffer, etc.), y las enumeraciones en cuestión ciertamente existen. Para completar, glGetString (GL_VERSION) devuelve “4.2.0”. Mi pregunta: ¿puedo forzar a una de estas bibliotecas de extensión a usar la versión OpenGL 4.2? ¿Si es así, cómo?

EDITAR: El código es demasiado complicado para publicar, pero aquí hay un ejemplo simple y autónomo que utiliza GLee y que también demuestra el problema:

#include  #include  #include  #include  //For Windows #pragma comment(lib,"GLee.lib") #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glu32.lib") #pragma comment(lib,"glut32.lib") #include  #include  const int screen_size[2] = {512,512}; #define TEXTURE_SIZE 64 //Choose a selection. If you see black, then texturing is working. If you see red, then the quad isn't drawing. If you see white, texturing has failed. #define TYPE 1 void error_check(void) { GLenum error_code = glGetError(); const GLubyte* error_string = gluErrorString(error_code); (error_string==NULL) ? printf("%d = (unrecognized error--an extension error?)\n",error_code) : printf("%d = \"%s\"\n",error_code,error_string); } #if TYPE==1 //############ 8-BIT TESTS ############ inline GLenum get_type(int which) { return (which==1)? GL_RGB8: GL_RGB; } //works #elif TYPE==2 inline GLenum get_type(int which) { return (which==1)? GL_RGBA8:GL_RGBA; } //works #elif TYPE==3 inline GLenum get_type(int which) { return (which==1)? GL_RGB8UI: GL_RGB; } //doesn't work (invalid op) #elif TYPE==4 inline GLenum get_type(int which) { return (which==1)? GL_RGB8I: GL_RGB; } //doesn't work (invalid op) #elif TYPE==5 inline GLenum get_type(int which) { return (which==1)? GL_RGBA8UI:GL_RGBA; } //doesn't work (invalid op) #elif TYPE==6 inline GLenum get_type(int which) { return (which==1)? GL_RGBA8I:GL_RGBA; } //doesn't work (invalid op) #elif TYPE==7 //############ 16-BIT TESTS ############ inline GLenum get_type(int which) { return (which==1)? GL_RGB16: GL_RGB; } //works #elif TYPE==8 inline GLenum get_type(int which) { return (which==1)? GL_RGBA16:GL_RGBA; } //works #elif TYPE==9 inline GLenum get_type(int which) { return (which==1)? GL_RGB16UI: GL_RGB; } //doesn't work (invalid op) #elif TYPE==10 inline GLenum get_type(int which) { return (which==1)? GL_RGB16I: GL_RGB; } //doesn't work (invalid op) #elif TYPE==11 inline GLenum get_type(int which) { return (which==1)?GL_RGBA16UI:GL_RGBA; } //doesn't work (invalid op) #elif TYPE==12 inline GLenum get_type(int which) { return (which==1)? GL_RGBA16I:GL_RGBA; } //doesn't work (invalid op) #elif TYPE==13 //############ 32-BIT TESTS ############ inline GLenum get_type(int which) { return (which==1)? GL_RGB32: GL_RGB; } //token doesn't exist #elif TYPE==14 inline GLenum get_type(int which) { return (which==1)? GL_RGBA32:GL_RGBA; } //token doesn't exist #elif TYPE==15 inline GLenum get_type(int which) { return (which==1)? GL_RGB32UI: GL_RGB; } //doesn't work (invalid op) #elif TYPE==16 inline GLenum get_type(int which) { return (which==1)? GL_RGB32I: GL_RGB; } //doesn't work (invalid op) #elif TYPE==17 inline GLenum get_type(int which) { return (which==1)?GL_RGBA32UI:GL_RGBA; } //doesn't work (invalid op) #elif TYPE==18 inline GLenum get_type(int which) { return (which==1)? GL_RGBA32I:GL_RGBA; } //doesn't work (invalid op) #elif TYPE==19 //############ 32-BIT FLOAT ############ inline GLenum get_type(int which) { return (which==1)? GL_RGB32F: GL_RGB; } //works #elif TYPE==20 inline GLenum get_type(int which) { return (which==1)? GL_RGBA32F:GL_RGBA; } //works #endif GLuint texture; void create_texture(void) { printf(" Status before texture setup: "); error_check(); glGenTextures(1,&texture); glBindTexture(GL_TEXTURE_2D,texture); printf(" Status after texture created: "); error_check(); GLenum data_type = GL_UNSIGNED_BYTE; int data_length = TEXTURE_SIZE*TEXTURE_SIZE*4; //maximum number of channels, so it will work for everything unsigned char* data = new unsigned char[data_length]; for (int i=0;i<data_length;++i) { data[i] = (unsigned char)(0); }; glTexImage2D(GL_TEXTURE_2D,0,get_type(1), TEXTURE_SIZE,TEXTURE_SIZE, 0,get_type(2),data_type,data); printf(" Status after glTexImage2D: "); error_check(); delete [] data; glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); printf(" Status after texture filters defined: "); error_check(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: //esc exit(0); break; } } void draw(void) { glClearColor(1.0,0.0,0.0,1.0); //in case the quad doesn't draw glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glViewport(0,0,screen_size[0],screen_size[1]); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,screen_size[0],0,screen_size[1]); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2f(0,0); glTexCoord2f(2,0); glVertex2f(screen_size[0],0); glTexCoord2f(2,2); glVertex2f(screen_size[0],screen_size[1]); glTexCoord2f(0,2); glVertex2f(0,screen_size[1]); glEnd(); glutSwapBuffers(); } int main(int argc, char* argv[]) { glutInit(&argc,argv); glutInitWindowSize(screen_size[0],screen_size[1]); glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH); glutCreateWindow("Texture Types - Ian Mallett"); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); printf("Status after OpenGL setup: "); error_check(); create_texture(); printf("Status after texture setup: "); error_check(); glutDisplayFunc(draw); glutIdleFunc(draw); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; } 

    Cuando busco errores, obtengo [EDIT:] 1282 (“operación no válida”). Supongo que esto significa que OpenGL todavía está usando OpenGL 2 para glTexImage2D, por lo que la llamada está fallando.

    Los errores de OpenGL no son tan complejos de entender. GL_INVALID_ENUM/VALUE se lanzan cuando pasa algo enum o valor inesperado, no compatible o fuera de rango. Si pasa “17” como formato interno a glTexImage2D , obtendrá GL_INVALID_ENUM , porque 17 no es un número de enumeración válido para un formato interno. Si pasa 103,422 como ancho a glTexImage2D , obtendrá GL_INVALID_VALUE , porque 103,422 es casi seguro mayor que GL_MAX_TEXTURE_2D .

    GL_INVALID_OPERATION siempre se usa para combinaciones de estados que GL_INVALID_OPERATION . O bien hay algún estado de contexto previamente establecido que no se acopla con la función a la que llama, o dos o más parámetros combinados están causando un problema. Este último es el caso que tienes aquí.

    Si su implementación no admite texturas enteras, obtendrá INVALID_ENUM (porque el formato interno no es válido). Obtener INVALID_OPERATION significa que algo más está mal.

    A saber, esto:

     glTexImage2D(GL_TEXTURE_2D,0,get_type(1), TEXTURE_SIZE,TEXTURE_SIZE, 0,get_type(2),data_type,data); 

    Su get_type(2) devuelve GL_RGB o GL_RGBA en todos los casos. Sin embargo, al usar formatos de imagen integrales, debe usar un formato de transferencia de píxeles con _INTEGER al final .

    Entonces tu get_type(2) necesita ser esto:

     inline GLenum get_type(int which) { return (which==1)? GL_RGB16UI: GL_RGB_INTEGER; } 

    Y de manera similar para otros formatos de imagen integrales.