2012-10-05 5 views
4

지금 컴퓨팅 쉐이더를 사용하는 파티클 시스템에서 작업 중입니다. 모든 입자를 쉐이더 ​​저장 버퍼에 넣었습니다. 파티클에는 현재 위치와 이전 위치의 두 개의 정점이 있습니다.쉐이더 저장 버퍼에있는 OpenGL 버텍스

struct Particle{ 
    glm::vec4 _currPosition; 
    glm::vec4 _prevPosition; 
}; 

계산 쉐이더를 보내고 난 후 모든 쉐이더를 셰이더 저장 버퍼에서 직접 그려야합니다. 그래서 내가 할 것입니다 :

glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, shaderStorageBufferID); 
_shaderManager->useProgram("computeProg"); 
glDispatchCompute((_numParticles/WORK_GROUP_SIZE)+1, 1, 1); 
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); 
_shaderManager->useProgram("shaderProg"); 
glBindBuffer(GL_ARRAY_BUFFER, shaderStorageBufferID); 
glVertexPointer(4,GL_FLOAT, sizeof(glm::vec4), (GLvoid*)0); 
glEnableClientState(GL_VERTEX_ARRAY); 
glDrawArrays(GL_POINTS, 0, _numParticles); 
glDisableClientState(GL_VERTEX_ARRAY); 

문제는 내가 화면에 _numParticles를 볼 수 있다는 것입니다하지만 절반은 내 입자 구조의 _prevPosition 속성으로 렌더링됩니다. 즉, 하나의 입자가 화면에 그려지는 두 개의 정점으로 해석됩니다. 그러나 모든 입자 구조에서 _prevPosition 특성을 건너 뛰기를 원합니다. 내 실수는 어디 갔어?

아마 내 쉐이더 저장 버퍼를 초기화하는 방법이 중요하다

GLuint shaderStorageBufferID; 

glGenBuffers(1, &shaderStorageBufferID); 
glBindBuffer(GL_SHADER_STORAGE_BUFFER, shaderStorageBufferID); 
glBufferData(GL_SHADER_STORAGE_BUFFER, numParticles*sizeof(Particle), NULL ,GL_STATIC_DRAW); 
struct Particle* particles = (struct Particle*) glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, numParticles*sizeof(Particle), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); 
for(int i = 0; i < numParticles; ++i){ 
    particles[i]._currPosition = glm::vec4(i, 0, 0.0, 1.0f); 
    particles[i]._prevPosition = glm::vec4(i, 0, 1.0, 1.0f); 
} 
+0

귀하의 코드는 현대 OpenGL 및 레거시 OpenGL의 놀라운 컬렉션입니다. 계산 쉐이더를 사용하고 메모리 동기화 문제를 충분히 이해할 수있는 방법은 무엇입니까? (여전히 잘못된 장벽을 사용하고 있습니다.) 코드가 제대로 작동한다고해서 반드시 보장된다는 의미는 아닙니다.), 그래도'glVertexPointer'와 같은 구식 함수를 사용합니까? –

+0

나는 과거에 DirectX 11에서 약간 작업했으며 거기에 계산 쉐이더를 사용하는 파티클 시스템을 프로그래밍했습니다. 하지만 지금은 OpenGL로 전환하고 싶습니다. 이것이 지난 주 시작한이 API를 사용한 첫 번째 프로젝트입니다. 그러므로 나는 아직도 많은 것을 배워야한다. :) 정말 유용한 문서 나 유용한 예제가 없기 때문에이 예제와 함께 glVertexPointer가 사용 된 계산 쉐이더에 대한 모든 세부 정보를 다루었습니다. http://education.siggraph.org/media/conference/S2012_Materials/ComputeShader_6pp.pdf – Stan

답변

6

귀하의 Particle 구조체는 두 개의 vec4 년대가 포함되어 있습니다. compute shader은 배열 요소 당 두 개의 vec4 개를 씁니다.

그러나이 라인 :

glVertexPointer(4,GL_FLOAT, sizeof(glm::vec4), (GLvoid*)0); 

당신이 vec4의 배열을 전달하는 OpenGL을 알려줍니다. 넌 아니야. 모든 요소가 이고 두 개가vec4 인 배열을 전달 중입니다. 그리고 두 번째 것은 건너 뛰고 싶습니다. BTW

glVertexPointer(4, GL_FLOAT, sizeof(Particle), (GLvoid*)0); 

아, 그리고 : 당신은 여전히 ​​using the wrong barrier있어

그래서 적절한 보폭을 제공함으로써 있다는 OpenGL을 말한다. 코드가 작동한다고해서 그것이 보장된다는 의미는 아닙니다. 모든 작업을 올바르게 수행하지 않으면 동기화되지 않은로드/저장 작업이 까다로울 수 있습니다.

+0

오 세상에! 나는 더 많은 휴식을 취해야한다고 생각한다! 고마워, 이제 모든 것이 잘되고있다. 그런 진부함으로 너를 괴롭히지 않아서 미안해. – Stan

관련 문제