[HCI] Graphics & OpenGL 2

2025. 4. 2. 21:37·강의/HCI

Vertex Shader

#version 330 core //OpenGL 버전(330 => 3.3 버전)
//Vertex Shader은 vec3타입의 데이터를 aPos라는 변수로 받는다. 이 입력 변수의 위치는 0.
layout (location = 0) in vec3 aPos; //0: 입력변수 위치. aPos: vertex shader 입력 변수 타입
void main()
{
	//gl_Position : vertex shader 출력 변수. vec4 타입(vec3아님!!)
	gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}

 

Vertex Buffer Object(VBO)

unsigned int VBO;
glGenBuffers(1, &VBO); //(생성할 버퍼 오브젝트 네임의 개수, 생성한 버퍼 오브젝트 네임을 저장할 변수의 주소값)
glBindBuffer(GL_ARRAY_BUFFER, VBO); //(바인딩하는 버퍼 오브젝트의 사용 방법, 바인딩할 버퍼 오브젝트)
  • Vertex 데이터를 저장하기 위한 GPU의 메모리, 버퍼
  • glGenBuffers를 통해 VBO를 생성함
  • Vertex 버퍼객체의 유형은 GL_ARRAY_BUFFER 등 여러가지로 glBindBuffer 함수로 설정
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  • glBufferData 함수 : 어떤 버퍼로부터 데이터를 복사해올 것인지 복사해올 버퍼를 지정하는 작업
    • 변수 등을 통해서 정의된 vertex 데이터를 버퍼 메모리로 복사
    • 첫번째 인자: 복사할 버퍼 유형
    • 두번째 인자: 복사할 버퍼의 크기
    • 세번째 인자: 복사할 데이터 주소
    • 네번째 인자: GL_STREAM_DRAW: 데이터가 한번만 지정되고 GPU가 수회 사용 GL_STATIC_DRAW: 데이터가 한번만 지정되고 GPU가 여러 번 사용 GL_DYNAMIC_DRAW: 데이터가 자주 변하고 GPU가 여러 번 사용

 

Vertex Shader Compile

unsigned int vertexShader
vertexShader=glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
  • glCreateShader
    • Vertex shader, geometry shader, fragment shader 객체를 생성. GL_VERTEX_SHADER는 vertex shader 생성
  • glShaderSource
    • 생성한 셰이더에 셰이더가 실행할 GLSL 프로그램 소스코드를 지정(생성한 셰이더, 입력 문자열의 개수, Shader string 주소, 문자열들의 길이 배열)
  • glCompileShader
    • 셰이더 컴파일

 

Fragment Shader

#version 330 core
out vec4 FragColor; //vec4: fragment shader 출력 변수 타입
void main()
{
    FragColor = vec4(1.0f, 0.5, 0.2f, 1.0f); //출력 색상, 출력 알파값
}

Fragment Shader Compile은 앞에 Vertex Shader Compile이랑

glCreateShader(GL_FRAGMENT_SHADER); 입력인자가 다른거 말고는 동일

 

Shader Program

unsigned int shaderProgram;
shaderProgram = glCreateProgram();

여러 개의 shader가 링크된 최종 버전의 프로그램 객체

객체를 렌더링할 때 shader program을 활성화해 실행

 

glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram); //Vertex Shader와 Fragment Shader를 한번에 링크

컴파일된 shader들을 프로그램으로 링크할때, 각 shader의 입출력 형식이 같아야됨.

다르면 링크 에러 발생

 

glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

Shader program에 링크된 후 shader 객체는 삭제해도 됨

 

while (!glfwWindowShouldClose(pWindow)) {
		...
		glUseProgram(shaderProgram);
		...
	}

링크된 shader program 객체는 렌더링 루프에서 glUseProgram 함수를 호출하여 활성화

 

Linking Vertex Attributes

[예제 1]

  • Vertex 위치(좌표) 데이터는 float(4 byte) 형식으로 저장
  • 예시에서 각 vertex 좌표는 3개의 float 값(x, y, z)로 구성
    • 1차원 배열에 담겨있는 이 정보를 3개씩 끊어서 써야한다고 알려줘야됨
  • Vertex 사이에 다른 데이터는 들어가지 않음
  • 예시에서 vertice 포인터에서 offset은 0

 

glVertexAttribPointer : 속성 지정해주는 함수

  • 데이터 구분 번호 = 속성의 인덱스
    • layout(location = 0) in vec3 aPos; 에서 location에 해당
  • vertex 구성 요소의 수 ⇒ x,y,z 이므로 3개
  • vertex data type ⇒ float 형 데이터
  • 정규화 플래그 : 각 데이터를 normalize할지 그대로 쓸지
  • stride : vertex마다 사용할 데이터의 간격.
    • float 형 3개 ⇒ 4 * 3 =12
  • 시작 위치 ⇒ 0부터 시작하므로 (void*) 0
  • 만든 속성은 glEnableVertexAttrbArray() 함수를 사용해 VAO에 등록

 

[예제 2]

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

 

색상을 뽑아냄 ⇒ 처음 offset에 12를 주어 12byte를 건너뛴 위치부터 3개씩 가져옴

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)3*sizeof(float));
glEnableVertexAttribArray(1);

 

Vertex Array Object (VAO)

VAO : vertex array 속성에 대한 설정을 저장하고 있는 object

unsigned int VAO;
glGenVertexArrays(1, &VAO); //1. vertex array 객체 생성
// 1. bind Vertex Array Object
glBindVertexArray(VAO); //2. vertex array 객체 바인드
// 2 copy our vertices array in a buffer for OpenGL to use
glBindBuffer(GL_ARRAY_BUFFER, VBO); //3. vertex buffer 객체 바인드&vertex data 할당
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//4. 데이터에서 입력 속성 범위 설정
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

 

vertex attributes pointer 속성 호출을 한번 VAO에 바인드하고, 렌더링 루프에서 해당 VAO에 바인드하면 렌더링됨.

while (!glfwWindowShouldClose(pWindow)) {
	..
	glUseProgram(shaderProgram); //Shader 프로그램 설정
	glBindVertexArray(VAO); //입력 VAO 바인드(입력 데이터 설정)
	glDrawArrays(GL_TRIANGLES, 0, 3); //Drawing
	...
}

 

Element Buffer Object (EBO)

OpenGL이 vertex를 그리는 순서에 대한 인덱스를 저장하는 버퍼

VBO 바인드할 때 EBO를 함께 바인드

unsigned int EBO; 
glGenBuffers(1, &EBO);  //버퍼 생성, 데이터 할당은 VBO와 동일
:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); //차이! VBO는 GL_ARRAY_BUFFER
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
while(!glfwWindowShouldClose(pWindow)){
	:
	//(무엇을 그릴지, 인덱스 수, 인덱스 타입, 인덱스 오프셋)
	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //차이! VBO는 glDrawArrays
	:
}

 

 

'강의 > HCI' 카테고리의 다른 글

[HCI] Graphics & OpenGL 4  (0) 2025.04.22
[HCI] Graphics & OpenGL 3  (0) 2025.04.03
[HCI] Graphics & OpenGL 1  (1) 2025.03.26
'강의/HCI' 카테고리의 다른 글
  • [HCI] Graphics & OpenGL 4
  • [HCI] Graphics & OpenGL 3
  • [HCI] Graphics & OpenGL 1
개발자 밍
개발자 밍
dev0404 님의 블로그 입니다.
  • 개발자 밍
    Developer
    개발자 밍
  • 전체
    오늘
    어제
    • 분류 전체보기 (88)
      • 강의 (8)
        • UE Climbing System (3)
        • UE Dungeon (1)
        • HCI (4)
      • 책 (18)
        • 객체지향의 사실과 오해 (5)
        • Effective C++ (3)
        • 이득우의 게임 수학 (4)
        • 이것이 취업을 위한 컴퓨터 과학이다 (4)
        • 리뷰 (2)
      • C++ (2)
      • 알고리즘 (2)
      • 자료구조 (1)
      • Unreal (4)
      • 내일배움캠프 (52)
        • TIL (52)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    알고리즘
    그래픽스
    게임수학
    언리얼
    Effective
    c++
    객체지향
    자료구조
    내일배움캠프
    컴퓨터구조
    컴퓨터 구조
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
개발자 밍
[HCI] Graphics & OpenGL 2
상단으로

티스토리툴바