2012-07-01 14 views
5

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.OpenGL 2 texturas formatos internos GL_RGB8I, GL_RGB32UI, etc.

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.

Configuro para usar GLEW o GLee para las 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?

EDIT: El código es demasiado complicado para publicar, pero aquí es un ejemplo simple, autónomo utilizando Glee que también demuestra el problema:

#include <GLee5_4/GLee.h> 
#include <GL/gl.h> 
#include <GL/glu.h> 
#include <gl/glut.h> 
//For Windows 
#pragma comment(lib,"GLee.lib") 
#pragma comment(lib,"opengl32.lib") 
#pragma comment(lib,"glu32.lib") 
#pragma comment(lib,"glut32.lib") 

#include <stdlib.h> 
#include <stdio.h> 

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; 
} 
+1

Publique la llamada glTexImage2D, el error puede no ser el que usted piensa. –

+0

También asegúrese de que todos los errores se procesaron antes de llamar a 'glTexImage2D', de modo que solo vea los errores que provienen de allí. –

+0

Se agregó un ejemplo que demuestra el problema, con dicha comprobación de errores. Gracias, – imallett

Respuesta

8

Cuando la comprobación de errores, me sale [EDITAR :] 1282 ("operación inválida"). Supongo que esto significa que OpenGL todavía está usando OpenGL 2 para glTexImage2D, por lo que la llamada está fallando.

OpenGL errors 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 al 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 el ancho a glTexImage2D, obtendrá GL_INVALID_VALUE, porque es casi seguro que 103,422 sea más grande que GL_MAX_TEXTURE_2D.

GL_INVALID_OPERATION siempre se usa para combinaciones del estado que salen mal. 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 de enteros, obtendrá INVALID_ENUM (porque el formato interno no es válido). Obtener INVALID_OPERATION significa que algo más está mal.

Es decir, esto:

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

Su llamada get_type(2) devuelve GL_RGB o GL_RGBA en todos los casos. Sin embargo, cuando usa la integral image formats, usted debe utilice un pixel transfer format with _INTEGER at the end.

lo tanto sus necesidades get_type(2) ser la siguiente:

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

y lo mismo para otros formatos de imagen integral.

+0

Estaba trabajando desde el primer enlace, en su mayoría, que no mencionaba _INTEGER. Cambiar el código anterior ciertamente funciona, pero para las texturas enteras, veo negro (nota, cambie "datos [i] = (caracteres sin signo) (0);" a 128 primero). ¿Tiene esto algo que ver con la interpretación de la función fija de "los formatos integrales se resolverán en un vector de números enteros", es decir, el dibujo de función fija + texturas OpenGL 4 = comportamiento indefinido? – imallett

+0

@Ian: Primero, las texturas de enteros son GL 3, no GL 4. En segundo lugar, las texturas de enteros no funcionan con la función fija; tienes que usar shaders con ellos. –

+0

Debo aclarar que quise decir: dibujo de función fija + texturas de enteros! = Sentido; naturalmente, las texturas de punto flotante GL 3, 4 funcionan bien. De todos modos, increíble, gracias! – imallett

Cuestiones relacionadas