2012-07-01 14 views
5

Sto riscrivendo gran parte del mio codice di texturing. Vorrei poter specificare alcuni formati interni: GL_RGB8I, GL_RGB8UI, GL_RGB16I, GL_RGB16UI, GL_RGB32I e GL_RGB32UI. Questi token non esistono in OpenGL 2.OpenGL 2 Texture formati interni GL_RGB8I, GL_RGB32UI, ecc.

Quando si specificano questi formati interni come argomenti per glTexImage2D, la texturing fallisce (la texture appare bianca). Quando si verificano errori, ottengo [EDIT:] 1282 ("operazione non valida"). Prendo questo per significare che OpenGL sta ancora usando OpenGL 2 per glTexImage2D, e quindi la chiamata sta fallendo. Ovviamente, sarà necessario utilizzare una versione più recente per avere successo. Enum come GL_RGB, GL_RGBA e (stranamente) GL_RGB32F, GL_RGBA32F funzionano come previsto.

Configurazione per utilizzare GLEW o GLee per le estensioni. Posso usare le chiamate OpenGL 4 senza problemi altrove (ad es. GlPatchParameteri, glBindFramebuffer, ecc.) E le enumerazioni in questione esistono sicuramente. Per completezza, glGetString (GL_VERSION) restituisce "4.2.0". La mia domanda: posso forzare una di queste librerie di estensioni per utilizzare la versione OpenGL 4.2? Se é cosi, come?

EDIT: Il codice è troppo complicato per spedire, ma qui è un semplice, ad esempio autonomo utilizzando Glee che dimostra anche il 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

Posta la chiamata a glTexImage2D, l'errore potrebbe non essere quello che pensi. –

+0

Assicurati inoltre che tutti gli errori siano stati elaborati prima di chiamare 'glTexImage2D', in modo che tu stia vedendo solo gli errori che provengono da lì. –

+0

Aggiunto un esempio che dimostra il problema, con detto controllo degli errori. Grazie, – imallett

risposta

8

Durante il controllo per gli errori, ottengo [EDIT :] 1282 ("operazione non valida"). Prendo questo per significare che OpenGL sta ancora usando OpenGL 2 per glTexImage2D, e quindi la chiamata sta fallendo.

OpenGL errors non sono così complessi da capire. GL_INVALID_ENUM/VALUE vengono generati quando si passa a qualcosa di enum o valore inaspettato, non supportato o fuori intervallo. Se si passa "17" come formato interno a glTexImage2D, si otterrà GL_INVALID_ENUM, perché 17 non è un numero enum valido per un formato interno. Se si passa 103.422 come larghezza a glTexImage2D, si otterrà GL_INVALID_VALUE, perché 103.422 è quasi certamente più grande della dimensione di GL_MAX_TEXTURE_2D.

GL_INVALID_OPERATION viene sempre utilizzato per combinazioni di stato che vanno male. O ci sono alcuni stati di contesto precedentemente impostati che non si adattano alla funzione che stai chiamando, o due o più parametri combinati stanno causando un problema. Quest'ultimo è il caso che hai qui.

Se l'implementazione non supportava le trame intere, si otterrebbe INVALID_ENUM (perché il formato interno non è un formato valido). Ottenere INVALID_OPERATION significa che qualcos'altro è sbagliato.

Vale a dire, in questo modo:

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

tuo get_type(2) chiamata restituisce GL_RGB o GL_RGBA in tutti i casi. Tuttavia, quando si utilizza l'integrale image formats, l'utente deve utilizzare utilizzare uno pixel transfer format with _INTEGER at the end.

Così i vostri get_type(2) deve essere questo:

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

E allo stesso modo per gli altri formati di immagine integrale.

+0

Stavo lavorando dal primo collegamento, soprattutto, che non menzionava _INTEGER. Cambiare il codice sopra certamente funziona, ma per le trame intere, vedo il nero (nota, cambia "data [i] = (unsigned char) (0);" a 128 prima). Questo ha qualcosa a che fare con l'interpretazione della funzione fissa di "formati integrali si risolverà in un vettore di interi" - cioè, disegno di funzioni fisse + Trame OpenGL 4 = comportamento indefinito? – imallett

+0

@Ian: Innanzitutto, le trame intere sono GL 3, non GL 4. In secondo luogo, le trame intere non funzionano con la funzione fissa; devi usare shader con loro. –

+0

Devo chiarire che intendevo: disegno di funzioni fisse + trame intere! = Senso; naturalmente, le texture GL 3, 4 a virgola mobile funzionano bene. Comunque, fantastico, grazie! – imallett

Problemi correlati