2012-04-17 2 views
0

저는 Model이라는 클래스를 가지고 있습니다.이 클래스는 그 자체를 그리는 데 필요한 모든 정보를 처리합니다. 기본적으로 두 가지 방법이 있습니다 :클래스 생성자가 데이터를 VBO로 보내지 않습니다.

1) 컨스트럭터 - VBO, VAO 및 유니폼 직원을 만들고 초기화합니다. 2) 그리기 - VAO 바인딩 그리기 및

내 문제는 glBufferData를 사용하여 VBO를 초기화하는 것입니다. GPU 메모리에 업로드해야하는 데이터가 아닙니다. gDebugger를 사용하여 이것을 확인했습니다. 또한 내가 데이터를 다시 생성자 클래스 외부로 보내려고하면 모든 것이 잘 진행된다. 나는 무엇을 놓치고 있는가 ???

Model의 클래스 인스턴스 객체는 템플릿 매개 변수 V 및 M이 각각 vec4 및 mat4 인 전역 변수입니다.

나는 또한 Linux/Windows/NVIDIA/RADEON에서 테스트했으며 동일한 문제가 발생합니다. 셰이더 용으로 #verson 400을 사용하고 glm 수학 라이브러리를 사용했습니다.

1) 생성자 :

/** This constructor has 5 steps: 
* 1) Allocate variables 
* 2) Create, bind and Send vbo inf. 
* 3) Create, bind vao info 
* 4) Create mapping between Buffer and Attributes in GPU memory 
* 5) Get uniform variables location 
* 
* */ 
template<class V, class M> 
Model<V, M>::Model(GLuint size, GLuint program){ 
    assert(size > 0); 

    /** BEG - 1) Allocate variables */ 
    /** beg - model variable initialization */ 
    this->vertex  = new vec4[ size ]; 
    this->numVertex  = size; 

    this->color   = new vec4[ size ]; 
    this->numColor  = size; 

    //this->element  => not initialized 
    //this->numElem  => not initialized 

    this->modelMatrix = M(1); // Identity Matrix 
    this->position  = V(0); // Orign 

    // VBO - Vertex Buffer Object information 
    this->vbo   = new GLuint[ this->numBuff ]; 
    this->vboSize  = this->numBuff; 

    // VAO - Vexter Array Object information 
    this->vao   = new GLuint[ 1 ]; 
    this->numVao  = 1; 
    this->attrib  = new GLuint[ this->numBuff ]; 
    this->numAttrib  = this->numBuff; 

    this->uniform  = new string[ this->numUni ]; 
    this->uniformLoc = new GLuint[ this->numUni ]; 
    this->numUniform = this->numUni; 

    this->program  = program; 

    //beg - Inittialization 
    this->attrib[VERTEX]  = 0; 
    this->attrib[COLOR]  = 1; 

    this->uniform[0]   = string("modelMatrix"); 
    this->uniform[1]   = string("position"); 
    //end - Inittialization 
    /** END - 1) Allocate variables */ 


    /** BEG - 2) Create, bind and Send vbo inf */ 
    // Create vbo identifier 
    glGenBuffers(this->vboSize, this->vbo); 
    Other<V>::checkError("glGenBuffers"); 

    // Bind Buffer 
    glBindBuffer(GL_ARRAY_BUFFER, (this->vbo)[0]); 
    Other<V>::checkError("glBindBuffer"); 

    // Send Data to buffer 
    glBufferData( GL_ARRAY_BUFFER, sizeof((this->vertex)[0][0]) * (this->vertex)[0].length() * (this->numVertex), 
        &(this->vertex[0][0]), GL_STATIC_DRAW); 
    Other<V>::checkError("glBufferData"); 

    // Bind Buffer 
    glBindBuffer(GL_ARRAY_BUFFER, (this->vbo)[1]); 
    Other<V>::checkError("glBindBuffer"); 

    // Send Data to buffer 
    glBufferData( GL_ARRAY_BUFFER, sizeof((this->color)[0][0]) * (this->color)[0].length() * (this->numColor), 
        &(this->color[0][0]), GL_STATIC_DRAW); 
    Other<V>::checkError("glBufferData"); 
    /** END - 2) Create, bind and Send vbo inf */ 


    /** BEG - 3) Create, bind and enable vao info */ 
    // Create vao identifier 
    glGenVertexArrays(1, this->vao); 
    Other<V>::checkError("glGenVertexArrays"); 
    glBindVertexArray((this->vao)[0]); 
    Other<V>::checkError("glBindVertexArray"); 

    // Enable attributes 
    for (uint i=0; i<numAttrib; i++){ 
     glEnableVertexAttribArray(i); 
     Other<V>::checkError("glEnableVertexAttribArray"); 
    } 
    /** END - 3) Create and enable vao info */ 


    /** BEG - 4) Create mapping between Buffer and Attributes in GPU memory */ 
    for (uint i=0; i<numAttrib; i++){ 
     glBindBuffer(GL_ARRAY_BUFFER, (this->vbo)[i]); 
     Other<V>::checkError("glBindBuffer"); 
     glVertexAttribPointer((this->attrib)[i], (this->vertex)[i].length(), GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL); 
     Other<V>::checkError("glBindBuffer"); 
    } 
    /** END - 4) Create mapping between Buffer and Attributes in GPU memory */ 


    /** BEG - 5) Get uniform variables location */ 
    for (uint i=0; i<numAttrib; i++){ 
     this->uniformLoc[i] = glGetUniformLocation(program, this->uniform[i].c_str()); 
     Other<V>::checkError("glGetUniformLocation"); 
    } 
    /** END - 5) Get uniform variables location */ 
} 

2)

template<class V, class M> 
void Model<V, M>::draw() 
{ 
    //glUniformMatrix4fv(this->uniformLoc[0], 1, GL_FALSE, &(this->modelMatrix[0][0])); 
    //glUniform4fv(  this->uniformLoc[1], 1, &(this->position[0])); 

    glBindVertexArray((this->vao)[0]); 
    glDrawArrays(GL_LINE_STRIP, 0, this->numVertex); 
} 

내가 같이 sendData 멤버 함수를 사용 생성자 후 GPU에 데이터 "재전송"그릴 여기

코드를 진행한다 :

template<class V, class M> 
void Model<V, M>::sendData() 
{ 
    glBindBuffer(GL_ARRAY_BUFFER, (this->vbo)[0]); 

    // Send Data to buffer 
    glBufferData( GL_ARRAY_BUFFER, sizeof((this->vertex)[0][0]) * (this->vertex)[0].length() * (this->numVertex), 
         &(this->vertex[0][0]), GL_STATIC_DRAW); 
} 

편집 : sendData 멤버 함수를 추가하는 것을 잊었습니다

답변

0

생성자가 호출되기 전에 유효한 OpenGL 컨텍스트 설정이 있습니까 (glewInit())?

OpenGL 호출로 정적으로 정의 된 객체가있는 경우 main()보다 먼저 생성되기 때문에 실패합니다. 생성자에서 OpenGL 호출을 사용하는 객체를 원한다면 컨텍스트가 초기화 된 후에 만 ​​new으로 생성해야합니다.

+0

감사합니다. 생성자 전에 glewInit을 호출 했었습니다. 나는 glut과 init의 모든 초기화 후에 객체 모델을 위해 새로운 것을 호출한다. 생성자 내의 모든 OpenGL 명령은 그 이후에 발행됩니다. – Caslu

0

정적 초기화 프로그램이나 비슷하게 렌더링 컨텍스트를 가져 오기 전에 해당 클래스를 인스턴스화하면 작동하지 않습니다.

기본적으로 OpenGL 연산을 올바른 생성자에서 작동하는지 확인하지 않는 한 클래스 생성자에 넣지 마십시오. 다른 클래스의 인스턴스에 유효한 OpenGL 컨텍스트를 캡슐화하고이를 컨텍스트에서 작동하는 생성자에 매개 변수로 전달하여이를 수행 할 수 있습니다.

+0

답변 해 주셔서 감사합니다. 나는 아래에서 말했듯이, 링크 단계 후에 만 ​​생성자에서 모든 opengl 명령을 발행합니다. – Caslu

+0

@LucasRibeiro : "링크 단계"로 무엇을 이해합니까? 일반적으로 "링크"는 컴파일 단위를 실행 가능한 프로그램으로 병합하는 프로세스로 이해됩니다. – datenwolf

+0

예, 알고 있습니다. 미안하다면 미안해. 임 셰이더 링크 프로세스에 대해 얘기. – Caslu

관련 문제