2012-03-17 5 views
4

iPhone 용 Open GL ES 1.1 게임에서 다소 복잡한 모델의 렌더링을 향상시키기 위해 Vertex Buffer Objects (VBOs)를 사용하고 싶습니다. SO 및이 (http://playcontrol.net/ewing/jibberjabber/opengl_vertex_buffer_object.html) 자습서의 여러 게시물을 읽은 후에도 VBO를 이해하는 데 문제가 있으며 Cheetah 3D 내보내기 모델 형식을 사용하여 VBO를 구현하는 방법을 여전히 이해할 수 없습니다. 누군가 제게 VBO를 구현하고 주어진 데이터 구조로 정점을 그리고 구문을 설명하기 위해 그것을 사용하는 예를 들어 주시겠습니까? 어떤 도움을 주셔서 감사합니다!iPhone Cheetah 3D OpenGL ES 버텍스 버퍼 객체 (VBO) 예

#define body_vertexcount 434 
#define body_polygoncount 780 

// The vertex data is saved in the following format: 
// u0,v0,normalx0,normaly0,normalz0,x0,y0,z0 
float body_vertex[body_vertexcount][8]={ 
{0.03333, 0.00000, -0.68652, -0.51763, 0.51063, 0.40972, -0.25028, -1.31418}, 
{...}, 
{...} 
} 

GLushort body_index[body_polygoncount][3]={ 
{0, 1, 2}, 
{2, 3, 0} 
} 

다음 코드는 Pro OpenGL ES (Appress)의 9 장을 사용하여 작성했습니다. DrawElements 명령으로 EXC_BAD_ACCESS가 표시됩니다. 이유가 확실하지 않습니다. 누군가 빛을 비춰 줄 수 있겠습니까? - 덕분에 여기

// First thing we do is create/setup the index buffer 
glGenBuffers(1, &bodyIBO); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bodyIBO); 

// For constrast, instead of glBufferSubData and glMapBuffer, 
// we can directly supply the data in one-shot 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, body_polygoncount*sizeof(GLubyte), body_index, GL_STATIC_DRAW); 

// Define our data structure 
int numXYZElements = 3; 
int numNormalElements = 3; 
int numTextureCoordElements = 2; 
long totalXYZBytes; 
long totalNormalBytes; 
long totalTexCoordinateBytes; 
int numBytesPerVertex; 

// Allocate a new buffer 
glGenBuffers(1, &bodyVBO); 

// Bind the buffer object to use 
glBindBuffer(GL_ARRAY_BUFFER, bodyVBO); 

// Tally up the size of the data components 
numBytesPerVertex = numXYZElements; 
numBytesPerVertex += numNormalElements; 
numBytesPerVertex += numTextureCoordElements; 
numBytesPerVertex *= sizeof(GLfloat); 

// Actually allocate memory on the GPU (Data is static here) 
glBufferData(GL_ARRAY_BUFFER, numBytesPerVertex * body_vertexcount, 0, GL_STATIC_DRAW); 

// Upload data to the cache (memory mapping) 
GLubyte *vboBuffer = (GLubyte *)glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); 

// Caclulate the total number of bytes for each data type 
totalXYZBytes = numXYZElements * body_vertexcount * sizeof(GLfloat); 
totalNormalBytes = numNormalElements * body_vertexcount * sizeof(GLfloat); 
totalTexCoordinateBytes = numTextureCoordElements * body_vertexcount * sizeof(GLfloat); 

// Set the total bytes property for the body 
self.bodyTotalBytes = totalXYZBytes + totalNormalBytes + totalTexCoordinateBytes; 

// Setup the copy of the buffer(s) using memcpy() 
memcpy(vboBuffer, body_vertex, self.bodyTotalBytes); 

// Perform the actual copy 
glUnmapBufferOES(GL_ARRAY_BUFFER); 

내가 예외를 받고 있어요 드로잉 명령입니다 :

// Activate the VBOs to draw 
    glBindBuffer(GL_ARRAY_BUFFER, bodyVBO); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bodyIBO); 

    // Setup drawing 
    glMatrixMode(GL_MODELVIEW); 
    glEnable(GL_TEXTURE_2D); 
    glClientActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D,lightGreyInt); 

    // Setup pointers 
    glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 0); 
    glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 12); 
    glNormalPointer(GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 24); 

    // Now draw the body 
    glDrawElements(GL_TRIANGLES, body_polygoncount,GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL)); 
    //glDrawElements(GL_TRIANGLES, body_polygoncount, GL_UNSIGNED_SHORT, nil); 
    //glDrawElements(GL_TRIANGLES,body_polygoncount*3,GL_UNSIGNED_SHORT,body_index); 
+0

당신이 이미 버텍스 배열과 나머지 OpenGL의 작동 방식을 이미 알고 있다고 가정 할 때,이 사실을 잘 설명하는 학습 자료가 없다는 것을 믿을 수 없습니다. ** ** OpenGL ES 1.1 게임에 대한 언급). [여기] (http://www.songho.ca/opengl/gl_vbo.html)를 볼 수도 있지만, 질문에서 링크 된 자습서는 합리적인 것처럼 보입니다 (나는 단지 그것을 훑어 보았습니다). –

+0

어떤 부분에 문제가 있습니까? 우리는 단지 코드를 작성하는 것이 아닙니다. 데이터 구조와 구문에 대해 이해하지 못하는 부분은 무엇입니까? 우리가 합리적인 답을 공식화 할 수 있도록 가능한 한 명시 적이어야합니다. – user1118321

+0

코드를 붙여 넣었습니다. 특히 glDrawElements 호출로 인터리브 된 데이터를 렌더링하는 데 문제가 있습니다. 나는 EXC_BAD_ACCESS를 얻고 있는데, 나는 정말로 도움이된다고 감사한다. - – PhilBot

답변

3

글쎄, 모든 인덱스 버퍼의 첫 번째는 방금 body_polygoncount 인덱스가없는, 너무 작습니다하지만, body_polygoncount * 3. 데이터가 먼저 텍스처를 포함하고 있기 때문에 당신은 또한 그들이 반바지에 있기 때문에, 당신은 GLushort하지 GLubyte 필요 유형을 엉망, 그래서 다음

glBufferData(GL_ELEMENT_ARRAY_BUFFER, body_polygoncount*3*sizeof(GLushort), 
      body_index, GL_STATIC_DRAW); 

되어야한다, 당신은 당신의 속성의 오프셋을 엉망 glDrawElements이 삼각형의 수 있지만, 요소 (인덱스)의 수를 제공하지 않습니다 전화에서 좌표는 다음 정상 및 다음 각 정점의 위치는, 그렇게, 마지막으로

glVertexPointer(3, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 20); //3rd, after 5*4 byte 
glTexCoordPointer(2, GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 0); //1st 
glNormalPointer(GL_FLOAT, sizeof(vertexStruct), (char *)NULL + 8);  //2nd, after 2*4 bytes 

되어야한다 그것은이어야한다

glDrawElements(GL_TRIANGLES, body_polygoncount*3, 
       GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL)); 

그렇지 않으면 코드가 합리적으로 보입니다 (물론 매핑이 잘못되었으므로 glBufferData을 다시 사용할 수는 있지만 학습을 위해 사용했을 것입니다). 그리고 모든 것을 이해하면 그 이상은 없습니다.

하지만 VBO없이 클라이언트 측 버텍스 배열을 사용하고 OpenGL ES 1.1에 직접 모드 glBegin/glEnd이없는 경우 이러한 모든 오류가 발생했을 것입니다. 그래서 당신이이 오류를 알지 못한다면 왜 게임이 VBO없이 이전에 작동했는지 의아하게 생각합니다.

+0

고마워. - 나는 나의 실수를 본다. 이제 이해가된다.이전에 다음과 같이 그리기를했습니다. // gun을 그리시오 - gunX의 렌더와 텍스처 Proceedure // glBindTexture (GL_TEXTURE_2D, lightGreyInt); glVertexPointer (3, GL_FLOAT, sizeof (vertexStruct) 및 interpolatedVerticesGun [0] [5]); glTexCoordPointer (2, GL_FLOAT, sizeof (vertexStruct), interpolatedVerticesGun [0] [0]); glNormalPointer (GL_FLOAT, sizeof (vertexStruct) 및 interpolatedVerticesGun [0] [2]); glDrawElements (GL_TRIANGLES, gun2_polygoncount * 3, GL_UNSIGNED_SHORT, gun2_index); – PhilBot