OpenGL 2纹理内部格式GL_RGB8I,GL_RGB32UI等

我正在重写我的纹理代码的很大一部分。 我想能够指定特定的内部格式:GL_RGB8I,GL_RGB8UI,GL_RGB16I,GL_RGB16UI,GL_RGB32I和GL_RGB32UI。 这些令牌在OpenGL 2中不存在。

当将这些内部格式指定为glTexImage2D的参数时,纹理化失败(纹理显示为白色)。 当检查错误时,我得到[编辑:] 1282(“无效操作”)。 我认为这意味着OpenGL仍在为glTexImage2D使用OpenGL 2,所以调用失败。 显然,它将需要使用更新的版本才能成功。 像GL_RGB,GL_RGBA和(奇怪)GL_RGB32F,GL_RGBA32F枚举像预期的那样工作。

我configuration使用GLEW或GLee进行扩展。 我可以在其他地方使用OpenGL 4调用(例如,glPatchParameteri,glBindFramebuffer等),并且当然存在枚举。 为了完整性,glGetString(GL_VERSION)返回“4.2.0”。 我的问题:我可以强制其中一个扩展库使用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; } 

当检查错误时,我得到[编辑:] 1282(“无效操作”)。 我认为这意味着OpenGL仍在为glTexImage2D使用OpenGL 2,所以调用失败。

OpenGL错误并不那么复杂。 当您传递某个枚举或值是意外的,不受支持的或超出范围的值时抛出GL_INVALID_ENUM/VALUE 。 如果将“17”作为内部格式传递给glTexImage2D ,则会得到GL_INVALID_ENUM ,因为17对于内部格式不是有效的枚举数。 如果将宽度作为宽度传递给glTexImage2D ,则将获得GL_INVALID_VALUE ,因为103,422几乎肯定大于GL_MAX_TEXTURE_2D的大小。

GL_INVALID_OPERATION总是用于出错状态的组合 。 或者有一些前面设置的上下文状态与您正在调用的函数不相关,或者两个或多个参数相结合导致问题。 后者是你在这里的情况。

如果你的实现根本不支持整数纹理,那么你会得到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; } 

对于其他整体图像格式也是如此。