[OpenGL] 12. Shader (8) - 여러 Texture 생성하기

2024. 4. 14. 03:08·CS/HCI 윈도우즈프로그래밍
반응형

Sampler

GLSL 에서 텍스쳐 객체를 저장하기 위한 내장 데이터 타입 (일종의 컨테이너) 이다.

텍스쳐 타입에 따라 sampler1D, sampler2D, sampler3D  등으로 분류되며, uniform 변수로 선언한다.

기본적으로 디폴트값이 정해져 있어서, 텍스쳐를 하나만 바인딩하는 경우에는 직접 유니폼 변수에 값을 등록하지 않아도 바로 사용할 수 있다.

 

텍스쳐를 유니폼 변수에 직접 등록하기

텍스쳐를 유니폼 변수에서 사용할 때는 텍스쳐의 위치에 해당하는 정수값을 넘겨주게 된다.

이러한 텍스쳐의 위치를 texture unit 이라고 한다.

이 텍스쳐 유닛의 기본값은 0이다. (그래서 하나를 바인딩할 때는 바로 가져다 사용할 수 있는 것)

텍스쳐 유닛을 사용하는 이유는 사용자가 셰이더로 하여금 1개 이상의 텍스쳐를 사용할 수 있도록 만들기 위함이다.

unsigned int texture1;
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(data);

 

우선 원래 등록하던대로 텍스쳐를 만들어서 이미지까지 연결시킨다.

원래는 이렇게만 하면 0번 위치에 알아서 바인딩이 되었다.

// Texture 2 loading
data = stbi_load("pepe.jpg", &width, &height, &componentCount, 0);

unsigned int texture2;
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(data);

 

두번째 텍스쳐도 이렇게 불러온다.

 

shader.use();
glUniform1i(glGetUniformLocation(shader.ID, "texture1"), 0);
glUniform1i(glGetUniformLocation(shader.ID, "texture2"), 1);

 

다음으로는 텍스쳐를 uniform 변수로 등록한다.

shader.use() 를 렌더링 루프 밖에서 호출하는 이유는 이렇게 셰이더를 활성화해두어야 등록이 되기 때문이라고 한다.

shader.setInt("texture2", 1);

 

셰이더 클래스를 사용하는 경우, 유니폼 변수를 이렇게 등록할 수도 있다.

 

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);

shader.use();

 

마지막으로 렌더링 루프에서 shader.use() 를 호출하기 전에 Texutre 를 각 할당한 인덱스별로 활성화하고, 바인딩까지 하면 된다.

 

아래는 실행 결과이다.

 

소스코드

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "stb_image.h"
#include "Shader.h"

float vertice[] = {
	-0.5, -0.5, 1.0, 0.0, 0.0, // 왼쪽 아래
	 0.5, -0.5, 1.0, 1.0, 0.0, // 오른쪽 아래
	-0.5,  0.5, 1.0, 0.0, 1.0, // 왼쪽 위
	 0.5,  0.5, 1.0, 1.0, 1.0, // 오른쪽 위
};

unsigned int indice[] = {
	0, 1, 2,
	1 ,2, 3
};

int main() {
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	GLFWwindow* window = glfwCreateWindow(800, 600, "multiple texture", NULL, NULL);
	glfwMakeContextCurrent(window);

	gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);

	// VBO, EBO, VAO
	unsigned int VBO, EBO, VAO;
	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);

	glGenBuffers(1, &VBO);
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertice), vertice, GL_STATIC_DRAW);

	glGenBuffers(1, &EBO);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indice), indice, GL_STATIC_DRAW);

	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)0);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (void*)(sizeof(float)*3));
	glEnableVertexAttribArray(1);

	// Shader
	Shader shader("7_texture.vs", "7_texture.fs");

	// Texture 1 loading
	unsigned char* data;
	int width, height, componentCount;
	data = stbi_load("container.jpg", &width, &height, &componentCount, 0);
	

	unsigned int texture1;
	glGenTextures(1, &texture1);
	glBindTexture(GL_TEXTURE_2D, texture1);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
	glGenerateMipmap(GL_TEXTURE_2D);
	stbi_image_free(data);

	// Texture 2 loading
	data = stbi_load("pepe.jpg", &width, &height, &componentCount, 0);

	unsigned int texture2;
	glGenTextures(1, &texture2);
	glBindTexture(GL_TEXTURE_2D, texture2);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
	glGenerateMipmap(GL_TEXTURE_2D);
	stbi_image_free(data);

	shader.use();
	glUniform1i(glGetUniformLocation(shader.ID, "texture1"), 0);
	/*glUniform1i(glGetUniformLocation(shader.ID, "texture2"), 1);*/
	shader.setInt("texture2", 1);

	while (!glfwWindowShouldClose(window)) {
		glClearColor(0.5, 0.5, 0.5, 1.0);
		glClear(GL_COLOR_BUFFER_BIT);

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texture1);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texture2);

		shader.use();
		glBindVertexArray(VAO);
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL);

		glEnable(GL_LINE_SMOOTH);

		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	glDeleteBuffers(1, &VBO);
	glDeleteBuffers(1, &EBO);
	glDeleteVertexArrays(1, &VAO);

	glfwTerminate();
}

 

#version 330 core
in vec2 TexCoord;
out vec4 aColor;
uniform sampler2D texture1;
uniform sampler2D texture2;
void main() {
    //aColor = vec4(0.7, 0.7, 0.7, 1.0);
    aColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
}

 

fragment shader 코드이다.

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
void main()
{
   gl_Position = vec4(aPos, 1.0);
   TexCoord = aTexCoord;
}

 

vertex shader 소스코드이다.

반응형
저작자표시 비영리 변경금지 (새창열림)

'CS > HCI 윈도우즈프로그래밍' 카테고리의 다른 글

[OpenGL] 14. Transformation (2) - 복합 변환  (0) 2024.04.18
[OpenGL] 13. Transformation (1) - 변환의 기본 개념  (0) 2024.04.17
[OpenGL] 11. Shader (7) - Texture Wrapping, Filtering, MipMaps  (1) 2024.04.12
[OpenGL] 10. Shader (6) - Texture  (0) 2024.04.11
[OpenGL] 9. Shader (5) - 직사각형에 실시간으로 변하는 색상 입히기 (GLFW, GLAD)  (0) 2024.04.09
'CS/HCI 윈도우즈프로그래밍' 카테고리의 다른 글
  • [OpenGL] 14. Transformation (2) - 복합 변환
  • [OpenGL] 13. Transformation (1) - 변환의 기본 개념
  • [OpenGL] 11. Shader (7) - Texture Wrapping, Filtering, MipMaps
  • [OpenGL] 10. Shader (6) - Texture
에버듀
에버듀
개발은 좋은데 뭘로 개발할까
  • 에버듀
    Blog. 에버듀
    에버듀
  • 전체
    오늘
    어제
    • 분류 전체보기 (615)
      • 개인 프로젝트 (43)
        • 토이 프로젝트 (3)
        • [2020] 카카오톡 봇 (9)
        • [2021] 코드악보 공유APP (22)
        • [2022] 유튜브 뮤직 클론코딩 (9)
        • [2025] 한글 SQL 데이터베이스 (0)
      • 팀 프로젝트 (22)
        • [2020] 인공지능 숫자야구 (4)
        • [2022] OSAM 온라인 해커톤 (10)
        • [2024] GDSC 프로젝트 트랙 (6)
        • [2025] 큰소리 웹 페이지 (2)
      • CS (335)
        • 자료구조 (19)
        • 어셈블리 (41)
        • 멀티미디어응용수학 (7)
        • 컴퓨터 구조 (29)
        • 알고리즘 분석 (4)
        • 컴퓨터 네트워크 (38)
        • 프로그래밍언어론 (15)
        • HCI 윈도우즈프로그래밍 (26)
        • 기초데이터베이스 (29)
        • 운영체제 (23)
        • 오토마타 (24)
        • 문제해결기법 (11)
        • 블록체인 (22)
        • 소프트웨어공학 (21)
        • 기계학습심화 (12)
        • 컴퓨터그래픽스와 메타버스 (8)
        • 분산시스템특론 (6)
      • 자기계발 (45)
        • 생각 정리 (23)
        • 대외활동 (11)
        • 동아리 (7)
        • 자격증 (3)
        • 머니 스터디 (1)
      • 알고리즘 (PS) (107)
        • BOJ (101)
        • Programmers (5)
        • 알고리즘 이모저모 (1)
      • WEB(BE) (8)
        • express.js (1)
        • Spring & Spring Boot (7)
      • WEB(FE) (2)
        • html, css, js (1)
        • React.js (1)
      • Tool & Language (6)
        • Edit Plus (1)
        • Git (1)
        • Python3 (2)
        • Java (2)
      • Infra (12)
        • AWS (1)
        • Oracle Cloud (8)
        • Firebase (2)
        • Network (1)
      • Android (18)
        • Java (6)
        • Flutter (12)
      • Window (2)
        • Visual Studio 없이 WPF (1)
        • MFC (1)
      • 독서 (14)
        • Inside Javascript (7)
        • Database Internals (6)
        • 한 글 후기 (1)
  • 링크

    • github
    • website
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
에버듀
[OpenGL] 12. Shader (8) - 여러 Texture 생성하기
상단으로

티스토리툴바