2009-11-02 3 views
1

이 문제는 원래 related question에서 발생했으며 일부 코드를 읽는 데 문제가있었습니다. 대답은이 줄로 밝혀졌습니다.포인터를 어떻게 오프셋으로 사용합니까?

&((GLushort *)0)[3 * mesh.sBoneBatches.pnBatchOffset[batchNum]] 

포인터로 평가됩니다. 그리고 정점 인덱스의 하위 집합을 그릴 오프셋로 해석됩니다

glDrawElements(GL_TRIANGLES, i32Tris * 3, GL_UNSIGNED_SHORT, &((unsigned short*)0)[3 * mesh.sBoneBatches.pnBatchOffset[batchNum]]); 

에 사용됩니다.

현재 내 코드에서는 glDrawElements에서 openGL이 수행하는 작업 중 일부를 직접 수행해야하며 포인터를 오프셋으로 사용하는 방법을 알 수 없습니다. glDrawElements는 (내 코드에서 vertexIndices 이름) 인덱스의 배열을 사용하기 때문에 나는이 같은 시도 :

vertexIndices[&((GLushort *)0)[3 * mesh.sBoneBatches.pnBatchOffset[batchNum]]] 

을하지만 분명히 실패했습니다.

편집 1 : 난 그냥이 시도하고 있지만 정확한 있다면 그것은 여전히 ​​... 확실하지 컴파일합니다. vertexIndices + (uint) &((GLushort *)0)[3 * mesh.sBoneBatches.pnBatchOffset[batchNum]]

+0

나는 '오프셋 된 포인터'에 대한 전반적인 생각이 매우 편안하지 않다고 생각한다. 나는 모든 포인터를 0에서부터의 오프셋으로 생각할 수 있다고 생각한다. 그러나 그것은 여전히 ​​여기에있는 구문에 도움이되지 않는다 : -p. – spencewah

+0

원래 질문을 보았을 때 생각했던 것과 똑같은 생각이 들었습니다. 정점 배열이 유효한 메모리 주소가 아닐 때 glDrawElements가 전달 된 정점 배열에 액세스하려고하면 충돌이 발생하지 않는 이유는 무엇입니까?)? –

+0

이 질문은 세부 사항에 대해 잠깐 사과 드리며,이 잘못된 메모리 주소가 전달 될 때 glDrawElements가 중단되지 않는 이유를 완전히 조사한 다른 질문 (게시물에 링크되어 있음)의 확장입니다. – spencewah

답변

6

이러한 종류의 관용구는 C에서 가끔 사용됩니다. 매크로에서 계산을 캡슐화하는 것이 좋지만 측면 문제입니다.

문제는 다음과 같습니다. 예, 표현식의 유형은 포인터 유형이지만 표현식의 해석은 (여러분이 알고 있듯이) 오프셋입니다. 따라서 expression 값은 int로 캐스트 할 때만 유효합니다.

glDrawElements() 호출에서 표현식 값은 C의 매개 변수 규칙에 의해 int로 강제 변환됩니다.

배열 인덱스에는 식을 int로 자동 캐스팅하는 강제 변환 규칙이 없습니다.

vertexIndices[(int)&((GLushort *)0)[3 * mesh.sBoneBatches.pnBatchOffset[batchNum]]]

더 나은 형태가 될 것이다 : 당신은 INT 캐스트 제공해야합니다

#define OFFSET_OF_GLUSHORT_STUFF (m, N) \ 
    ((int)&((GLushort *)0)[3 * (m).sBoneBatches.pnBatchOffset[(N)]]) 
/*...*/ vertexIndices[OFFSET_OF_GLUSHORT_STUFF(mesh, batchNum)]; 

워, 당신은 당신이 포인터를 계산하는 오프셋 사용하려는 나타 내기 위해 질문을 변경 배열 요소에. 이 경우 호환 가능한 포인터 유형을 전달하는 경우 포인터 계산이 직접 작동해야하므로이 오프셋 기반 접근 방식을 사용하지 마십시오. 호환 가능한 포인터 유형을 전달하지 않으면 혼란이 일어날 것입니다.

코드 안정성을 위해 직접 포인터 연산을 사용하려면이 값을 구해야합니다. glDrawElements에 전달되는 무슨

+0

부끄러움처럼 일했습니다. 감사합니다. – spencewah

+0

오신 것을 환영합니다. 행복한 그림! :) –

2

는 오프셋 같은 오프셋에 대한 포인터 아닌 포인터이다. 직접 오프셋으로 glDrawElements()이 네 번째 매개 변수를 사용하지 않는, 즉

size_t offset = ((GLushort*)0)[3 * mesh.sBoneBatches.pnBatchOffset[batchNum]]; 
glDrawElements(GL_TRIANGLES, i32Tris * 3, GL_UNSIGNED_SHORT, &offset); 

하지만, 오프셋 값에 대한 포인터 : 코드 귀하의 신비 라인은 동일합니다.이 glDrawElements에 대한 다음의 서명이있는 OpenGL documentation에서 분명하다

void glDrawElements(GLenum mode, 
       GLsizei count, 
       GLenum type, 
       const GLvoid *indices); 

그리고 설명 :

지수 - 인덱스가 저장되는 위치에 포인터를 지정합니다. 다른 질문에 대한 답변에 설명 된 이유로 오프셋 계산이 조금 이상하지만, 유효 :

(강조 광산.)을 제외하고

. 온 기반

size_t offset = sizeof(GLushort) * 3 * mesh.sBoneBatches.pnBatchOffset[batchNum]; 
+0

아, 죄송 합니다만, Vertex Buffer Objects를 사용하고 있고, 특별한 경우 (서버 측 계산이기 때문에) OpenGL은 클라이언트 측 계산에서와 같이 실제 포인터를 사용하는 대신 포인터를 AS 오프셋을 사용합니다 (glDrawArrays와 같이) – spencewah

+0

opengl.org에서 : • 해결 : 기본 버퍼 객체 (객체 제로)가 인 경우 모든 포인터는 실제 포인터처럼 동작합니다. 다른 개체가 바인딩되면 모든 포인터는 오프셋으로 처리됩니다. 개념적으로, 버퍼 객체 0은 버퍼 객체가 기본 NULL에 있고 범위가 충분히 크며 시스템의 모든 가상 주소 공간을 포함한다고 생각할 수 있습니다. 이 접근 방식은 기본적으로 바인딩 포인트 이 클라이언트 (서버가 아님) 상태 여야 함을 유의하십시오. – spencewah

1

계산 어떤 컴파일러 제로 작업의 오프셋 (offset),하지만 그렇게 할을 보장 하지 않습니다 : 그것은 같은 것을 작성하는 명확하고 더 문체 정상입니다. ANSI C는 the offsetof operatorstddef.h에 제공하여 구조체의 멤버 오프셋을 계산할 수 있습니다.

관련 문제