1 Getting started 6 Textures - JJhuk/LearnOpenGL GitHub Wiki
LearnOpenGL - Textures
url: https://learnopengl.com/Getting-started/Textures μμ±μΌ: 2021λ 1μ 2μΌ μ€ν 3:16
μ°λ¦¬λ μ€λΈμ νΈμ λ λ§μ λν μΌμ μΆκ°νκΈ° μν΄ κ° λ²ν μ€μ μμμ μ¬μ©νμ¬ ν₯λ―Έλ‘μ΄ μ΄λ―Έμ§λ₯Ό λ§λ€ μ μλ€λ κ²μ λ°°μ μ΅λλ€. κ·Έλ¬λ μ¬μ€κ°μ λ μ»κΈ° μν΄μ λ λ§μ μμμ μ§μ ν μ μλλ‘ λ§μ λ²ν μ€κ° μμ΄μΌ ν©λλ€. κ° λͺ¨λΈμλ ν¨μ¬ λ λ§μ λ²ν μ€λ€μ΄ νμνκ³ κ° λ²ν μ€μ λν΄ μμ μμ±λ νμνκΈ° λλ¬Έμ μ΄κ²μ μλΉν μμ μΆκ° μ€λ²ν€λλ₯Ό μ°¨μ§ν©λλ€.
μν°μ€νΈμ νλ‘κ·Έλλ¨Έκ° μΌλ°μ μΌλ‘ μ νΈνλ κ²μ ν μ€μ³λ₯Ό μ¬μ©νλ κ²μ λλ€. ν μ€μ³λ κ°μ²΄μ μΈλΆ μ 보λ₯Ό μΆκ°νλ λ° μ¬μ©λλ 2Dμ΄λ―Έμ§ (1Dλ° 3Dλ μ‘΄μ¬ν¨)μ λλ€. (μλ₯Όλ€μ΄) ν μ€μ³λ₯Ό λ©μ§ λ²½λ μ΄λ―Έμ§κ° μλ μ’ μ΄ νμ₯μΌλ‘ μκ°νλ©΄ 3D μ§ μμ κΉλνκ² μ νμ μ§μ λ²½λ μΈκ΄μ΄ μλ κ² μ²λΌ 보μ λλ€. λ¨μΌ μ΄λ―Έμ§μ λ§μ λν μΌμ μ½μ ν μ μκΈ° λλ¬Έμ μΆκ° λ²ν μ€λ₯Ό μ§μ νμ§ μκ³ λ μ€λΈμ νΈκ° λ§€μ° μΈλ°ν λλμ μ€ μ μμ΅λλ€.
μ΄λ―Έμ§ μμ μλ ν μ€μ³λ₯Ό μ¬μ©νμ¬ μ °μ΄λλ‘ λ³΄λΌ λλμ μμ λ°μ΄ν° 컬λ μ μ μ μ₯νλ λ°λ μ¬μ©ν μ μμ§λ§ λ€λ₯Έ μ£Όμ λ‘ λμ΄κ°κ² μ΅λλ€.
μλμμ μ΄μ μ₯μμ μΌκ°νμ΄ λ§€ν λ λ²½λλ²½ μ ν μ€μ³ μ΄λ―Έμ§λ₯Ό λ³Ό μ μμ΅λλ€.
ν μ€μ³λ₯Ό μΌκ°νμ 맀ννλ €λ©΄ μΌκ°νμ κ° κΌμ§μ μ ν΄λΉνλ ν μ€μ³ λΆλΆμ μλ €μΌ ν©λλ€. λ°λΌμ κ° λ²ν μ€μλ ν μ€μ³ μ΄λ―Έμ§μμ μνλ§ν λΆλΆμ μ§μ νλ ν μ€μ³ μ’νκ° μμ΄μΌ ν©λλ€. νλ κ·Έλ¨ΌνΈ λ³΄κ°μ λλ¨Έμ§ νλ κ·Έλ¨ΌνΈμ λν΄ λλ¨Έμ§λ₯Ό μνν©λλ€.
ν
μ€μ³ μ’νλ x
λ° y
μΆμ 0
μμ 1
κΉμ§ μ
λλ€. (2D ν
μ€μ³ μ΄λ―Έμ§λ₯Ό μ¬μ©νλ€λ μ μ κΈ°μ΅νμΈμ.) ν
μ€μ² μ’νλ₯Ό μ¬μ©νμ¬ ν
μ€μ² μμμ κ²μνλ κ²μ μνλ§μ΄λΌκ³ ν©λλ€. ν
μ€μ² μ’νλ ν
μ€μ² μ΄λ―Έμ§μ μΌμͺ½ νλ¨μ λν (0,0)
μμ μμνμ¬ ν
μ€μ² μ΄λ―Έμ§μ μ€λ₯Έμͺ½ μλ¨μ λν (1,1)
κΉμ§μ
λλ€. λ€μ μ΄λ―Έμ§λ ν
μ€μ² μ’νλ₯Ό μΌκ°νμ 맀ννλ λ°©λ²μ 보μ¬μ€λλ€. λ€μ μ΄λ―Έμ§λ ν
μ€μ² μ’νλ₯Ό μΌκ°νμ 맀ννλ λ°©λ²μ 보μ¬μ€λλ€.
μΌκ°νμ λν΄ 3κ°μ ν
μ€μ² μ’ν μ μ μ§μ ν©λλ€. μΌκ°νμ μΌμͺ½ νλ¨μ΄ ν
μ€μ²μ μΌμͺ½ νλ¨κ³Ό μΌμΉνκΈ°λ₯Ό μνλ―λ‘ μΌκ°νμ μΌμͺ½ νλ¨ λ²ν
μ€μ (0.0)
ν
μ€μ² μ’νλ₯Ό μ¬μ©ν©λλ€. (1,0)
ν
μ€μ² μ’νκ° μλ μ€λ₯Έμͺ½ νλ¨μλ λμΌνκ² μ μ©λ©λλ€. μΌκ°νμ μλ¨μ ν
μ€μ² μ΄λ―Έμ§μ μλ¨ μ€μκ³Ό μΌμΉν΄μΌ νλ―λ‘ (0.5, 1.0)
μ ν
μ€μ² μ’νλ‘ μ¬μ©ν©λλ€. λ²ν
μ€ μ
°μ΄λμ 3κ°μ ν
μ€μ² μ’νλ§ μ λ¬νλ©΄ λ©λλ€. κ·Έλ¬λ©΄ κ° νλ κ·Έλ¨ΌνΈμ λͺ¨λ ν
μ€μ² μ’νλ₯Ό κΉλνκ² λ³΄κ°νλ νλ κ·Έλ¨ΌνΈ μ
°μ΄λλ‘ μ λ¬λ©λλ€.
κ²°κ³Ό ν μ€μ² μ’νλ λ€μκ³Ό κ°μ΅λλ€.
float texCoords[] = {
0.0f, 0.0f, // μΌμͺ½ μλ κΌμ§μ
1.0f, 0.0f, // μ€λ₯Έμͺ½ μλ κΌμ§μ
0.5f, 1.0f // μ€μ μλ¨ κΌμ§μ
};
νμ€μ² μνλ§μ ν΄μμ΄ λμ¨νμ¬ λ€μν λ°©λ²μΌλ‘ μν ν μ μμ΅λλ€. λ°λΌμ OpenGLμκ² ν μ€μ²λ₯Ό μνλ§ νλ λ°©λ²μ μλ €μ£Όλ κ²μ΄ μ°λ¦¬μ μ무μ λλ€.
Texture Wrapping
ν
μ€μ² μ’νλ μΌλ°μ μΌλ‘ (0, 0)
μμ (1,1)
κΉμ§ μ΄μ§λ§ λ²μλ₯Ό λ²μ΄λ μ’νλ₯Ό μ§μ νλ©΄ μ΄λ»κ² λ κΉμ? OpenGLμ κΈ°λ³Έ λμμ ν
μ€μ² μ΄λ―Έμ§λ₯Ό λ°λ³΅νλ κ²μ
λλ€. (κΈ°λ³Έμ μΌλ‘ λΆλ μμμ ν
μ€μ² μ’νμ μ μ λΆλΆμ 무μν¨.) OpenGLμ΄ μ 곡νλ λ λ§μ μ΅μ
μ΄ μμ΅λλ€.
- GL_REPEAT : ν μ€μ³μ κΈ°λ³Έ λμμ λλ€. ν μ€μ² μ΄λ―Έμ§λ₯Ό λ°λ³΅ν©λλ€.
- GL_MIRRORED_REPEAT : GL_REPEATμ κ°μ§λ§ λ°λ³΅ ν λλ§λ€ μ΄λ―Έμ§λ₯Ό λ―Έλ¬λ§ν©λλ€.
- GL_CLAMP_TO_EDGE :
0
κ³Ό1
μ¬μ΄ μ’νλ₯Ό κ³ μ ν©λλ€. κ·Έ κ²°κ³Ό λ λμ μ’νκ° κ°μ₯μ리μ κ³ μ λμ΄ κ°μ₯μ리 ν¨ν΄μ΄ λμ΄λ©λλ€. - GL_CLAMP_TO_BORDER : μ΄μ λ²μ λ°μ μ’νμ μ¬μ©μ μ§μ ν λ리 μμμ΄ μ§μ λ©λλ€.
κ° μ΅μ μ κΈ°λ³Έ λ²μλ₯Ό λ²μ΄λ ν μ€μ² μ’νλ₯Ό μ¬μ©ν λ λ€λ₯Έ μκ°μ μΆλ ₯μ κ°μ§λλ€. μν μμ€μ² μ΄λ―Έμ§ (HΓ³lger Rezendeμ μλ³Έ μ΄λ―Έμ§)μμ μ΄κ²μ΄ μ΄λ»κ² 보μ΄λμ§ λ³΄κ² μ΅λλ€.
μμ μΈκΈν κ° μ΅μ
μ glTexParameter*
ν¨μλ₯Ό μ¬μ©νμ¬ μ’ν μΆ (s
, t
(3D ν
μ€μ³λ₯Ό μ¬μ©νλ κ²½μ° r
) λΉ x
, y
, z
μ ν΄λΉ)λ³λ‘ μ€μ ν μ μμ΅λλ€.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
첫 λ²μ§Έ μΈμλ ν
μ€μ² λμμ μ§μ ν©λλ€. 2D ν
μ€μ²λ‘ μμ
νκ³ μμΌλ―λ‘ ν
μ€μ² λμμ GL_TEXTURE_2D
μ
λλ€. λλ²μ§Έ μΈμλ μ€μ νλ €λ μ΅μ
κ³Ό ν
μ€μ² μΆμ μ§μ ν΄μΌ ν©λλ€. S
μ T
μΆ λͺ¨λμ λν΄ κ΅¬μ±νλ €κ³ ν©λλ€. λ§μ§λ§ μΈμλ μ°λ¦¬κ° μνλ ν
μ€μ² λν λͺ¨λλ₯Ό μ λ¬νλλ‘ μꡬνλ©°, μ΄ κ²½μ° OpenGLμ GL_MIRRORED_REPEAT
λ‘ νμ¬ νμ±ν λ ν
μ€μ²μ ν
μ€μ² λν μ΅μ
μ μ€μ ν©λλ€.
GL_CLAMP_TO_BORDER
μ΅μ
μ μ ννλ©΄ ν
λ리 μμλ μ§μ ν΄μΌ ν©λλ€. μ΄κ²μ GL_TEXTURE_BORDER_COLOR
λ₯Ό μ΅μ
μΌλ‘ μ¬μ©νλ glTexParameter
ν¨μμ ν΄λΉνλ fv
λ₯Ό μ¬μ©νμ¬ μνλλ©°, μ¬κΈ°μμ ν
λ리μ μμ κ°μ λΆλ λ°°μ΄μ μ λ¬ν©λλ€.
float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
Texture Filtering
ν
μ€μ³ μ’νλ ν΄μλμ μμ‘΄νμ§ μμ§λ§ λΆλ μμμ κ°μ΄ λ μ μμΌλ―λ‘ OpenGLμ ν
μ€μ² μ’νλ₯Ό 맀ν ν ν
μ€μ² ν½μ
(ν
μ
μ΄λΌκ³ λ ν¨)μ νμ
ν΄μΌ ν©λλ€. μ΄κ²μ λ§€μ° ν° λ¬Όμ²΄μ μ ν΄μλ ν
μ€μ²κ° μμ κ²½μ° νΉν μ€μν©λλ€. OpenGLμλ μ΄λ¬ν ν
μ€μ² νν°λ§ μ΅μ
λ ν¬ν¨λμ΄ μλ€κ³ μΆμΈ‘ν μ μμ΅λλ€. μ¬λ¬ κ°μ§ μ΅μ
μ μ¬μ©ν μ μμ§λ§, νμ¬ κ°μ₯ μ€μν μ΅μ
μΈ GL_NEAREST
λ° GL_LINEAR
μ λν΄ μ΄ν΄λ³΄κ² μ΅λλ€.
GL_NEAREST
(κ°μ₯ κ°κΉμ΄ μ΄μ λλ ν¬μΈνΈ νν°λ§μ΄λΌκ³ λ ν¨)λ OpenGLμ κΈ°λ³Έ ν
μ€μ² νν°λ§ λ°©λ²μ
λλ€. GL_NEAREST
λ‘ μ€μ νλ©΄ OpenGLμ μ€μ¬μ΄ ν
μ€μ² μ’νμ κ°κΉμ΄ ν
μ
μ μ νν©λλ€. μλμμ μμκ°κ° μ νν ν
μ€μ² μ’νλ₯Ό λνλ΄λ 4ν½μ
μ λ³Ό μ μμ΅λλ€. μΌμͺ½ μλ¨ ν
μ
μ ν
μ€μ² μ’νμ κ°μ₯ κ°κΉμ΄ μ€μ¬μ κ°μ§λ―λ‘ μνλ§ λ μμμΌλ‘ μ νλ©λλ€.
GL_LINEAR
((μ΄μ€) μ ν νν°λ§μ΄λΌκ³ λ ν¨)μ ν
μ€μ² μ’νμ μΈμ ν
μ
μμ λ³΄κ° λ κ°μ κ°μ Έμ ν
μ
μ¬μ΄μ μμμ κ·Όμ¬ν©λλ€. ν
μ€μ² μ’νμμ ν
μ
μ€μ¬κΉμ§μ κ±°λ¦¬κ° μμμλ‘ ν΄λΉ ν
μ
μ μμμ΄ μνλ§ λ μμμ λ λ§μ΄ κΈ°μ¬ν©λλ€. μλμμ μ΄μ ν½μ
μ νΌν© μμμ΄ λ°νλλ κ²μ λ³Ό μ μμ΅λλ€.
κ·Έλ¬λ μ΄λ¬ν ν μ€μ² νν°λ§ λ°©λ²μ μκ°μ ν¨κ³Όλ 무μμΌκΉμ? ν° κ°μ²΄μ μ ν΄μλμ ν μ€μ²λ₯Ό μ¬μ©ν λ μ΄λ¬ν λ°©λ²μ΄ μ΄λ»κ² μλνλμ§ μ΄ν΄λ³΄κ² μ΅λλ€. (λ°λΌμ ν μ€μ²κ° μμͺ½μΌλ‘ νμ₯λκ³ κ°λ³ ν μ μ΄ λμ λλλ€
GL_NEAREST
λ ν
μ€μ²λ₯Ό νμ±νλ ν½μ
μ λͺ
ννκ² λ³Ό μ μλ λΈλ‘ ν¨ν΄μ μμ±νλ λ°λ©΄ GL_LINEAR
μ κ°λ³ ν½μ
μ΄ λ 보μ΄λ λΆλλ¬μ΄ ν¨ν΄μ μμ±ν©λλ€. GL_LINER
μ λ³΄λ€ μ¬μ€μ μΈ μΆλ ₯μ μμ±νμ§λ§ μΌλΆ κ°λ°μλ κ·Έκ²λ³΄λ€ 8λΉνΈ λͺ¨μμ μ νΈνλ―λ‘ GL_NEAREST
μ΅μ
μ μ νν©λλ€.
νλ λ° μΆμμμ μ μν΄ ν μ€μ² νν°λ§μ μ€μ ν μ μμ΅λλ€. μλ₯Ό λ€μ΄ ν μ€μ²κ° μΆμλ λ κ°μ₯ κ°κΉμ΄ μ΄μ νν°λ§μ μ¬μ©νκ³ μ μ€μΌμΌ λ ν μ€μ²μ λν΄μ μ ν νν°λ§μ μ¬μ©ν μ μμ΅λλ€. λ°λΌμ glTexParameter*λ₯Ό ν΅ν΄ λ μ΅μ μ λν νν°λ§ λ°©λ²μ μ§μ ν΄μΌ ν©λλ€. μ½λλ λν λ°©λ² μ€μ κ³Ό μ μ¬ν΄μΌ ν©λλ€.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Mipmaps
μμ²κ°μ λ¬Όμ²΄κ° μλ ν° λ°©μ΄ μκ³ κ°κ° ν μ€μ²κ° λΆμ΄μλ€κ³ μμν΄λ³΄μΈμ. λ·°μ΄μ κ°κΉμ΄ κ°μ²΄μ λμΌν κ³ ν΄μλ ν μ€μ²κ° μ°κ²°λ λ©λ¦¬μλ κ°μ²΄κ° μμ΅λλ€. μ€λΈμ νΈκ° λ©λ¦¬ λ¨μ΄μ Έ μκ³ μλ§λ λͺ κ°μ νλ κ·Έλ¨ΌνΈλ§ μμ±νκΈ° λλ¬Έμ OpenGLμ ν μ€μ²μ λ§μ λΆλΆμ κ±Έμ³μλ νλ κ·Έλ¨ΌνΈμ λν΄ ν μ€μ² μμμ μ νν΄μΌνκΈ° λλ¬Έμ κ³ ν΄μλ ν μ€μ²μμ νλ κ·Έλ¨ΌνΈμ λν μ¬λ°λ₯Έ μμ κ°μ κ²μνλ λ° μ΄λ €μμ κ²ͺμ΅λλ€. μ΄λ κ² νλ©΄ μμ 물체μ κ³ ν΄μλ ν μ€μ²λ₯Ό μ¬μ©νλ λ©λͺ¨λ¦¬ λμν λλΉλ λ§ν κ²λ μκ³ , μμ 물체μ κ°μμ μΈ μ΄ν©νΈκ° μμ±λ©λλ€.
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ OpenGLμ κΈ°λ³Έμ μΌλ‘ κ° νμ ν μ€μ²κ° μ΄μ ν μ€μ²μ λΉν΄ 2λ°° μμ νμ€μ² μ΄λ―Έμ§ λͺ¨μμΈ λ°λ§΅μ΄λΌλ κ°λ μ μ¬μ©ν©λλ€. λ°λ§΅μ κ°λ μ μ΄ν΄νκΈ° μ½μ΅λλ€. λ·°μ΄μμ νΉμ 거리 μκ³ κ°μ΄ μ§λλ©΄ OpenGLμ κ°μ²΄κΉμ§μ 거리μ κ°μ₯ μ ν©ν λ€λ₯Έ λ°λ§΅ ν μ€μ²λ₯Ό μ¬μ©ν©λλ€. λ¬Όμ²΄κ° λ©λ¦¬ λ¨μ΄μ Έ μκΈ° λλ¬Έμ λ μμ ν΄μλλ₯Ό μ¬μ©νλλΌλ μ¬μ©μμκ² λμ λμ§ μμ΅λλ€. κ·Έλ¬λ©΄ OpenGLμ μ¬λ°λ₯Έ ν μ μ μνλ§ ν μ μμΌλ©° λ°λ§΅μ ν΄λΉ λΆλΆμ μνλ§ ν λ κ΄λ ¨λ μΊμ 맀λͺ¨λ¦¬κ° μ€μ΄λλλ€. λ° λ§€νλ ν μ€μ²κ° μ΄λ»κ² μκ²Όλμ§ μμΈν λ³΄κ² μ΅λλ€.
κ° ν μ€μ² μ΄λ―Έμ§μ λν΄ λ° λ§€νλ ν μ€μ² λͺ¨μμ λ§λλ κ²μ μλμΌλ‘ μννκΈ°κ° λ²κ±°λ‘μ§λ§ λ€νμ€λ½κ²λ OpenGLμ ν μ€μ²λ₯Ό λ§λ ν glGenerateMipmapsλ₯Ό ν λ²λ§ νΈμΆνμ¬ λͺ¨λ μμ μ μν ν μ μμ΅λλ€.
λ λλ§ μ€μ λ°λ§΅ λ 벨 μ¬μ΄λ₯Ό μ ν ν λ OpenGLμ λ λ°λ§΅ λ μ΄μ΄ μ¬μ΄μ 보μ΄λ λ μΉ΄λ‘μ΄ κ°μ₯μ리μ κ°μ μΌλΆ μν°ν©νΈλ₯Ό νμν μ μμ΅λλ€. μΌλ° ν μ€μ² νν°λ§κ³Ό λ§μ°¬κ°μ§λ‘ λ°λ§΅ μμ€ κ° μ νμ μν΄ NEAREST λ° LINEAR νν°λ§μ μ¬μ©νμ¬ λ°λ§΅ μμ€κ°μ νν°λ§ ν μλ μμ΅λλ€. λ°λ§΅ λ 벨 μ¬μ΄μ νν°λ§ λ°©λ²μ μ§μ νκΈ° μν΄ μλ νν°λ§ λ°©λ²μ λ€μ λ€ κ°μ§ μ΅μ μ€ νλλ‘ λ체 ν μ μμ΅λλ€.
- GL_NEAREST_MIPMAP_NEAREST : ν½μ ν¬κΈ°μ μΌμΉμν€κΈ° μν΄ κ°μ₯ κ°κΉμ΄ λ°λ§΅μ μ·¨νκ³ ν μ€μ² μνλ§μ κ°μ₯ κ°κΉμ΄ μ΄μ 보κ°μ μ¬μ©ν©λλ€.
- GL_LINEAR_MIPMAP_NEAREST : κ°μ₯ κ°κΉμ΄ λ°λ§΅ λ 벨μ μ·¨νκ³ μ ν 보κ°μ μ¬μ©νμ¬ ν΄λΉ λ 벨μ μνλ§ν©λλ€.
- GL_NEAREST_MIPMAP_LINEAR : ν½μ ν¬κΈ°μ κ°μ₯ κ·Όμ ν λ λ°λ§΅ μ¬μ΄λ₯Ό μ ν 보κ°νκ³ κ°μ₯ κ°κΉμ΄ μ΄μ 보κ°μ ν΅ν΄ λ³΄κ° λ λ 벨μ μνλ§ν©λλ€.
- GL_LINEAR_MIPMAP_LINEAR : κ°μ₯ κ°κΉμ΄ λ λ°λ§΅ μ¬μ΄λ₯Ό μ νμΌλ‘ 보κ°νκ³ μ ν 보κ°μ ν΅ν΄ 보κ°λ λ 벨μ μνλ§ν©λλ€.
ν μ€μ² νν°λ§κ³Ό λ§μ°¬κ°μ§λ‘ νν°λ§ λ°©λ²μ glTexParameteriλ₯Ό μ¬μ©νμ¬ μμ μΈκΈν 4κ°μ§ λ°©λ² μ€ νλλ₯Ό μ¬μ©ν μ μμ΅λλ€.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
μΌλ°μ μΈ μ€μλ λ°λ§΅ νν°λ§ μ΅μ μ€ νλλ₯Ό νλ νν°λ‘ μ€μ νλ κ²μ λλ€. λ°λ§΅μ μ£Όλ‘ ν μ€μ²κ° μΆμ λ λ μ¬μ©λκΈ° λλ¬Έμ ν¨κ³Όκ° μμ΅λλ€. ν μ€μ² νλλ λ°λ§΅μ μ¬μ©νμ§ μμΌλ©° λ°λ§΅ νν°λ§ μ΅μ μ μ 곡νλ©΄ OpenGL GL_INVALID_ENUM μλ¬ μ½λκ° μμ±λ©λλ€.
Loading and Creating textures
μ€μ λ‘ ν
μ€μ²λ₯Ό μ¬μ©νκΈ° μν΄ ν΄μΌν 첫 λ²μ§Έ μΌμ μ ν리μΌμ΄μ
μ λ‘λνλ κ²μ
λλ€. ν
μ€μ² μ΄λ―Έμ§λ κ°κ° κ³ μ ν ꡬ쑰μ λ°μ΄ν° μμκ° μλ μμκ°μ νμΌ νμμΌλ‘ μ μ₯ν μ μμ΅λλ€. κ·Έλ λ€λ©΄ μ ν리μΌμ΄μ
μμ μ΄λ¬ν μ΄λ―Έμ§λ₯Ό μ΄λ»κ² κ°μ Έμ¬ μ μμκΉμ? ν κ°μ§ ν΄κ²°μ±
μ .png
μ κ°μ΄ μ¬μ©ν νμΌ νμμ μ ννκ³ μ체 μ΄λ―Έμ§ λ‘λλ₯Ό μμ±νμ¬ μ΄λ―Έμ§ νμμ ν° λ°μ΄νΈ λ°°μ΄λ‘ λ³ννλ κ²μ
λλ€. μ체 μ΄λ―Έμ§ λ‘λλ₯Ό μμ±νλ κ²μ 그리 μ΄λ ΅μ§λ μμ§λ§ μ¬μ ν λ²κ±°λ‘κ³ λ λ§μ νμμ μ§μνλ €λ©΄ κ° νμμ λν΄ μ΄λ―Έμ§ λ‘λλ₯Ό μμ±ν΄μΌ ν©λλ€.
λ λ€λ₯Έ ν΄κ²°μ±
μ΄μ μ’μ 보μ΄λ ν΄κ²°μ±
μ μμ£Ό μ¬μ©νλ μ¬λ¬κ°μ§ νμμ μ§μνκ³ μ°λ¦¬λ₯Ό μν΄ λͺ¨λ λ
Έλ ₯μ λ€νλ μ΄λ―Έμ§ λ‘λ© λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ κ²μ
λλ€. std_image.h
μ κ°μκ±° λ§μ΄μ£
stb_image.h
stb_image.h
λ Sean Barrett μ λ§€μ° μΈκΈ°μλ λ¨μΌ ν€λ μ΄λ―Έμ§ λ‘λ© λΌμ΄λΈλ¬λ¦¬λ‘, κ°μ₯ λ§μ΄ μ¬μ©λλ νμΌ νμμ λ‘λν μ μμΌλ©°, νλ‘μ νΈμ μ½κ² ν΅ν©ν μ μμ΅λλ€. stb_image.h
λ μ¬κΈ°μμ λ€μ΄λ‘λ ν μ μμ΅λλ€. λ¨μΌ ν€λνμΌμ λ€μ΄λ‘λνκ³ stb_image.h
λ‘ νλ‘μ νΈμ μΆκ°ν ν λ€μ μ½λλ‘ μΆκ° C++ νμΌμ λ§λλλ€.
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h
STB_IMAGE_IMPLEMENTATION μ μ μν¨μΌλ‘μ¨ μ μ²λ¦¬κΈ°λ κ΄λ ¨ μ μ μμ€ μ½λλ§ ν¬ν¨νλλ‘ ν€λ νμΌμ μμ νμ¬ ν¨κ³Όμ μΌλ‘ ν€λ νμΌμ .cpp
νμΌλ‘ λ³νν©λλ€. μ΄μ νλ‘κ·Έλ¨ μ΄λκ°μ std_image.h
λ₯Ό ν¬ν¨νκ³ μ»΄νμΌνμμμ€.
λ€μ ν
μ€μ² μΉμ
μλ λ무 컨ν
μ΄λμ μ΄λ―Έμ§λ₯Ό μ¬μ©ν©λλ€. stb_image.h
λ₯Ό μ¬μ©νμ¬ μ΄λ―Έμ§λ₯Ό λ‘λνλ €λ©΄ stbi_load ν¨μλ₯Ό μ¬μ©ν©λλ€.
int width, height, nrChannels;
unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
μ΄ ν¨μλ λ¨Όμ μ΄λ―Έμ§ νμΌμ μμΉλ₯Ό μ
λ ₯μΌλ‘ λ°μ΅λλ€. κ·Έλ° λ€μ stb_image.h
κ° κ²°κ³Ό μ΄λ―Έμ§μ λλΉ, λμ΄ λ° μμ 체λλ‘ μ±μΈ **λ λ²μ§Έ, μΈ λ²μ§Έ, λ€ λ²μ§Έ μΈμλ‘ μΈ κ°μ ints
λ₯Ό μ 곡 ν κ²μΌλ‘ μμν©λλ€. λμ€μ ν
μ€μ²λ₯Ό μμ±νλ €λ©΄ μ΄λ―Έμ§μ λλΉμ λμ΄κ° νμν©λλ€.
Generating a texture
OpenGLμ μ΄μ κ°μ²΄μ λ§μ°¬κ°μ§λ‘ ν μ€μ²λ IDλ‘ μ°Έμ‘°λ©λλ€. νλ λ§λ€μ΄ λ³΄κ² μ΅λλ€.
unsigned int texture;
glGenTextures(1, &texture);
glGenTextures ν¨μλ λ¨Όμ μ°λ¦¬κ° μμ±νλ €λ ν
μ€μ²μ μλ₯Ό μ
λ ₯μΌλ‘ μ·¨νκ³ λ λ²μ§Έ μΈμλ‘ μ§μ λ unsigned int
λ°°μ΄λ‘ μ μ₯ν©λλ€ (μ΄ κ²½μ°μλ λ¨μΌ unsigned int
). λ€λ₯Έ μ€λΈμ νΈμ λ§μ°¬κ°μ§λ‘ λ°μΈλ© ν΄μΌ νμ ν
μ€μ² λͺ
λ Ήμ΄ νμ¬ λ°μΈλ© λ ν
μ€μ²λ₯Ό ꡬμ±ν©λ
glBindTexture(GL_TEXTURE_2D, texture);
μ΄μ ν μ€μ²κ° λ°μΈλ©λμμΌλ―λ‘ μ΄μ μ λ‘λ λ μ΄λ―Έμ§ λ°μ΄ν°λ₯Ό μ¬μ©νμ¬ ν μ€μ³ μμ±μ μμν μ μμ΅λλ€. ν μ€μ²λ glTexImage2Dλ‘ μμ±λ©λλ€.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
μ΄κ²μ λ§€κ° λ³μκ° μλΉν λ§μ ν° ν¨μμ΄λ―λ‘ λ¨κ³λ³λ‘ μ΄ν΄λ³΄κ² μ΅λλ€.
- 첫 λ²μ§Έ μΈμλ ν μ€μ² λμμ μ§μ ν©λλ€. μ΄κ²μ GL_TEXTURE_2D λ‘ μ€μ νλ©΄ μ΄ μμ μ΄ λμΌν λμμμ νμ¬ λ°μΈλ© λ κ°μ²΄μ ν μ€μ²λ₯Ό μμ±νλ€λ μλ―Έμ λλ€. (λ°λΌμ λμ GL_TEXTURE_ID λλ GL_TEXTURE_3Dμ λ°μΈλ© λ ν μ€μ²λ μν₯μ λ°μ§ μμ΅λλ€.)
- λ λ²μ§Έ μΈμλ κ° λ°λ§΅ λ 벨μ μλμΌλ‘ μ€μ νλ €λ κ²½μ° ν
μ€μ²λ₯Ό μμ±νλ €λ λ°λ§΅ λ 벨μ μ§μ νμ§λ§ κΈ°λ³Έ λ 벨μΈ
0
μΌλ‘ λκ² μ΅λλ€. - μΈ λ²μ§Έ μΈμλ OpenGL μκ² ν
μ€μ²λ₯Ό μ μ₯ν νμμ μλ €μ€λλ€. μ΄λ―Έμ§μλ
RGB
κ°λ§ μμΌλ―λ‘RGB
κ°μΌλ‘ ν μ€μ²λ μ μ₯ν©λλ€. - λ€ λ²μ§Έμ λ€μ― λ²μ§Έ μΈμλ κ²°κ³Ό ν μ€μ²μ λλΉμ λμ΄λ₯Ό μ€μ ν©λλ€. μ΄λ―Έμ§λ₯Ό λ‘λ ν λ μ΄μ μ μ μ₯νμΌλ―λ‘ ν΄λΉ λ³μλ₯Ό μ¬μ©ν©λλ€.
- λ€μ μΈμλ νμ
0
μ΄μ΄μΌ ν©λλ€. (λ κ±°μ νλͺ©) - 7λ²μ§Έμ 8λ²μ§Έ μΈμλ μμ€ μ΄λ―Έμ§μ νμκ³Ό λ°μ΄ν° μ νμ μ§μ ν©λλ€. μ΄λ―Έμ§μ
RGB
κ°μ λ‘λνκ³char
(λ°μ΄νΈ)λ‘ μ μ₯νμΌλ―λ‘ ν΄λΉ κ°μ μ λ¬ν©λλ€. - λ§μ§λ§ μΈμλ μ€μ μ΄λ―Έμ§ λ°μ΄ν°μ λλ€.
glTexture2Dκ° νΈμΆλλ©΄ νμ¬ λ°μΈλ© λ ν μ€μ² κ°μ²΄μ ν μ€μ² μ΄λ―Έμ§κ° λΆνμ§λλ€. κ·Έλ¬λ νμ¬ ν μ€μ² μ΄λ―Έμ§μ κΈ°λ³Έ μμ€λ§ λ‘λλμ΄ μμΌλ©° λ°λ§΅μ μ¬μ©νλ €λ©΄ λͺ¨λ λ€λ₯Έ μ΄λ―Έμ§λ₯Ό μμ μΌλ‘ μ§μ ν΄μΌ ν©λλ€. (λ λ²μ§Έ μΈμλ₯Ό κ³μ μ¦κ°μν€λ©΄μ) λλ ν μ€μ²λ₯Ό μμ± ν ν glGenerateMipmapμ νΈμΆ ν μ μμ΅λλ€. κ·Έλ¬λ©΄ νμ¬ λ°μΈλ© λ ν μ€μ²μ νμν λͺ¨λ λ°λ§΅μ΄ μλμΌλ‘ μμ±λ©λλ€.
ν μ€μ² λ° ν΄λΉ λ°λ§΅ μμ±μ μλ£ ν ν μ΄λ―Έμ§ λ©λͺ¨λ¦¬λ₯Ό ν΄μ νλ κ²μ΄ μ’μ΅λλ€.
stbi_image_free(data);
λ°λΌμ ν μ€μ²λ₯Ό μμ±νλ μ 체 νλ‘μΈμ€λ λ€μκ³Ό κ°μ΅λλ€,
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// ν
μ€μ³ λν / νν°λ§ μ΅μ
μ€μ (νμ¬ λ°μΈλ© λ ν
μ€μ³ κ°μ²΄μμ)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// ν
μ€μ²λ₯Ό λ‘λ©νκ³ μμ±
int width, height, nrChannels;
unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
Applying textures
λ€μ μΉμ μμλ Hello Triangle μ₯μ λ§μ§λ§ λΆλΆμμ glDrawElementsλ‘ κ·Έλ¦° μ¬κ°ν λͺ¨μμ μ¬μ©ν©λλ€. ν μ€μ²λ₯Ό μνλ§νλ λ°©λ²μ OpenGLμ μλ €μΌ νλ―λ‘ ν μ€μ² μ’νλ‘ λ²ν μ€ λ°μ΄ν°λ₯Ό μ λ°μ΄νΈ ν΄μΌ ν©λλ€.
float vertices[] = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
μΆκ° λ²ν μ€ μμ±μ μΆκ° νμΌλ―λ‘ λ€μ OpenGLμκ² μλ‘μ΄ λ²ν μ€ νμμ μλ €μΌ ν©λλ€.
glVertexAttribPointer(2,2,GL_FLOAT,GL_FALSE,8*sizeof(float),(void*)(6*sizeof(float)));
glEnableVertexAttribArray(2);
μ΄μ λ λ²ν
μ€ μμ±μ stride λ§€κ° λ³μλ 8 * sizeof(float)
λ‘ μ‘°μ ν΄μΌ ν©λλ€.
λ€μμΌλ‘ ν μ€μ² μ’νλ₯Ό λ²ν μ€ μμ±μΌλ‘ λ°μλ€μ΄λλ‘ λ²ν μ€ μ °μ΄λλ₯Ό λ³κ²½ ν λ€μ ν΄λΉ μ’νλ₯Ό νλ κ·Έλ¨ΌνΈ μ °μ΄λλ‘ μ λ¬ν΄μΌ ν©λλ€.
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = aTexCoord;
}
κ·Έλ¬λ©΄ νλκ·Έλ¨ΌνΈ μ
°μ΄λλ TexCoord
μΆλ ₯ λ³μλ₯Ό μ
λ ₯ λ³μλ‘ λ°μ λ€μ΄μΌ ν©λλ€.
νλκ·Έλ¨ΌνΈ μ
°μ΄λλ ν
μ€μ² κ°μ²΄μ μ‘μΈμ€ ν μ μμ΄μΌ νμ§λ§ ν
μ€μ² κ°μ²΄λ₯Ό νλκ·Έλ¨ΌνΈ μ
°μ΄λλ‘ μ΄λ»κ² μ λ¬ν κΉμ? GLSLμλ μ°λ¦¬κ° μνλ ν
μ€μ² μ νμ μ λ―Έμ¬λ‘ μ·¨νλ μνλ¬λΌλ ν
μ€μ² κ°μ²΄μ λν λ΄μ₯ λ°μ΄ν° μ νμ΄ μμ΅λλ€. sampler1D
, sampler3D
λλ μ΄ κ²½μ° sampler2D
μ
λλ€. κ·Έλ° λ€μ λμ€μ ν
μ€μ²λ₯Ό ν λΉ ν uniform sampler2D
λ₯Ό μ μΈνμ¬ νλ κ·Έλ¨ΌνΈ μ
°μ΄λμ ν
μ€μ²λ₯Ό μΆκ°ν μ μμ΅λλ€.
#version 330 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCoord;
uniform sampler2D ourTexture;
void main()
{
FragColor = texture(ourTexture, TexCoord);
}
ν μ€μ²μ μμμ μνλ§νκΈ° μν΄ μ²« λ²μ§Έ μΈμλ‘ ν μ€μ² μνλ¬λ₯Ό, λ λ²μ§Έ μΈμλ‘ ν΄λΉ ν μ€μ² μ’νλ₯Ό λ°λ GLSLμ λ΄μ₯ ν μ€μ² ν¨μλ₯Ό μ¬μ©ν©λλ€. ν μ€μ² ν¨μλ μμ μ€μ ν ν μ€μ² λ§€κ° λ³μλ₯Ό μ¬μ©νμ¬ ν΄λΉ μμ κ°μ μνλ§ν©λλ€. μ΄ νλ κ·Έλ¨ΌνΈ μ °μ΄λμ μΆλ ₯μ (λ³΄κ° λ) ν μ€μ² μ’νμμ ν μ€μ²μ (νν°λ§ λ) μμμ λλ€.
μ΄μ λ¨μ μΌμ glDrawElementsλ₯Ό νΈμΆνκΈ° μ μ ν μ€μ²λ₯Ό λ°μΈλ©νλ κ²μ λλ€. κ·Έλ¬λ©΄ ν μ€μ²κ° νλ κ·Έλ¨ΌνΈ μ °μ΄λμ μνλ¬μ μλμΌλ‘ ν λΉλ©λλ€.
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
λͺ¨λ κ²μ μ¬λ°λ₯΄κ² μννλ€λ©΄ λ€μ μ΄λ―Έμ§κ° νμλ©λλ€.
μ§μ¬κ°νμ΄ μμ ν νμμ΄κ±°λ κ²μμμ΄λ©΄ λμ€μ μ€λ₯κ° λ°μν κ² μΌ μ μμ΅λλ€. μ °μ΄λ λ‘κ·Έλ₯Ό νμΈνκ³ μ½λλ₯Ό μμ€ μ½λμ λΉκ΅ ν΄ λ³΄μΈμ.
ν μ€μ² μ½λκ° μλνμ§ μκ±°λ μμ ν κ²μμμΌλ‘ νμλλ κ²½μ°, κ·Έλ₯ κ³μ λ°λΌκ°μ μλν΄μΌ νλ λ§μ§λ§ μμ λ₯Ό νμΈνμΈμ. μΌλΆ λλΌμ΄λ²μμλ κ° μνλ¬ μ λνΌμ ν μ€μ² λ¨μλ₯Ό ν λΉνλ κ²μ΄ νμμ΄λ©°, μ΄λ μ΄ μ₯μμ μμΈν μ€λͺ ν©λλ€.
μ’ νν€νκ² λ§λ€κΈ° μν΄ κ²°κ³Ό ν μ€μ² μμμ λ²ν μ€ μμκ³Ό νΌν© ν μλ μμ΅λλ€. κ²°κ³Ό ν μ€μ² μμμ νλκ·Έλ¨ΌνΈ μ °μ΄λμ λ²ν μ€ μμκ³Ό κ³±νμ¬ λ μμμ νΌν©νκΈ°λ§ νλ©΄ λ©λλ€.
FragColor = texture(ourTexture, TexCoord) * vec4(ourColor, 1.0);
λ²ν μ€μ μμκ³Ό ν μ€μ²μ μμμ νΌν©μ λ€μκ³Ό κ°μ΄ 보μ λλ€.
μ°λ¦¬ 컨ν μ΄λκ° λμ€μ½λ₯Ό μ’μνλκ±° κ°μ΅λλ€.
Texture Units
glUniformμΌλ‘ κ°μ ν λΉνμ§ μλ κ²½μ° μ sampler2D
λ³μκ° κ· μΌνμ§ κΆκΈ ν κ²μ
λλ€. glUniform1iλ₯Ό μ¬μ©νμ¬ μ€μ λ‘ location κ°μ ν
μ€μ² μνλ¬μ ν λΉν μ μμΌλ―λ‘ νλ κ·Έλ¨ΌνΈ μ
°μ΄λμμ ν λ²μ μ¬λ¬ ν
μ€μ²λ₯Ό μ€μ ν μ μμ΅λλ€. ν
μ€μ²μ μ΄ μμΉλ μΌλ°μ μΌλ‘ ν
μ€μ² λ¨μλ‘ μλ €μ Έ μμ΅λλ€. ν
μ€μ²μ κΈ°λ³Έ ν
μ€μ² λ¨μλ κΈ°λ³Έ νμ± ν
μ€μ² λ¨μμΈ 0
μ΄λ―λ‘ μ΄μ μΉμ
μμ μμΉλ₯Ό ν λΉ ν νμκ° μμ΅λλ€. λͺ¨λ κ·Έλν½ λλΌμ΄λ²κ° κΈ°λ³Έ ν
μ€μ² λ¨μλ₯Ό ν λΉνλ κ²μ μλλ―λ‘ μ΄μ μΉμ
μ΄ λ λλ§ λμ§ μμμ μλ μμ΅λλ€.
ν μ€μ² μ λμ μ£Όμ λͺ©μ μ μ °μ΄λμμ νλ μ΄μμ ν μ€μ²λ₯Ό μ¬μ©ν μ μλλ‘ νλ κ²μ λλ€. μνλ¬μ ν μ€μ² λ¨μλ₯Ό ν λΉνλ©΄ ν΄λΉ ν μ€μ² λ¨μλ₯Ό λ¨Όμ νμ±ννλ ν νλ²μ μ¬λ¬ ν μ€μ²μ λ°μΈλ© ν μ μμ΅λλ€. glBindTextureμ λ§μ°¬κ°μ§λ‘ μ¬μ©ν ν μ€μ² μ λμ μ λ¬νλ glActiveTextureλ₯Ό μ¬μ©νμ¬ ν μ€μ² μ λμ νμ±ν ν μ μμ΅λλ€.
glActiveTexture(GL_TEXTURE0); // ν
μ€μ²λ₯Ό λ°μΈλ© νκΈ° μ μ λ¨Όμ ν
μ€μ² μ λμ νμ±νν΄μΌν¨
glBindTexture(GL_TEXTURE_2D, texture);
ν μ€μ² μ λμ νμ±ν ν ν νμ glBindTexture νΈμΆμ ν΄λΉ ν μ€μ²λ₯Ό νμ¬ νμ±ν λ ν μ€μ² μ λμ λ°μΈλ©ν©λλ€. ν μ€μ² λ¨μ GL_TEXTURE0λ νμ κΈ°λ³Έμ μΌλ‘ νμ±νλμ΄ μμΌλ―λ‘ glBindTextureλ₯Ό μ¬μ©ν λ μ΄μ μμ μμ ν μ€μ² λ¨μλ₯Ό νμ±ν ν νμκ° μμ΅λλ€.
OpenGLμλ GL_TEXTURE0 ~ GL_TEXTURE15λ₯Ό μ¬μ©νμ¬ νμ±ν ν μ μλ μ΅μ 16κ°μ ν μ€μ² λ¨μκ° μμ΄μΌ ν©λλ€. μλ₯Ό λ€μ΄ GL_TEXTURE + 8μ ν΅ν΄ GL_TEXTURE8μ μ»μ μ μλλ‘ μμλλ‘ μ μλ©λλ€. μ΄λ μ¬λ¬ ν μ€μ² λ¨μλ₯Ό λ°λ³΅ν΄μΌ ν λ μ μ©ν©λλ€.
κ·Έλ¬λ λ€λ₯Έ μνλ¬λ₯Ό λ°μλ€μ΄λ €λ©΄ μ¬μ ν νλ κ·Έλ¨ΌνΈ μ °μ΄λλ₯Ό νΈμ§ν΄μΌ ν©λλ€. μ΄μ λΆν΄ λΉκ΅μ κ°λ¨ν©λλ€.
#version 330 core
...
uniform sampler2D texture1;
uniform sampler2D texture2;
void main()
{
FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
}
μ΅μ’
μΆλ ₯ μμμ μ΄μ λ ν
μ€μ²μ μ‘°ν©μ
λλ€. GLSLμ λ΄μ₯λ νΌν© ν¨μλ λ κ°μ κ°μ μ
λ ₯μΌλ‘ μ·¨νκ³ μΈ λ²μ§Έ μΈμλ₯Ό κΈ°λ°μΌλ‘ λ κ°μ μ νμΌλ‘ 보κ°ν©λλ€. μΈ λ²μ§Έ κ°μ΄ 0.0
μ΄λ©΄ 첫 λ²μ§Έ μ
λ ₯μ λ°νν©λλ€. 1.0
μ΄λ©΄ λ λ²μ§Έ μ
λ ₯ κ°μ λ°νν©λλ€. κ°μ΄ 0.2
μ΄λ©΄ 첫 λ²μ§Έ μ
λ ₯ μμμ 80%
μ λ λ²μ§Έ μ
λ ₯ μμμ 20%
κ° λ°νλμ΄ λ ν
μ€μ²κ° νΌν©λ©λλ€.
μ΄μ λ€λ₯Έ ν μ€μ²λ₯Ό λ‘λνκ³ μμ±νλ €κ³ ν©λλ€. μ΄μ λ¨κ³μ μ΅μν΄μ§μ μΌ ν©λλ€. λ€λ₯Έ ν μ€μ² κ°μ²΄λ₯Ό μμ±νκ³ μ΄λ―Έμ§λ₯Ό λ‘λνκ³ glTexImage2Dλ₯Ό μ¬μ©νμ¬ μ΅μ’ ν μ€μ²λ₯Ό μμ±ν΄μΌ ν©λλ€. λ λ²μ§Έ ν μ€μ²μλ OpenGLμ λ°μ°λ λμμ νμ μ΄λ―Έμ§λ₯Ό μ¬μ©ν©λλ€.
unsigned char *data = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);
if (data)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
μ΄μ μν(ν¬λͺ
λ) μ±λμ ν¬ν¨νλ .png
μ΄λ―Έμ§λ₯Ό λ‘λν©λλ€. μ¦, GL_RGBAλ₯Ό μ¬μ©νμ¬ μ΄λ―Έμ§ λ°μ΄ν°μ μν μ±λλ ν¬ν¨λλλ‘ μ§μ ν΄μΌ ν©λλ€. κ·Έλ μ§ μμΌλ©΄ OpenGLμ΄ μ΄λ―Έμ§ λ°μ΄ν°λ₯Ό μλͺ» ν΄μν©λλ€.
λ λ²μ§Έ ν μ€μ² (λ° μ²«λ²μ§Έ ν μ€μ²)λ₯Ό μ¬μ©νλ €λ©΄ λ ν μ€μ²λ₯Ό ν΄λΉ ν μ€μ² λ¨μμ λ°μΈλ©νμ¬ λ λλ§ μ μ°¨λ₯Ό μ½κ° λ³κ²½ν΄μΌ ν©λλ€.
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
λν glUniform1iλ₯Ό μ¬μ©νμ¬ κ° μνλ¬λ₯Ό μ€μ νμ¬ κ° μ °μ΄λ μνλ¬κ° μν ν μ€μ² λ¨μλ₯Ό OpenGLμ μλ €μΌ ν©λλ€. ν λ²λ§ μ€μ νλ©΄ λλ―λ‘ λ λλ§ λ£¨νμ λ€μ΄κ°κΈ° μ μ μ΄ μμ μ μνν μ μμ΅λλ€
ourShader.use(); //μ λνΌμ μ€μ νκΈ° μ μ μ
°μ΄λλ₯Ό μ‘ν°λΈνλ κ²μ κΉλ¨Ήμ§λ§μΈμ!
glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0); // μλμΌλ‘ μ€μ
ourShader.setInt("texture2", 1); // μλλ©΄ μ
°μ΄λ ν΄λμ€λ‘ μ€μ
while(...)
{
[...]
}
glUniform1iλ₯Ό ν΅ν΄ μνλ¬λ₯Ό μ€μ νμ¬ κ° κ· μΌν μνλ¬κ° μ μ ν ν μ€μ² λ¨μμ ν΄λΉνλμ§ νμΈν©λλ€. λ€μκ³Ό κ°μ κ²°κ³Όλ₯Ό μ»μ΄μΌ ν©λλ€.
ν
μ€μ²κ° κ±°κΎΈλ‘ λ€μ§ν κ²μ λ³Ό μ μμ κ²λλ€! μ΄κ²μ OpenGLμ΄ yμΆμ 0.0
μ’νκ° μ΄λ―Έμ§μ μλμͺ½μ μμ κ²μΌλ‘ μμνκΈ° λλ¬Έμ λ°μνμ§λ§ μ΄λ―Έμ§λ μΌλ°μ μΌλ‘ yμΆμ μμͺ½μ 0.0
μ΄ μμ΅λλ€. λ€νμ€λ½κ²λ stb_image.h
λ μ΄λ―Έμ§λ₯Ό λ‘λνκΈ° μ μ λ€μ λ¬Έμ μΆκ°νμ¬ μ΄λ―Έμ§ λ‘λ μ€μ yμΆμ λ€μ§μ μ μμ΅λλ€.
stbi_set_flip_vertically_on_load(true);
μ΄λ―Έμ§λ₯Ό λ‘λν λ stb_image.h
μκ² yμΆμ λ€μ§λλ‘ μ§μν ν λ€μ κ²°κ³Όλ₯Ό μ»μ μ μμ΅λλ€.
ν΄νΌ 컨ν μ΄λλ₯Ό λ³Ό μ μκ² λμλ€λ©΄ μνκ²λλ€. μμ€ μ½λμ λΉκ΅ν΄λ³΄μΈμ.
Exercises
ν μ€μ²μ λ μ΅μν΄ μ§λ €λ©΄ κ³μνκΈ° μ μ μ΄λ¬ν μ°μ΅μ ν΅ν΄ μμ νλ κ²μ΄ μ’μ΅λλ€.
- νλκ·Έλ¨ΌνΈ μ °μ΄λλ§ λ³κ²½νμ¬ ν볡ν μΌκ΅΄μ΄ λ°λ / μλ°©ν₯μΌλ‘ 보μ΄λμ§ νμΈνμΈμ: μ λ΅.
0.0f
~1.0f
λμ0.0f
~2.0f
λ²μμ ν μ€μ² μ’νλ₯Ό μ§μ νμ¬ λ€μν ν μ€μ² λν λ°©λ²μ μ€νν΄λ³΄μΈμ. κ°μ₯μ리μ κ³ μ λ λ¨μΌ 컨ν μ΄λ μ΄λ―Έμ§μ μλ μΌκ΅΄ 4κ°λ₯Ό νμ ν μ μλμ§ νμΈνμΈμ: μ λ΅, κ²°κ³Ό. λ€λ₯Έ ν¬μ₯ λ°©λ²λ μ€νν μ μλμ§ νμΈνμμμ€.- ν μ€μ³ μ’νλ₯Ό λ³κ²½νμ¬ κ°λ³ ν½μ μ΄ λ³΄μ΄λλ‘ μ§μ¬κ°ν ν μ€μ² μ΄λ―Έμ§μ μ€μ¬ νμ λ§ νμνλλ‘ ν©λλ€. ν½μ μ λ λͺ ννκ² λ³΄λ €λ©΄ ν μ€μ² νν°λ§ λ°©λ²μ GL_NEARESTλ‘ μ€μ νμμμ€: μ λ΅.
- κ· μΌ λ³μλ₯Ό νΌν© ν¨μμ μΈ λ²μ§Έ λ§€κ° λ³μλ‘ μ¬μ©νμ¬ λ ν μ€μ²κ° νμλλ μμ λ³κ²½ν©λλ€. μμͺ½ λ° μλμͺ½ νμ΄ν ν€λ₯Ό μ¬μ©νμ¬ μ»¨ν μ΄λ λλ μλ μΌκ΅΄μ΄ νμλλ μ λλ₯Ό λ³κ²½ν©λλ€. μ λ΅.