6

テクスチャリングコードの大部分を書き直しています。特定の内部形式(GL_RGB8I、GL_RGB8UI、GL_RGB16I、GL_RGB16UI、GL_RGB32I、およびGL_RGB32UI)を指定できるようにしたいと思います。これらのトークンはOpenGL2には存在しません。

これらの内部フォーマットをglTexImage2Dの引数として指定すると、テクスチャリングが失敗します(テクスチャは白で表示されます)。エラーをチェックすると、[EDIT:] 1282(「無効な操作」)が表示されます。これは、OpenGLがまだglTexImage2DにOpenGL 2を使用しているため、呼び出しが失敗していることを意味します。明らかに、成功するには新しいバージョンを使用する必要があります。GL_RGB、GL_RGBA、および(奇妙なことに)GL_RGB32F、GL_RGBA32Fなどの列挙型は期待どおりに機能します。

拡張機能にGLEWまたはGLeeを使用するように構成します。他の場所(glPatchParameteri、glBindFramebufferなど)でOpenGL 4呼び出しを問題なく使用でき、問題の列挙型は確かに存在します。完全を期すために、glGetString(GL_VERSION)は「4.2.0」を返します。私の質問:これらの拡張ライブラリの1つにOpenGL 4.2バージョンの使用を強制できますか?もしそうなら、どのように?

編集:コードは複雑すぎて投稿できませんが、GLeeを使用した単純な自己完結型の例で、問題も示されています。

#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;
}
4

1 に答える 1

10

エラーをチェックすると、[EDIT:] 1282(「無効な操作」)が表示されます。これは、OpenGLがまだglTexImage2DにOpenGL 2を使用しているため、呼び出しが失敗していることを意味します。

OpenGLエラーは、理解するのにそれほど複雑ではありません。GL_INVALID_ENUM/VALUE予期しない、サポートされていない、または範囲外の列挙型または値を渡すとスローされます。内部形式として「17」をに渡すと、17は内部形式の有効な列挙型番号ではないため、glTexImage2Dが得られます。GL_INVALID_ENUMの幅として103,422を渡すと、103,422はほぼ確実にのサイズよりも大きいため、glTexImage2Dが得られます。GL_INVALID_VALUEGL_MAX_TEXTURE_2D

GL_INVALID_OPERATIONうまくいかない状態の組み合わせには常に使用されます。呼び出している関数と一致しない以前に設定されたコンテキスト状態があるか、2つ以上のパラメーターが組み合わされて問題が発生しています。後者はあなたがここにいる場合です。

実装が整数テクスチャをまったくサポートしていなかった場合は、次のようになりますINVALID_ENUM(内部形式が有効な形式ではないため)。取得INVALID_OPERATIONするということは、他の何かが間違っていることを意味します。

つまり、これ:

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

折り返しget_type(2)電話するGL_RGBGL_RGBA、すべての場合に。ただし、統合画像形式を使用する場合は、最後にピクセル転送形式を使用する必要があります。_INTEGER

だからあなたはこれでget_type(2)ある必要があります:

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

また、他の統合画像形式についても同様です。

于 2012-08-02T05:41:45.233 に答える