인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

샤니캉님의 프로필 이미지

작성한 질문수

게임 개발자를 위한 3D 그래픽스, 쉐이더, OpenGL (3) - 애니메이션, depth 개념, Z 버퍼

glm-tri.cpp 의 glVertexAttribPointer 질문입니다.

해결된 질문

작성

·

60

0

glVertexAttribPointer(locPos, 4, GL_FLOAT, GL_FALSE, 0, glm::value_ptr(vertPos[0]));

 

위와 같은 형태로 소스코드에 배포가 되어있는데요.

삼각형이 출력되지 않아서 여러가지 확인해보면서 내용을 찾아보았습니다.

 

우선 glVertexAttribPointer 의 마지막 인자는 배열 내 데이터의 시작 지점(offset)을 나타내고, 이를 통해 GPU가 정점 데이터 배열에서 해당 속성(attribute)을 어디서부터 읽어야 할지 알게한다고 보았습니다.

 

소스 코드 상의 glm::value_ptr(vertPos[0]))은 vertPos[0]이라는 벡터의 메모리 주소를 반환 하므로, 오프셋 값을 나타낸다고 볼 수 없는 것 같아 다소 이해가 가지 않습니다.

 

또한 5번째 인자인 stride에 0 이 기입되는 것이 이해가 가지 않습니다.

stride는 버텍스 데이터 배열 내에서 데이터들이 몇 개씩 한 덩어리인지를 나타내주는 인자로 이해했는데 0 이 아니라, sizeof(glm::vec4) 가 옳은 표현이 되는 것 아닌가요??

 

실제로, glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (void*)0); 로 바꾸어 빌드했더니 삼각형이 올바르게 나왔습니다.

 

바쁘시겠지만 확인해주시면 감사하겠습니다.

답변 2

0

드립커피+한모금더님의 프로필 이미지

안녕하세요.

현재 사용하시는 컴퓨터와 OS 를 알 수 있을까요.

그리고, 이 프로그램 이전의 프로그램들에서는 정상 작동했었는지도 체크가 필요합니다.

현재 배포되는 예제들은 Win10/Win11 또는 Linux 에서 pre-compiled header 를 배제한 환경을 대상으로 합니다.

 

아래 AI 인턴에서도 설명이 나옵니다만, glVertexAtttribPointer 의 마지막 인수는 memory address 또는 offset 모두 가능한데, offset으로 쓰기 위해서는 vertex buffer 를 만들었어야 합니다.

이 강의 내에서도 vertex buffer object를 만드는 방법을 설명합니다만, 아직은 적용하지 않았기 때문에, memory address 를 써야 맞고, 여기 (void*)0을 넣었는데, 작동했다면, 더 이상한 상황입니다.

glGenBuffers() 와 같은 함수가 혹시 어디선가 사용되었나요?

배포된 예제에서는 vertex buffer 사용이 없었기 때문에, 작동하지 않아야 정상입니다.

stride 도 vertex buffer object 를 사용하는 부분에서 추가 설명되는데, 0 으로 설정하면 자동 계산이 되어서, compact packing 된 상태로 보기 때문에, 현재 설정에서는 0으로 하나, 4 * sizeof(float) 또는 sizeof(glm::vec4)로 하나 동일하게 작동해야 합니다.

감사합니다.

샤니캉님의 프로필 이미지
샤니캉
질문자

MacOS입니다 !

 

이전 프로그램들에서도 문제가 있었는데, 버텍스를 직접적으로 전달하면 삼각형이 렌더링되지 않는 문제가 있어서, vao, vbo를 만들어서 진행해보고 있었습니다. 윈도우 환경에서도 한번 진행해보겠습니다. 감사합니다.

드립커피+한모금더님의 프로필 이미지

MacOS 에서는 OpenGL 에 대한 기술적 지원을 2018년에 중단하겠다고 선언해서, driver 레벨에서 오류가 있을 수도 있습니다.

OpenGL 쪽 문제라기 보다는, 현재 MacOS 에서 돌아가는 OpenGL driver 들이 2018년 이후의 Mac 하드웨어들과는 충돌하거나, OpenGL 표준을 준수하지 않았을 수도 있습니다. "공식 지원"이 아닌 상황이라서요. 참고하세요. ~

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다. 샤니캉님, 질문해 주셔서 감사합니다!

glVertexAttribPointer 함수는 OpenGL에서 정점 데이터의 배열을 어떻게 해석할지를 지정하는데 사용됩니다. 질문하신 부분에 대해 자세히 살펴보겠습니다.

  1. 마지막 인자 (glm::value_ptr(vertPos[0]))에 대한 이해:

    • glm::value_ptr(vertPos[0])glm 라이브러리를 사용할 때, 벡터의 첫 번째 요소에 대한 포인터를 반환합니다. 이는 특정한 메모리 주소를 가리키게 됩니다. 말씀하신 것처럼 마지막 인자는 오프셋을 나타내지 않고, 시작 주소를 나타내야 해서, glm::value_ptr을 사용하는 대신 (void*)0 또는 nullptr로 설정하는 것이 더 일반적입니다.
  2. stride에 0이 들어간 이유:

    • stride가 0으로 설정된 경우, OpenGL은 데이터가 연속적이라는 것을 의미합니다. 모든 정점 데이터가 바로 이어져 있고, 중간에 다른 데이터가 끼어들지 않는 경우에 사용되곤 하지만, 이상적으로는 각 데이터 간의 공간 크기를 정확히 지정하는 것이 효과적입니다. 따라서 sizeof(glm::vec4)를 사용하는 것이 일반적으로 더 정확하고, 명확한 코드 작성에 도움이 됩니다.

따라서 생긴 문제는 glVertexAttribPointer 함수의 데이터 해석 방식에서 발생한 것 같습니다. 작성하신 코드도 올바르게 삼각형이 나타났다면, 명시적으로 stride를 설정한 것이 문제 해결에 도움이 되었겠네요.

위 설명을 바탕으로 아래 관련 링크들을 통해 추가적인 내용을 확인하실 수 있습니다:
- OpenGL glVertexAttribPointer 사용법 - Inflearn Q&A
- GPU에서의 메모리와 데이터 처리 방법 - Inflearn

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.