macOS에서 OpenGL 프로그래밍 (2-2. 구조체와 벡터를 사용하여 정점 데이터 지정)
소개
지난번은 셰이더를 작성하고 읽고 VBO와 VAO를 사용하여 화면을 그리는 방법을 설명했습니다.
이번에는, 정점 데이터를 구조체와 vector를 사용해 준비해, 그것에 의해 VBO와 VAO 각각의 지정을 알기 쉽게 된다는 것을 해설하고 싶습니다.
1. VertexData 구조체 정의
Game.cpp를 편집하여 vector 헤더를 포함하여 정점 데이터를 나타내는 VertexData 구조체를 정의합니다.
Game.cpp(선두 부분)#include "Game.hpp"
#include <cmath>
#include <vector>
struct VertexData
{
GLfloat pos[3];
GLfloat color[4];
};
GLfloat형의 수치를 3개 조합한 배열로 정점 좌표를 나타내, GLfloat형의 수치를 4개 조합한 배열로 색 정보를 나타냅니다.
2. Game 클래스의 생성자 재작성
다음으로, Game 클래스의 생성자를 편집해, 전회는 GLfloat형의 수치를 나란히 해 정점 데이터를 정의하고 있었던 것을, C++ 표준의 std::vector와 VertexData를 조합한 형태로 정점 데이터를 정의하도록(듯이) 로 변경합니다.
Game.cpp(생성자)Game::Game()
{
program = new ShaderProgram("myshader.vsh", "myshader.fsh");
std::vector<VertexData> data;
data.push_back({ { -0.5f, -0.5f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } });
data.push_back({ { 0.5f, -0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } });
data.push_back({ { 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } });
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * data.size(), &data[0], GL_STATIC_DRAW);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->pos);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->color);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
어떻습니까? 정점 좌표와 색 정보를 따로 지정할 수 있게 되어 알기 쉬워졌고, 무엇보다 VBO와 VAO에서의 데이터 포맷의 지정도 알기 쉬워지고 있다고 생각합니다.
2.1. VBO 데이터 전송 방법 비교
실제로 봐 비교해 봅시다. 먼저 VBO 변경 전과 변경 후를 비교해 보겠습니다.
VBO 데이터 전송 비교// 変更前
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 7 * 3, data, GL_STATIC_DRAW);
// 変更後
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * data.size(), &data[0], GL_STATIC_DRAW);
변경전은 GLfloat형의 수치가 정점 좌표 3개+색 정보 4개의 7개로, 한층 더 그것이 3 세트분 있는 것을 머리로 계산해 지정하지 않으면 안되었습니다.
그러나 변경 후의 것에서는, C++의 std::vector를 사용해, 데이터를 구조체로서 정리한 VertexData를 이용하는 것으로, 정점 데이터 1분의 사이즈를 「 sizeof(VertexData)
」라고 쓰는 것만으로 계산할 수 있다 size()
함수를 사용해 구한 데이터의 개수를 곱하는 것만으로 VBO의 지정을 할 수 있게 되어 있습니다.
2.2. VAO 포맷 지정 방법 비교
다음으로 VAO 변경 전과 변경 후를 비교해 보겠습니다.
VAO 형식 지정 비교// 変更前
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 7, (GLfloat *)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 7, ((GLfloat *)0)+3);
// 変更後
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->pos);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->color);
glVertexAtrribPointer()
함수의 다섯 번째 인수에서 데이터의 stride 값을 구하기 위해 변경 후에는 "sizeof(VertexData)
"라고 쓰는 것만으로 좋아지는 것은 VBO와 같습니다.
glVertexAtrribPointer()
함수의 여섯 번째 인수에서 오프셋 값을 지정하는 방법에 대해 오프셋 값 0을 VertexData 포인터 형식으로 캐스팅 한 것을 사용하여 화살표 연산자로 pos와 color 각각의 배열에 액세스하여 pos 배열의 선두의 오프셋(offset)치와 color 배열의 선두의 오프셋(offset)치를 적절히 지정할 수 있게 되어 있습니다. 이것은 향후, 법선 벡터나 텍스처의 UV 좌표 등을 지정하는 등, 정점 속성의 수가 증가했을 경우에, 확실히 간단하게 오프셋치를 지정할 수 있게 되는 것을 나타내고 있습니다.
실행 결과는 이전과 동일합니다.
여기까지의 프로젝트 : MyGL은 _s로 p2-2. 지 p
3. 정리
이번에는 구조와 벡터를 사용하여 원본 데이터를 준비하여 VBO와 VAO를 더 쉽게 지정할 수 있다는 것을 알았습니다.
다음 번에는 인덱스 목록을 사용하여 정점 데이터의 순서를 제어하는 방법을 설명합니다.
다음 기사 : macOS에서 OpenGL 프로그래밍 (2-3. 정점의 인덱스 목록을 사용하여 그리기)
Reference
이 문제에 관하여(macOS에서 OpenGL 프로그래밍 (2-2. 구조체와 벡터를 사용하여 정점 데이터 지정)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/sazameki/items/4eab1b846992899e1e61
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Game.cpp를 편집하여 vector 헤더를 포함하여 정점 데이터를 나타내는 VertexData 구조체를 정의합니다.
Game.cpp(선두 부분)
#include "Game.hpp"
#include <cmath>
#include <vector>
struct VertexData
{
GLfloat pos[3];
GLfloat color[4];
};
GLfloat형의 수치를 3개 조합한 배열로 정점 좌표를 나타내, GLfloat형의 수치를 4개 조합한 배열로 색 정보를 나타냅니다.
2. Game 클래스의 생성자 재작성
다음으로, Game 클래스의 생성자를 편집해, 전회는 GLfloat형의 수치를 나란히 해 정점 데이터를 정의하고 있었던 것을, C++ 표준의 std::vector와 VertexData를 조합한 형태로 정점 데이터를 정의하도록(듯이) 로 변경합니다.
Game.cpp(생성자)Game::Game()
{
program = new ShaderProgram("myshader.vsh", "myshader.fsh");
std::vector<VertexData> data;
data.push_back({ { -0.5f, -0.5f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } });
data.push_back({ { 0.5f, -0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } });
data.push_back({ { 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } });
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * data.size(), &data[0], GL_STATIC_DRAW);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->pos);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->color);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
어떻습니까? 정점 좌표와 색 정보를 따로 지정할 수 있게 되어 알기 쉬워졌고, 무엇보다 VBO와 VAO에서의 데이터 포맷의 지정도 알기 쉬워지고 있다고 생각합니다.
2.1. VBO 데이터 전송 방법 비교
실제로 봐 비교해 봅시다. 먼저 VBO 변경 전과 변경 후를 비교해 보겠습니다.
VBO 데이터 전송 비교// 変更前
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 7 * 3, data, GL_STATIC_DRAW);
// 変更後
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * data.size(), &data[0], GL_STATIC_DRAW);
변경전은 GLfloat형의 수치가 정점 좌표 3개+색 정보 4개의 7개로, 한층 더 그것이 3 세트분 있는 것을 머리로 계산해 지정하지 않으면 안되었습니다.
그러나 변경 후의 것에서는, C++의 std::vector를 사용해, 데이터를 구조체로서 정리한 VertexData를 이용하는 것으로, 정점 데이터 1분의 사이즈를 「 sizeof(VertexData)
」라고 쓰는 것만으로 계산할 수 있다 size()
함수를 사용해 구한 데이터의 개수를 곱하는 것만으로 VBO의 지정을 할 수 있게 되어 있습니다.
2.2. VAO 포맷 지정 방법 비교
다음으로 VAO 변경 전과 변경 후를 비교해 보겠습니다.
VAO 형식 지정 비교// 変更前
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 7, (GLfloat *)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 7, ((GLfloat *)0)+3);
// 変更後
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->pos);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->color);
glVertexAtrribPointer()
함수의 다섯 번째 인수에서 데이터의 stride 값을 구하기 위해 변경 후에는 "sizeof(VertexData)
"라고 쓰는 것만으로 좋아지는 것은 VBO와 같습니다.
glVertexAtrribPointer()
함수의 여섯 번째 인수에서 오프셋 값을 지정하는 방법에 대해 오프셋 값 0을 VertexData 포인터 형식으로 캐스팅 한 것을 사용하여 화살표 연산자로 pos와 color 각각의 배열에 액세스하여 pos 배열의 선두의 오프셋(offset)치와 color 배열의 선두의 오프셋(offset)치를 적절히 지정할 수 있게 되어 있습니다. 이것은 향후, 법선 벡터나 텍스처의 UV 좌표 등을 지정하는 등, 정점 속성의 수가 증가했을 경우에, 확실히 간단하게 오프셋치를 지정할 수 있게 되는 것을 나타내고 있습니다.
실행 결과는 이전과 동일합니다.
여기까지의 프로젝트 : MyGL은 _s로 p2-2. 지 p
3. 정리
이번에는 구조와 벡터를 사용하여 원본 데이터를 준비하여 VBO와 VAO를 더 쉽게 지정할 수 있다는 것을 알았습니다.
다음 번에는 인덱스 목록을 사용하여 정점 데이터의 순서를 제어하는 방법을 설명합니다.
다음 기사 : macOS에서 OpenGL 프로그래밍 (2-3. 정점의 인덱스 목록을 사용하여 그리기)
Reference
이 문제에 관하여(macOS에서 OpenGL 프로그래밍 (2-2. 구조체와 벡터를 사용하여 정점 데이터 지정)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/sazameki/items/4eab1b846992899e1e61
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Game::Game()
{
program = new ShaderProgram("myshader.vsh", "myshader.fsh");
std::vector<VertexData> data;
data.push_back({ { -0.5f, -0.5f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } });
data.push_back({ { 0.5f, -0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } });
data.push_back({ { 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } });
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * data.size(), &data[0], GL_STATIC_DRAW);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->pos);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->color);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
// 変更前
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 7 * 3, data, GL_STATIC_DRAW);
// 変更後
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * data.size(), &data[0], GL_STATIC_DRAW);
// 変更前
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 7, (GLfloat *)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 7, ((GLfloat *)0)+3);
// 変更後
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->pos);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), ((VertexData *)0)->color);
이번에는 구조와 벡터를 사용하여 원본 데이터를 준비하여 VBO와 VAO를 더 쉽게 지정할 수 있다는 것을 알았습니다.
다음 번에는 인덱스 목록을 사용하여 정점 데이터의 순서를 제어하는 방법을 설명합니다.
다음 기사 : macOS에서 OpenGL 프로그래밍 (2-3. 정점의 인덱스 목록을 사용하여 그리기)
Reference
이 문제에 관하여(macOS에서 OpenGL 프로그래밍 (2-2. 구조체와 벡터를 사용하여 정점 데이터 지정)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/sazameki/items/4eab1b846992899e1e61텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)