2012-07-01 13 views
5

Tôi đang viết lại một phần lớn mã văn bản của mình. Tôi muốn có thể chỉ định một số định dạng nội bộ: GL_RGB8I, GL_RGB8UI, GL_RGB16I, GL_RGB16UI, GL_RGB32I và GL_RGB32UI. Các mã thông báo này không tồn tại trong OpenGL 2.OpenGL 2 Kết cấu định dạng nội bộ GL_RGB8I, GL_RGB32UI, v.v.

Khi chỉ định các định dạng nội bộ dưới dạng đối số cho glTexImage2D, kết cấu không thành công (kết cấu sẽ xuất hiện dưới dạng màu trắng). Khi kiểm tra lỗi, tôi nhận được [EDIT:] 1282 ("hoạt động không hợp lệ"). Tôi thực hiện điều này có nghĩa là OpenGL vẫn đang sử dụng OpenGL 2 cho glTexImage2D và do đó cuộc gọi không thành công. Rõ ràng, nó sẽ cần phải sử dụng một phiên bản mới hơn để thành công. Enums như GL_RGB, GL_RGBA, và (kỳ quặc) GL_RGB32F, GL_RGBA32F hoạt động như mong đợi.

Tôi định cấu hình sử dụng GLEW hoặc GLee cho tiện ích. Tôi có thể sử dụng các cuộc gọi OpenGL 4 mà không có vấn đề gì ở nơi khác (ví dụ: glPatchParameteri, glBindFramebuffer, v.v.) và các enums được đề cập chắc chắn tồn tại. Để hoàn thành, glGetString (GL_VERSION) trả về "4.2.0". Câu hỏi của tôi: tôi có thể buộc một trong các thư viện mở rộng này sử dụng phiên bản OpenGL 4.2 không? Nếu vậy, làm thế nào?

EDIT: Mã này là quá phức tạp để gửi, nhưng đây là một đơn giản, khép kín ví dụ sử dụng Glee đó cũng chứng tỏ vấn đề:

#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

Đăng cuộc gọi glTexImage2D, lỗi có thể không phải là suy nghĩ của bạn. –

+0

Ngoài ra hãy chắc chắn rằng tất cả các lỗi đã được xử lý trước khi gọi 'glTexImage2D', do đó bạn chỉ thấy các lỗi đến từ đó. –

+0

Đã thêm ví dụ minh họa sự cố, với kiểm tra lỗi đã nêu. Cảm ơn, – imallett

Trả lời

8

Khi kiểm tra xem có lỗi, tôi nhận được [EDIT :] 1282 ("hoạt động không hợp lệ"). Tôi thực hiện điều này có nghĩa là OpenGL vẫn đang sử dụng OpenGL 2 cho glTexImage2D và do đó cuộc gọi không thành công.

OpenGL errors không phức tạp để hiểu. GL_INVALID_ENUM/VALUE được ném khi bạn truyền một thứ gì đó một enum hoặc giá trị bất ngờ, không được hỗ trợ hoặc ngoài phạm vi. Nếu bạn chuyển "17" làm định dạng nội bộ thành glTexImage2D, bạn sẽ nhận được GL_INVALID_ENUM, vì 17 không phải là số enum hợp lệ cho định dạng nội bộ. Nếu bạn vượt qua 103,422 là chiều rộng đến glTexImage2D, bạn sẽ nhận được GL_INVALID_VALUE, bởi vì 103,422 gần như chắc chắn lớn hơn kích thước của GL_MAX_TEXTURE_2D.

GL_INVALID_OPERATION luôn được sử dụng cho kết hợp trạng thái sai. Hoặc có một số trạng thái ngữ cảnh được đặt trước đó không khớp với hàm bạn đang gọi hoặc hai hoặc nhiều tham số kết hợp đang gây ra sự cố. Sau đó là trường hợp bạn có ở đây.

Nếu triển khai của bạn không hỗ trợ họa tiết nguyên, bạn sẽ nhận được INVALID_ENUM (vì định dạng nội bộ không phải là định dạng hợp lệ). Nhận INVALID_OPERATION có nghĩa là có điều gì đó sai.

Cụ thể, điều này:

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

gọi get_type(2) bạn trả GL_RGB hoặc GL_RGBA trong mọi trường hợp. Tuy nhiên, khi sử dụng tích phân image formats, bạn phải sử dụng pixel transfer format with _INTEGER at the end.

Vì vậy get_type(2) nhu cầu của bạn sẽ được này:

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

Và tương tự cho các định dạng hình ảnh không thể thiếu khác.

+0

Tôi đã làm việc từ liên kết đầu tiên, chủ yếu, không đề cập đến _INTEGER. Thay đổi mã trên chắc chắn hoạt động, nhưng đối với kết cấu số nguyên, tôi thấy màu đen (lưu ý, thay đổi "dữ liệu [i] = (unsigned char) (0);" thành 128 đầu tiên). Điều này có liên quan gì đến việc giải thích chức năng cố định của "định dạng tích phân sẽ giải quyết thành vec tơ số nguyên" - tức là, vẽ chức năng cố định + OpenGL 4 textures = hành vi không xác định? – imallett

+0

@Ian: Đầu tiên, kết cấu nguyên là GL 3, không phải GL 4. Thứ hai, kết cấu nguyên không hoạt động với chức năng cố định; bạn phải sử dụng shaders với họ. –

+0

Tôi nên làm rõ rằng tôi có nghĩa là: cố định chức năng vẽ + kết cấu số nguyên! = Ý nghĩa; tự nhiên, điểm nổi GL 3, 4 kết cấu hoạt động tốt. Dù sao, tuyệt vời, cảm ơn! – imallett

Các vấn đề liên quan