1 Getting started 4 Hello Triangle - JJhuk/LearnOpenGL GitHub Wiki

LearnOpenGL - Hello Triangle

url: https://learnopengl.com/Getting-started/Hello-Triangle ์ƒ์„ฑ์ผ: 2020๋…„ 12์›” 23์ผ ์˜ค์ „ 1:35

OpenGL์—์„œ๋Š” ๋ชจ๋“  ๊ฒƒ์ด 3D ๊ณต๊ฐ„์— ์žˆ์ง€๋งŒ, ํ™”๋ฉด์ด๋‚˜ ์ฐฝ์€ ํ”ฝ์…€์˜ 2D๋ฐฐ์—ด์ด๋ฏ€๋กœ OpenGL ์ž‘์—…์˜ ๋Œ€๋ถ€๋ถ„์€ ๋ชจ๋“  3D ์ขŒํ‘œ๋ฅผ ํ™”๋ฉด์— ๋งž๋Š” 2D ํ”ฝ์…€๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. 3D์ขŒํ‘œ๋ฅผ 2D ํ”ฝ์…€๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๋Š” OpenGL์˜ ๊ทธ๋ž˜ํ”ฝ ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜ํ”ฝ ํŒŒ์ดํ”„ ๋ผ์ธ์€ ํฌ๊ฒŒ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋ถ€๋ถ„์€ 3D์ขŒํ‘œ๋ฅผ 2D ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ๋‘๋ฒˆ์งธ ๋ถ€๋ถ„์€ 2D์ขŒํ‘œ๋ฅผ ์‹ค์ œ ์ƒ‰์ƒ ํ”ฝ์…€๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ์žฅ์—์„œ๋Š” ๊ทธ๋ž˜ํ”ฝ ํŒŒ์ดํ”„ ๋ผ์ธ์— ๋Œ€ํ•ด ๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ‹์ง„ ํ”ฝ์…€์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜ํ”ฝ ํŒŒ์ดํ”„๋ผ์ธ์€ 3D์ขŒํ‘œ ์„ธํŠธ๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์•„, ์ด๋ฅผ ํ™”๋ฉด์˜ ์ปฌ๋Ÿฌ 2Dํ”ฝ์…€๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜ํ”ฝํŒŒ์ดํ”„๋ผ์ธ์€ ๊ฐ ๋‹จ๊ณ„์—์„œ ์ด์ „ ๋‹จ๊ณ„์˜ ์ถœ๋ ฅ์„ ์ž…๋ ฅ์œผ๋กœ ์š”๊ตฌํ•˜๋Š” ์—ฌ๋Ÿฌ ๋‹จ๊ณ„๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋“  ๋‹จ๊ณ„๋Š” ๊ณ ๋„๋กœ ์ „๋ฌธํ™” ๋˜์–ด ์žˆ์œผ๋ฉฐ (ํ•˜๋‚˜์˜ ํŠน์ • ๊ธฐ๋Šฅ์ด ์žˆ์Œ) ๋ณ‘๋ ฌ๋กœ ์‰ฝ๊ฒŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ‘๋ ฌ ํŠน์„ฑ์œผ๋กœ ์ธํ•ด ์˜ค๋Š˜๋‚ ์˜ ๊ทธ๋ž˜ํ”ฝ์นด๋“œ์—๋Š” ๊ทธ๋ž˜ํ”ฝ ํŒŒ์ดํ”„๋ผ์ธ ๋‚ด์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ฒœ๊ฐœ์˜ ์ž‘์€ ์ฒ˜๋ฆฌ ์ฝ”์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์‹ฑ ์ฝ”์–ด๋Š” ํŒŒ์ดํ”„ ๋ผ์ธ์˜ ๊ฐ ๋‹จ๊ณ„์— ๋Œ€ํ•ด GPU์—์„œ ์ž‘์€ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ž‘์€ ํ”„๋กœ๊ทธ๋žจ์„ ์…ฐ์ด๋”๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์…ฐ์ด๋” ์ค‘ ์ผ๋ถ€๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ธฐ์กด ๊ธฐ๋ณธ ์…ฐ์ด๋”๋ฅผ ๋Œ€์ฒด ํ•  ์ž์ฒด ์…ฐ์ด๋”๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํŒŒ์ดํ”„๋ผ์ธ์˜ ํŠน์ • ๋ถ€๋ถ„์„ ํ›จ์”ฌ ๋” ์„ธ๋ฐ€ํ•˜๊ฒŒ ์ œ์–ด ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ GPU์—์„œ ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ท€์ค‘ํ•œ CPU์‹œ๊ฐ„๋„ ์ ˆ์•ฝ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.์…ฐ์ด๋”๋Š” OpenGL ์…ฐ์ด๋”ฉ ์–ธ์–ด (GLSL)๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ๋‹ค์Œ ์žฅ์—์„œ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์—์„œ ๊ทธ๋ž˜ํ”ฝํŒŒ์ดํ”„๋ผ์ธ์˜ ๋ชจ๋“  ๋‹จ๊ณ„์— ๋Œ€ํ•œ ์ถ”์ƒ์ ์ธ ํ‘œํ˜„์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ๋ž€์ƒ‰ ์„น์…˜์€ ์ž์ฒด ์…ฐ์ด๋”๋ฅผ ์‚ฝ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ์„น์…˜์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

pipeline

๋ณด์‹œ๋‹ค์‹œํ”ผ ๊ทธ๋ž˜ํ”ฝ ํŒŒ์ดํ”„๋ผ์ธ์—๋Š” ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ์™„์ „ํ•œ ๋ Œ๋”๋ง ๋œ ํ”ฝ์…€๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํŠน์ • ๋ถ€๋ถ„์„ ๊ฐ๊ฐ ์ฒ˜๋ฆฌํ•˜๋Š” ๋งŽ์€ ์„น์…˜์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ดํ”„๋ผ์ธ์˜ ๊ฐ ๋ถ€๋ถ„์„ ๋‹จ์ˆœํ™” ๋œ ๋ฐฉ์‹์œผ๋กœ ๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…ํ•˜์—ฌ ํŒŒ์ดํ”„ ๋ผ์ธ ์ž‘๋™ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์ข‹์€ ์˜ˆ์‹œ๋ฅผ ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜ํ”ฝ ํŒŒ์ดํ”„๋ผ์ธ์— ๋Œ€ํ•œ ์ž…๋ ฅ์œผ๋กœ ์šฐ๋ฆฌ๋Š” ์—ฌ๊ธฐ์„œ Vertex Data ๋ผ๋Š” ๋ฐฐ์—ด์—์„œ ์‚ผ๊ฐํ˜•์„ ํ˜•์„ฑํ•ด์•ผ ํ•˜๋Š” 3๊ฐœ์˜ 3D์ขŒํ‘œ ๋ชฉ๋ก์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด Vertex Data๋Š” ๋ฒ„ํ…์Šค๋“ค์˜ ๋ชจ์Œ์ž…๋‹ˆ๋‹ค. ๋ฒ„ํ…์Šค๋Š” 3D ์ขŒํ‘œ ๋‹น ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์ž…๋‹ˆ๋‹ค. ์ด ๋ฒ„ํ…์Šค์˜ ๋ฐ์ดํ„ฐ๋Š” ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ„ํ…์Šค ์†์„ฑ(Vertex Attribute)์„ ์‚ฌ์šฉ ์‚ฌ์šฉํ•˜์—ฌ ํ‘œํ˜„๋˜์ง€๋งŒ, ๋‹จ์ˆœ์„ฑ์„ ์œ„ํ•ด ๊ฐ ๋ฒ„ํ…์Šค๋Š” 3D ์œ„์น˜์™€ ์ผ๋ถ€ ์ƒ‰์ƒ ๊ฐ’์œผ๋กœ๋งŒ ๊ตฌ์„ฑ๋˜์–ด์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

OpenGL์ด ์ขŒํ‘œ ๋ฐ ์ƒ‰์ƒ ๊ฐ’ ๋ชจ์Œ์„ ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์ง€ ์•Œ๊ธฐ ์œ„ํ•ด์„œ๋Š” OpenGL์€ ๋ฐ์ดํ„ฐ๋กœ ์–ด๋–ค ์ข…๋ฅ˜์˜ ๋ Œ๋” ์œ ํ˜•์„ ํ˜•์„ฑ ํ•  ๊ฒƒ์ธ์ง€ ํžŒํŠธ๋ฅผ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ์  ์ง‘ํ•ฉ, ์‚ผ๊ฐํ˜• ์ง‘ํ•ฉ ๋˜๋Š” ํ•˜๋‚˜์˜ ๊ธด ์„ ์œผ๋กœ ๋ Œ๋”๋ง ๋˜๊ธธ ์›ํ•˜์‹œ๋‚˜์š”? ์ด๋Ÿฌํ•œ ํžŒํŠธ๋ฅผ ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ๋ผ๊ณ  ํ•˜๋ฉฐ ๊ทธ๋ฆฌ๊ธฐ ๋ช…๋ น์„ ํ˜ธ์ถœํ•˜๋Š” ๋™์•ˆ OpenGL์— ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. ํžˆ๋Ÿฌํ•œ ํžŒํŠธ ์ค‘ ํ•˜๋‚˜๊ฐ€ GL_POINTS, GL_TRIANGLES ๋ฐ GL_LINE_STRIP์ž…๋‹ˆ๋‹ค.

ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ฒซ ๋ฒˆ์งธ ๋ถ€๋ถ„์€ ๋‹จ์ผ ๋ฒ„ํ…์Šค๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›๋Š” ๋ฒ„ํ…์Šค ์…ฐ์ด๋”์ž…๋‹ˆ๋‹ค. ๋ฒ„ํ…์Šค ์…ฐ์ด๋”์˜ ์ฃผ์š” ๋ชฉ์ ์€ 3D์ขŒํ‘œ๋ฅผ ๋‹ค๋ฅธ 3D์ขŒํ‘œ๋ฅผ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ(๋‚˜์ค‘์— ์ž์„ธํ•œ ์„ค๋ช…ํ•จ) ๋ฒ„ํ…์Šค ์…ฐ์ด๋”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฒ„ํ…์Šค ์†์„ฑ์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ๊ธฐ๋ณธ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ ์–ด์…ˆ๋ธ”๋ฆฌ ๋‹จ๊ณ„๋Š” ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ๋ฅผ ํ˜•์„ฑํ•˜๋Š” ๋ฒ„ํ…์Šค ์…ฐ์ด๋”์—์„œ ๋ชจ๋“  ๋ฒ„ํ…์Šค (๋˜๋Š” GL_POINTS๊ฐ€ ์„ ํƒ๋œ ๊ฒฝ์šฐ ๋ฒ„ํ…์Šค)์„ ์ž…๋ ฅ์œผ๋กœ ์ทจํ•˜๊ณ  ์ฃผ์–ด์ง„ ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ ๋ชจ์–‘์˜ ๋ชจ๋“  ์ ์„ ์กฐ๋ฆฝํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ์˜ˆ์ œ์—์„œ๋Š” ์‚ผ๊ฐํ˜•์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ง€์˜ค๋ฉ”ํŠธ๋ฆฌ ์…ฐ์ด๋”์˜ ์ถœ๋ ฅ์€ rasterization ๋‹จ๊ณ„๋กœ ์ „๋‹ฌ๋˜์–ด ๊ฒฐ๊ณผ ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ(๋“ค)๋ฅผ ์ตœ์ข… ํ™”๋ฉด์˜ ํ•ด๋‹น ํ”ฝ์…€์— ๋งคํ•‘ํ•˜์—ฌ ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”์— ๋งคํ•‘ํ•˜์—ฌ ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๊ฐ€ ์‚ฌ์šฉํ•  ํ”„๋ ˆ๊ทธ๋จผํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ํด๋ฆฌํ•‘์ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ํด๋ฆฌํ•‘์€ ๋ทฐ ์™ธ๋ถ€์— ์žˆ๋Š” ๋ชจ๋“  ์กฐ๊ฐ์„ ์‚ญ์ œํ•˜์—ฌ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

OpenGL์˜ ํ”„๋ ˆ๊ทธ๋จผํŠธ๋Š” OpenGL์ด ๋‹จ์ผ ํ”ฝ์…€์„ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.

ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”์˜ ์ฃผ์š” ๋ชฉ์ ์€ ํ”ฝ์…€์˜ ์ตœ์ข… ์ƒ‰์ƒ์„ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“  ๊ณ ๊ธ‰ OpenGL ํšจ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ํ”„๋ž˜๊ทธ๋จผํŠธ ์…ฐ์ด๋”์—๋Š” ์ตœ์ข… ํ”ฝ์…€ ์ƒ‰์ƒ (์˜ˆ: ์กฐ๋ช…, ๊ทธ๋ฆผ์ž, ์กฐ๋ช… ์ƒ‰์ƒ ๋“ฑ)์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” 3D ์žฅ๋ฉด์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ํ•ด๋‹น ์ƒ‰์ƒ ๊ฐ’์ด ๊ฒฐ์ •๋˜๋ฉด ์ตœ์ข… ๊ฐ์ฒด๋Š” ์•ŒํŒŒ ํ…Œ์ŠคํŠธ ๋ฐ ๋ธ”๋ Œ๋”ฉ ๋‹จ๊ณ„๋ผ๊ณ  ํ•˜๋Š” ํ•œ ๋‹จ๊ณ„๋ฅผ ๋” ํ†ต๊ณผํ•ฉ๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„๋Š” ํ”„๋ ˆ๊ทธ๋จผํŠธ์˜ ํ•ด๋‹น ๊นŠ์ด (๊ทธ๋ฆฌ๊ณ  ์Šคํ…์‹ค) ๊ฐ’ (๋‚˜์ค‘์— ์–ป์„ ๊ฒƒ์ž„) ์„ ํ™•์ธํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ ํ”„๋ ˆ๊ทธ๋จผํŠธ๊ฐ€ ๋‹ค๋ฅธ ๊ฐœ์ฒด์˜ ์•ž ๋˜๋Š” ๋’ค์— ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ๊ทธ์— ๋”ฐ๋ผ ํ๊ธฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์Šคํ…Œ์ด์ง€๋Š” ๋˜ํ•œ ์•ŒํŒŒ ๊ฐ’( ์•ŒํŒŒ๊ฐ’์€ ๊ฐœ์ฒด์˜ ๋ถˆํˆฌ๋ช…๋„๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.)์„ ํ™•์ธํ•˜๊ณ  ๊ทธ์— ๋”ฐ๋ผ ๊ฐœ์ฒด๋ฅผ ๋ธ”๋ Œ๋”ฉ(ํ˜ผํ•ฉ)ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ”ฝ์…€ ์ถœ๋ ฅ ์ƒ‰์ƒ์ด ํ”„๋ž˜๊ทธ๋จผํŠธ ์…ฐ์ด๋”์—์„œ ๊ณ„์‚ฐ ๋˜๋”๋ผ๋„ ์—ฌ๋Ÿฌ ์‚ผ๊ฐํ˜•์„ ๋ Œ๋”๋ง ํ•  ๋•Œ ์ตœ์ข… ํ”ฝ์ƒ ์„น์ƒ์€ ์™„์ „ํžˆ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ณด์‹œ๋‹ค์‹œํ”ผ ๊ทธ๋ž˜ํ”ฝํŒŒ์ดํ”„๋ผ์ธ์€ ์ „์ฒด๊ฐ€ ๋งค์šฐ ๋ณต์žกํ•˜๊ณ  ๊ตฌ์„ฑ ๊ฐ€๋Šฅํ•œ ๋ถ€๋ถ„์ด ๋งŽ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ๋ฒ„ํ…์Šค ๋ฐ ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๋กœ๋งŒ ์ž‘์—…ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ง€์˜ค๋ฉ”ํŠธ๋ฆฌ ์…ฐ์ด๋”๋Š” ์„ ํƒ ์‚ฌํ•ญ์ด๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ๋ณธ ์…ฐ์ด๋”๋กœ ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ์„ค๋ช…ํ•˜์ง€ ์•Š์€ ํ…Œ์…€๋ ˆ์ด์…˜ ๋‹จ๊ณ„์™€ ๋ณ€ํ™˜ ํ”ผ๋“œ๋ฐฑ ๋ฃจํ”„๋„ ์žˆ์ง€๋งŒ ์ด๊ฑด ๋‚˜์ค‘์— ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ตœ์‹  OpenGL์—์„œ๋Š” ์ตœ์†Œํ•œ ์šฐ๋ฆฌ ์ž์‹ ์˜ ๋ฒ„ํ…์Šค ๋ฐ ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๋ฅผ ๋ฐ˜๋“œ์‹œ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. (GPU์—๋Š” ๊ธฐ๋ณธ ๋ฒ„ํ…์Šค / ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.) ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ ์ฒซ ๋ฒˆ์งธ ์‚ผ๊ฐํ˜•์„ ๋ Œ๋”๋งํ•˜๊ธฐ ์ „์— ๋งŽ์€ ์ง€์‹์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์‹  OpenGL ํ•™์Šต์„ ์‹œ์ž‘ํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ์ด ์žฅ์˜ ๋์—์„œ ๋งˆ์นจ๋‚ด ์‚ผ๊ฐํ˜•์„ ๋ Œ๋”๋งํ•˜๋ฉด ๊ทธ๋ž˜ํ”ฝ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋Œ€ํ•ด ๋” ๋งŽ์ด ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฒ„ํ…์Šค ์ž…๋ ฅ

๋ฌด์–ธ๊ฐ€๋ฅผ ๊ทธ๋ฆฌ๊ธฐ๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด์„  ๋จผ์ € OpenGL์—๊ฒŒ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. OpenGL์€ ๊ทธ๋ž˜ํ”ฝ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋ฏ€๋กœ OpenGL์—์„œ ์ง€์ •ํ•˜๋Š” ๋ชจ๋“  ์ขŒํ‘œ๋Š” 3D์ž…๋‹ˆ๋‹ค. (x, y ๊ทธ๋ฆฌ๊ณ  z ์ขŒํ‘œ๊ณ„) OpenGL์€ ๋ชจ๋“  3D ์ขŒํ‘œ๊ณ„๋ฅผ ๋„ˆ์˜ ์Šคํฌ๋ฆฐ์— ๋งž๋Š” 2D ํ”ฝ์…€๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ณ€ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. OpenGL์€ ์˜ค์ง 3์ถ•์„(x , y ๊ทธ๋ฆฌ๊ณ  z ) -1.0 ์—์„œ 1.0 ์‚ฌ์ด์˜ ๋ฒ”์œ„์—๋งŒ ์žˆ์„๋•Œ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ขŒํ‘œ๊ณ„๋Š” ์ •๊ทœํ™”๋œ ๊ธฐ๊ธฐ ์ขŒํ‘œ ๋ฒ”์œ„์—๋งŒ ๋„ˆ์˜ ํ™”๋ฉด์— ๋ณด์ž…๋‹ˆ๋‹ค. (๊ทธ ๋ฐ–์— ์žˆ๋Š” ๋ถ€๋ถ„์€ ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.) ํ•˜๋‚˜์˜ ์‚ผ๊ฐํ˜•์„ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด 3D ์ขŒํ‘œ๋ฅผ ๊ฐ€์ง€๊ณ ์žˆ๋Š” ๊ฐ๊ฐ์˜ ๋ฒ„ํ…์Šค๋“ค์„ ๋ณ€ํ™˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ •๊ทœํ™”๋œ ์žฅ์น˜ ์ขŒํ‘œ๋ฅผ float ๋ฐฐ์—ด๋กœ ์ •์˜ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

float vertices[] = {
    -0.5f, -0.5f, 0.0f,
     0.5f, -0.5f, 0.0f,
     0.0f,  0.5f, 0.0f
};  

OpenGL์€ 3D ๊ณต๊ฐ„์—์„œ ์ž‘๋™ํ•˜๋ฏ€๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋ Œ๋”๋งํ•˜๋Š” 2D ์‚ผ๊ฐํ˜•์€ ๊ฐ๊ฐ ๋ฒ„ํ…์Šค๋“ค์˜ z ์ขŒํ‘œ๋Š” 0.0 ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‚ผ๊ฐํ˜•์˜ ๊นŠ์ด๊ฐ€ ๊ฐ™์•„์ง€๋ฏ€๋กœ 2D๊ฐ™์ด ๋ณด์ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ •๊ทœํ™”๋œ ๊ธฐ๊ธฐ ์ขŒํ‘œ (Normalized Device Coordinates NDC)

๋ฒ„ํ…์Šค ์ขŒํ‘œ๋“ค์ด ๋ฒ„ํ…์Šค ์‰์ด๋”๋ฅผ ํ†ต๊ณผํ•˜๊ฒŒ ๋˜๋ฉด, ๊ทธ๊ฒƒ๋“ค์€ -1.0 ์—์„œ 1.0 ๋ฒ”์œ„์˜ x , y, z ์˜ ์ž‘์€ ๊ณต๊ฐ„์˜ ์ •๊ทœํ™”๋œ ๊ธฐ๊ธฐ ์ขŒํ‘œ๊ฐ€ ๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์–ด๋– ํ•œ ์ขŒํ‘œ๋“ค์ด ์ด ๋ฒ”์œ„๊ฐ€ ๋ฒ—์–ด๋‚œ๋‹ค๋ฉด ๋ฒ„๋ ค์ง€๊ฑฐ๋‚˜/clipped ๋˜์–ด ๋„ˆ์˜ ์Šคํฌ๋ฆฐ์— ๋ณด์—ฌ์ง€์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋ฅผ ๋ณด๋ฉด ์‚ผ๊ฐํ˜•์ด ์ •๊ทœํ™”๋œ ๊ธฐ๊ธฐ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (z ์ถ•์€ ๋ฌด์‹œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.)

ndc

์ผ๋ฐ˜์ ์ธ ํ™”๋ฉด ์ขŒํ‘œ์™€ ๋‹ฌ๋ฆฌ, ํ™”๋ฉด์€ ์œ„์ชฝ ๋ฐฉํ–ฅ์˜ y์ถ• ์ ๋“ค์„ ๊ณ ์ •ํ•˜๊ณ  ๊ทธ๋ž˜ํ”„ ์ค‘์•™์—๋Š” ์™ผ์ชฝ ์ƒ๋‹จ ๋Œ€์‹  (0,0) ์ขŒํ‘œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ตญ ๋ณ€ํ™˜๋œ ๋ชจ๋“  ์ขŒํ‘œ๊ฐ€ ์ด ์ขŒํ‘œ ๊ณต๊ฐ„์— ํ‘œ์‹œ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ•ด๋‹น ์ขŒํ‘œ๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

NDC ์ขŒํ‘œ๋Š” glViewport์—์„œ ์ œ๊ณตํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ทฐํฌํŠธ ๋ณ€ํ™˜์„ ํ†ตํ•ด ํ™”๋ฉด ๊ณต๊ฐ„ ์ขŒํ‘œ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ ํ™”๋ฉด ๊ณต๊ฐ„ ์ขŒํ‘œ๋Š” ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”์— ๋Œ€ํ•œ ์ž…๋ ฅ์œผ๋กœ ํ”„๋ ˆ๊ทธ๋จผํŠธ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.

์ •์˜ ๋œ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ž˜ํ”ฝ ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ฒซ ๋ฒˆ์งธ ํ”„๋กœ์„ธ์Šค์ธ ๋ฒ„ํ…์Šค์…ฐ์ด๋”์— ์ž…๋ ฅ์œผ๋กœ ๋ณด๋‚ด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” GPU์— ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ  OpenGL์ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ตฌ์„ฑํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ž˜ํ”ฝ์นด๋“œ๋กœ ๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์ง€์ •ํ•˜์—ฌ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ฒ„ํ…์Šค ์…ฐ์ด๋”๋Š” ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ง€์ •ํ•œ๋งŒํผ์˜ ๋ฒ„ํ…์Šค๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” GPU์˜ ๋ฉ”๋ชจ๋ฆฌ์— ๋งŽ์€ ์ˆ˜์˜ ๋ฒ„ํ…์Šค๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ์†Œ์œ„ ๋ฒ„ํ…์Šค ๋ฒ„ํผ ๊ฐœ์ฒด(VBO)๋ฅผ ํ†ตํ•ด ์ด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฒ„ํผ ๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์ ์€ ํ•œ๋ฒˆ์— ํ•œ ๋ฒ„ํ…์Šค์”ฉ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ผ ํ•„์š” ์—†์ด ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ๋ฒˆ์— ๊ทธ๋ž˜ํ”ฝ์นด๋“œ๋กœ ๋ณด๋‚ด๊ณ  ์ถฉ๋ถ„ํ•œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋‚จ์•„์žˆ๋Š” ๊ฒฝ์šฐ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. CPU์—์„œ ๊ทธ๋ž˜ํ”ฝ์นด๋“œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ์€ ์ƒ๋Œ€์ ์œผ๋กœ ๋Š๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•œ ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ๋ฒˆ์— ๋ณด๋‚ด๋Š”๊ฒŒ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ ๊ทธ๋ž˜ํ”ฝ์นด๋“œ์˜ ๋ฉ”๋ชจ๋ฆฌ์— ์žˆ์œผ๋ฉด ๋ฒ„ํ…์Šค์…ฐ์ด๋”๋Š” ๋ฒ„ํ…์Šค์— ๊ฑฐ์˜ ์ฆ‰๊ฐ์ ์œผ๋กœ ์•ก์„ธ์Šคํ•˜์—ฌ ๋งค์šฐ ๋น ๋ฆ…๋‹ˆ๋‹ค.

๋ฒ„ํ…์Šค ๋ฒ„ํผ ๊ฐœ์ฒด๋Š” OpenGL ์žฅ์—์„œ ๋งํ•œ ๊ฒƒ์ฒ˜๋Ÿผ OpenGL ๊ฐœ์ฒด์˜ ์ฒซ๋ฒˆ์งธ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค. OpenGL์˜ ๋ชจ๋“  ๊ฐœ์ฒด์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด ๋ฒ„ํผ์—๋Š” ํ•ด๋‹น ๋ฒ„ํผ์— ํ•ด๋‹นํ•˜๋Š” ๊ณ ์œ ํ•œ ID๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ glGenBuffers ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„ํผ ID๋กœ ํ•˜๋‚˜ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

unsigned int VBO;
glGenBuffers(1, &VBO);  //๋ฒ„ํผ์˜ ๊ฐฏ์ˆ˜

OpenGL์—๋Š” ๋งŽ์€ ์œ ํ˜•์˜ ๋ฒ„ํผ ๊ฐœ์ฒด๊ฐ€ ์žˆ์œผ๋ฉฐ ๋ฒ„ํ…์Šค ๋ฒ„ํผ ๊ฐœ์ฒด์˜ ๋ฒ„ํผ ์œ ํ˜•์€ GL_ARRAY_BUFFER ์ž…๋‹ˆ๋‹ค. OpenGL์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฒ„ํผ ์œ ํ˜•์ด ๋‹ค๋ฅธํ•œ ํ•œ๋ฒˆ์— ์—ฌ๋Ÿฌ ๋ฒ„ํผ์— ๋ฐ”์ธ๋”ฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. glBlindBuffer ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ ์ƒ์„œ๋œ ๋ฒ„ํผ๋ฅผ GL_ARRAY_BUFFER ํƒ€๊ฒŸ์— ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

glBindBuffer(GL_ARRAY_BUFFER, VBO);  

๊ทธ ์‹œ์ ๋ถ€ํ„ฐ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“œ๋Š” ๋ชจ๋“  ๋ฒ„ํผ ํ˜ธ์ถœ(GL_ARRAY_BUFFER ํƒ€๊ฒŸ์—์„œ)์€ ํ˜„์žฌ ๋ฐ”์ธ๋”ฉ๋œ ๋ฒ„ํผ์ธ VBO๋ฅผ ๊ตฌ์„ฑํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด์ „์— ์ •์˜๋œ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ๋ฒ„ํผ์˜ ๋ฉ”๋ชจ๋ฆฌ์— ๋ณต์‚ฌํ•˜๋Š” glBufferData ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBufferData๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ˜„์žฌ ๋ฐ”์ธ๋”ฉ๋œ ๋ฒ„ํผ๋กœ ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ์„ ์œ„ํ•ด ํŠน๋ณ„ํžˆ ๊ณ ์•ˆ๋œ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์‚ฌํ•˜๋ ค๋Š” ๋ฒ„ํผ์˜ ์œ ํ˜•์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ GL_ARRAY_BUFFER ํƒ€๊ฒŸ์— ๋ฐ”์ธ๋”ฉ ๋œ ๋ฒ„ํ…์Šค ๋ฒ„ํผ ๊ฐœ์ฒด์ž…๋‹ˆ๋‹ค.(VBO) ๋‘๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ๋ฒ„ํผ์— ์ „๋‹ฌํ•  ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ(๋ฐ”์ดํŠธ) ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๋Š” ๋‹จ์ˆœํ•œ sizeof ๋ฉด ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์„ธ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๋ณด๋‚ด๋ ค๋Š” ์‹ค์ œ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค.

๋„ค๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ทธ๋ž˜ํ”ฝ์นด๋“œ๊ฐ€ ์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” 3๊ฐ€์ง€ ํ˜•ํƒœ๋ฅผ ์ทจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • GL_STREAM_DRAW : ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œ๋ฒˆ๋งŒ ์„ค์ •๋˜๊ณ  GPU์—์„œ ์ ๊ฒŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • GL_STATIC_DRAW : ๋ฐ์ดํ„ฐ๊ฐ€ ํ•œ๋ฒˆ๋งŒ ์„ค์ •๋˜๊ณ  ๋งŽ์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • GL_DYNAMIC_DRAW : ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์ด ๋ณ€๊ฒฝ๋˜๊ณ  ๋งŽ์ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์‚ผ๊ฐํ˜•์˜ ์œ„์น˜ ๋ฐ์ดํ„ฐ๋Š” ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๊ณ  ๋งŽ์ด ์‚ฌ์šฉ๋˜๋ฉฐ ๋ชจ๋“  ๋ Œ๋” ํ˜ธ์ถœ์—์„œ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜๋ฏ€๋กœ ์‚ฌ์šฉ ์œ ํ˜•์€ GL_STATIC_DRAW ๊ฐ€ ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ž์ฃผ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์ด์“ดใ„ด ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ๋ฒ„ํผ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ GL_DYNAMIC_DRAW ์œ ํ˜•์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ทธ๋ž˜ํ”ฝ ์นด๋“œ๊ฐ€ ๋” ๋น ๋ฅธ ์“ฐ๊ธฐ๋ฅผ ํ—ˆ์šฉํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์šฐ๋ฆฌ๋Š” VBO๋ผ๋Š” ๋ฒ„ํ…์Šค ๋ฒ„ํผ ๊ฐœ์ฒด์—์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๊ทธ๋ž˜ํ”ฝ์นด๋“œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋‚ด์— ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ์‹ค์ œ๋กœ ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฒ„ํ…์Šค ๋ฐ ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๋ฅผ ๋งŒ๋“ค๊ณ ์ž ํ•˜๋ฏ€๋กœ ๋นŒ๋“œ๋ฅผ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฒ„ํ…์Šค ์…ฐ์ด๋”

๋ฒ„ํ…์Šค ์…ฐ์ด๋”๋Š” ์šฐ๋ฆฌ์™€ ๊ฐ™์€ ์‚ฌ๋žŒ๋“ค์ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ•  ์ˆ˜ ์žˆ๋Š” ์…ฐ์ด๋” ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ตœ์‹  OpenGL์—์„œ๋Š” ๋ Œ๋”๋ง์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ์ตœ์†Œํ•œ ๋ฒ„ํ…์Šค ๋ฐ ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๋ฅผ ์„ค์ •ํ•ด์•ผํ•˜๋ฏ€๋กœ ์…ฐ์ด๋”๋ฅผ ๊ฐ„๋žตํ•˜๊ฒŒ ์†Œ๊ฐœํ•˜๊ณ  ์ฒซ ๋ฒˆ์งธ ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ฆฌ๊ธฐ ์œ„ํ•ด ๋‘ ๊ฐœ์˜ ๋งค์šฐ ๊ฐ„๋‹จํ•œ ์…ฐ์ด๋”๋ฅผ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์žฅ์—์„œ๋Š” ์…ฐ์ด๋”์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€์žฅ ๋จผ์ € ํ•ด์•ผ ํ•  ์ผ์€ ์…ฐ์ด๋” ์–ธ์–ด GLSL(OpenGL Shading Language)๋กœ ๋ฒ„ํ…์Šค ์…ฐ์ด๋”๋ฅผ ์ž‘์„ฑํ•œ ๋‹ค์Œ ์…ฐ์ด๋”๋ฅผ ์ปดํŒŒ์ผํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š”๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„๋ž˜์—์„œ GLSL์˜ ๋งค์šฐ ๊ธฐ๋ณธ์ ์ธ ๋ฒ„ํ…์Šค ์…ฐ์ด๋”์˜ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


#version 330 core
layout (location = 0) in vec3 aPos;

void main()
{
    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}

๋ณด์‹œ๋‹ค์‹œํ”ผ GLSL์€ C์™€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์…ฐ์ด๋”๋Š” ๋ฒ„์ „ ์„ ์–ธ์œผ๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. OpenGL 3.3 ์ด์ƒ๋ถ€ํ„ฐ GLSL ๋ฒ„์ „ ๋ฒˆํ˜ธ๋Š” OpenGL ๋ฒ„์ „๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค. (์˜ˆ : GLSL ๋ฒ„์ „ 420์€ OpenGL 4.2์— ํ•ด๋‹น). ๋˜ํ•œ core profile ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ์„ ๋ช…์‹œ์ ์œผ๋กœ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ in ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„ํ…์Šค ์…ฐ์ด๋”์˜ ๋ชจ๋“  ์ž…๋ ฅ ๋ฒ„ํ…์Šค ์†์„ฑ์„ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ์œ„์น˜ ๋ฐ์ดํ„ฐ์—๋งŒ ๊ด€์‹ฌ์ด ์žˆ์œผ๋ฏ€๋กœ ํ•˜๋‚˜์˜ ๋ฒ„ํ…์Šค ์†์„ฑ๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. GLSL์—๋Š” ์ ‘๋ฏธ์‚ฌ ์ˆซ์ž๋ฅผ ๊ธฐ์ค€์œผ๋กœ 1~4๊ฐœ์˜ ๋ถ€๋™ ์†Œ์ˆ˜์ ์„ ํฌํ•จํ•˜๋Š” ๋ฒกํ„ฐ ๋ฐ์ดํ„ฐ ์œ ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ๋ฒ„ํ…์Šค์—๋Š” 3D ์ขŒํ‘œ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ aPos ๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ vec3 ์ž…๋ ฅ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋˜ํ•œ layout (location = 0) ์„ ํ†ตํ•ด ์ž…๋ ฅ ๋ณ€์ˆ˜์˜ ์œ„์น˜๋ฅผ ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค์ •ํ–ˆ์œผ๋ฉฐ ๋‚˜์ค‘์— ํ•ด๋‹น ์œ„์น˜๊ฐ€ ํ•„์š”ํ•œ ์ด์œ ๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Vector

๊ทธ๋ž˜ํ”ฝ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์šฐ๋ฆฌ๋Š” ๋ฒกํ„ฐ์˜ ์ˆ˜ํ•™์  ๊ฐœ๋…์„ ์ž์ฃผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฒกํ„ฐ๋Š” ๋ชจ๋“  ๊ณต๊ฐ„์—์„œ ์œ„์น˜/๋ฐฉํ–ฅ์„ ๊น”๋”ํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๊ณ  ์œ ์šฉํ•œ ์ˆ˜ํ•™์  ์†์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. GLSL์˜ ๋ฒกํ„ฐ๋Š” ์ตœ๋Œ€ ํฌ๊ธฐ๊ฐ€ 4์ด๊ณ  ๊ฐ ๊ฐ’์€ ๊ฐ๊ฐ vec.x , vec.y , vec.z ๋ฐ vec.w ๋ฅผ ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ๊ฐ์— ๋Œ€ํ•œ ๊ฐ’์€ ๊ณต๊ฐ„์—์„œ์˜ ์ขŒํ‘œ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. vec.w ๋Š” ๊ณต๊ฐ„์˜ ์œ„์น˜๋กœ ์‚ฌ์šฉ๋˜์ง€ ์•Š์ง€๋งŒ (์šฐ๋ฆฌ๋Š” 4D๊ฐ€ ์•„๋‹Œ 3D๋ฅผ ๋‹ค๋ฅด๊ณ  ์žˆ์Œ) ์›๊ทผ ๋ถ„ํ• ์ด๋ผ๋Š” ๊ฒƒ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ดํ›„ ์žฅ์—์„œ ๋ฒกํ„ฐ์— ๋Œ€ํ•ด ํ›จ์”ฌ ๋” ๊นŠ๊ฒŒ ๋‹ค๋ค„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฒ„ํ…์Šค ์…ฐ์ด๋”์˜ ์ถœ๋ ฅ์„ ์„ค์ •ํ•˜๋ ค๋ฉด ์”ฌ ๋’ค์—์„œ ์‚ฌ์ „ ์ •์˜๋œ vec4 gl_Position ๋ณ€์ˆ˜์— ์œ„์น˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ• ๋‹นํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์ธ ํ•จ์ˆ˜์˜ ๋์—์„œ, ์šฐ๋ฆฌ๊ฐ€ ์„ค์ •ํ•œ gl_position์€ ๋ฒ„ํ…์Šค ์…ฐ์ด๋”์˜ ์ถœ๋ ฅ์œผ๋กœ ์‚ฌ์šฉ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž…๋ ฅ์€ ํฌ๊ธฐ 3์˜ ๋ฒกํ„ฐ์ด๋ฏ€๋กœ ์ด๋ฅผ ํฌ๊ธฐ 4์˜ ๋ฒกํ„ฐ๋กœ ์ผ€์ŠคํŒ… ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. vec4 ์˜ ์ƒ์„ฑ์ž ์•ˆ์— vec3 ๊ฐ’์„ ์‚ฝ์ž…ํ•˜๊ณ  w ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ 1.0f ๋กœ ์„ค์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. (์ด๋ ‡๊ฒŒ ํ•˜๋Š” ์ด์œ ๋Š” ์ดํ›„ ์žฅ์—์„œ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.)

์…ฐ์ด๋” ์ปดํŒŒ์ผ

๋ฒ„ํ…์Šค ์…ฐ์ด๋”์˜ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ ์™€์„œ ์ง€๊ธˆ ์ฝ”๋“œ ํŒŒ์ผ ๋งจ ์œ„์— const char ๋ฌธ์ž์—ด์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

const char *vertexShaderSource = "#version 330 core\n"
    "layout (location = 0) in vec3 aPos;\n"
    "void main()\n"
    "{\n"
    "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
    "}\0";

OpenGL์ด ์…ฐ์ด๋”๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋Ÿฐํƒ€์ž„์— ์†Œ์Šค์ฝ”๋“œ์—์„œ ๋™์ ์œผ๋กœ ์ปดํŒŒ์ผ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๋จผ์ € ํ•ด์•ผ ํ•  ์ผ์€ ์…ฐ์ด๋” ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ID๋กœ ์ฐธ์กฐ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฒ„ํ…์Šค ์…ฐ์ด๋”๋ฅผ unsigned int ๋กœ ์ง€์ •ํ•˜๊ณ  glCreateShader๋กœ ์…ฐ์ด๋”๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);

glCreateShader์— ๋Œ€ํ•œ ์ธ์ˆ˜๋กœ ์ƒ์„ฑํ•˜๋ ค๋Š” ์…ฐ์ด๋” ์œ ํ˜•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํ…์Šค ์…ฐ์ด๋”๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ GL_VERTEX_SHADER ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ์…ฐ์ด๋” ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์…ฐ์ด๋” ๊ฐœ์ฒด์— ์—ฐ๊ฒฐํ•˜๊ณ  ์…ฐ์ด๋”๋ฅผ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค.

glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);

glShaderSource ํ•จ์ˆ˜๋Š” ์ปดํŒŒ์ผ ์…ฐ์ด๋” ๊ฐœ์ฒด๋ฅผ ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‘๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ์†Œ์Šค ์ฝ”๋“œ๋กœ ์ „๋‹ฌํ•  ๋ฌธ์ž์—ด ์ˆ˜๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์„ธ๋ฒˆ์งธ ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” ๋ฒ„ํ…์Šค ์…ฐ์ด๋”์˜ ์‹ค์ œ ์†Œ์Šค ์ฝ”๋“œ์ด๋ฉฐ ๋„ค๋ฒˆ์งธ ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” NULL๋กœ ๋‚จ๊ฒจ ๋‘˜ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

glCompileShader๋ฅผ ํ˜ธ์ถœ ํ•œ ํ›„ ์ปดํŒŒ์ผ์ด ์„ฑ๊ณตํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ์–ด๋–ค ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ๊ฒฌ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ ํƒ€์ž„ ์˜ค๋ฅ˜ ํ™•์ธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.

int  success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);

๋จผ์ € ์„ฑ๊ณต์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ •์ˆ˜์™€ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€(์žˆ๋Š” ๊ฒฝ์šฐ)์— ๋Œ€ํ•œ ์ €์žฅ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ glGetShaderiv๋กœ ์ปดํŒŒ์ผ์ด ์„ฑ๊ณตํ–ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ์ด ์‹คํŒจํ•˜๋ฉด glGetShaderInfoLog๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

if(!success)
{
    glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
    std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}

์•„๋ฌด๋Ÿฐ ์• ๋Ÿฌ๋ฅผ ๊ฐ์ง€ํ•˜์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด ๋ฒ„ํ…์Šค ์…ฐ์ด๋”๊ฐ€ ์ปดํŒŒ์ผ ๋˜์—ˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ์ž…๋‹ˆ๋‹ค.

ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”

ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๋Š” ์‚ผ๊ฐํ˜•์„ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์ง„ ๋‘๋ฒˆ์งธ์ด์ž ๋งˆ์ง€๋ง‰ ์…ฐ์ด๋”์ž…๋‹ˆ๋‹ค. ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๋Š” ํ”ฝ์…€์˜ ์ƒ‰์ƒ ์ถœ๋ ฅ์„ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹จ์ˆœํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๋Š” ํ•ญ์ƒ ์ฃผํ™ฉ์ƒ‰์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

์ปดํ“จํ„ฐ ๊ทธ๋ž˜ํ”ฝ์˜ ์ƒ‰์ƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ RGBA๋กœ ์ถ•์•ฝ๋˜๋Š” ๋นจ๊ฐ•, ๋…น์ƒ‰, ํŒŒ๋ž‘ ๋ฐ ์•ŒํŒŒ(ํˆฌ๋ช…๋„) ๊ตฌ์„ฑ ์š”์†Œ์˜ 4๊ฐœ์˜ ๊ฐ’ ๋ฐฐ์—ด๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. OpenGL ๋˜๋Š” GLSL์—์„œ ์ƒ‰์ƒ์„ ์ •์˜ํ•  ๋•Œ ๊ฐ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ฐ•๋„๋ฅผ 0.0 ์—์„œ 1.0 ์‚ฌ์ด์˜ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋นจ๊ฐ„์ƒ‰์€ 1.0 ์œผ๋กœ, ๋…น์ƒ‰์„ 1.0 ์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ๋‘ ์ƒ‰์ƒ์ด ํ˜ผํ•ฉ๋˜์–ด ๋…ธ๋ž€์ƒ‰์ด ๋ฉ๋‹ˆ๋‹ค. ์ด 3๊ฐ€์ง€ ์ƒ‰์ƒ ๊ตฌ์†Œ ์š”์†Œ๋ฅผ ๊ณ ๋ คํ•˜๋ฉด 1600๋งŒ ๊ฐ€์ง€๊ฐ€ ๋„˜๋Š” ์ƒ‰์ƒ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

#version 330 core
out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
} 

ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”์—๋Š” ํ•˜๋‚˜์˜ ์ถœ๋ ฅ ๋ณ€์ˆ˜๋งŒ ํ•„์š”ํ•˜๋ฉฐ ์ด๋Š” ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ๊ณ„์‹ผํ•ด์•ผํ•˜๋Š” ์ตœ์ข… ์ƒ‰์ƒ ์ถœ๋ ฅ์„ ์ •์˜ํ•˜๋Š” ํฌ๊ธฐ 4์˜ ๋ฒกํ„ฐ์ž…๋‹ˆ๋‹ค. out ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ถœ๋ ฅ ๊ฐ’์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์—ฌ๊ธฐ์—์„œ ์ฆ‰์‹œ FragColor ๋ผ๋Š” ์ด๋ฆ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ์•ŒํŒŒ ๊ฐ’์ด 1.0 (1.0 ์€ ์™„์ „ํžˆ ๋ถˆํˆฌ๋ช…ํ•จ)์˜ ์ฃผํ™ฉ์ƒ‰์œผ๋กœ vec4๋ฅผ ์ƒ‰์ƒ ์ถœ๋ ฅ์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋ž˜๊ทธ๋จผํŠธ ์…ฐ์ด๋”๋ฅผ ์ปดํŒŒ์ผํ•˜๋Š” ๊ณผ์ •์€ ๋ฒ„ํ…์Šค ์…ฐ์ด๋”์™€ ๋น„์Šทํ•˜์ง€๋งŒ ์ด๋ฒˆ์—๋Š” ์…ฐ์ด๋” ์œ ํ˜•์œผ๋กœ GL_FRAGMENT_SHADER ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);

์ด์ œ ๋‘ ์…ฐ์ด๋”๊ฐ€ ๋ชจ๋‘ ์ปดํŒŒ์ผ๋˜๊ณ  ๋‚จ์€ ๊ฒƒ์€ ๋ Œ๋”๋ง์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์…ฐ์ด๋” ํ”„๋กœ๊ทธ๋žจ์— ๋‘ ์…ฐ์ด๋” ๊ฐœ์ฒด๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ ๋ฟ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋„ ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋ฅผ ํ™•์ธํ•˜์„ธ์š”!

์…ฐ์ด๋” ํ”„๋กœ๊ทธ๋žจ

์…ฐ์ด๋” ํ”„๋กœ๊ทธ๋žจ ๊ฐœ์ฒด๋Š” ๊ฒฐํ•ฉ ๋œ ์—ฌ๋Ÿฌ ์…ฐ์ด๋”์˜ ์ตœ์ข… ๋งํฌ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. ๋ง‰ ์ปดํŒŒ์ผ ๋œ ์…ฐ์ด๋”๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์…ฐ์ด๋” ํ”„๋กœ๊ทธ๋žจ ๊ฐœ์ฒด์— ๋งํฌํ•œ ๋‹ค์Œ ๊ฐœ์ฒด๋ฅผ ๋ Œ๋”๋ง ํ• ๋•Œ ์ด ์…ฐ์ด๋” ํ”„๋กœ๊ทธ๋žจ์„ ํ™œ์„ฑํ™” ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ™œ์„ฑํ™”๋œ ์…ฐ์ด๋” ํ”„๋กœ๊ทธ๋žจ์˜ ์…ฐ์ด๋”๋Š” ๋ Œ๋”๋ง ํ˜ธ์ถœ์„ ์‹คํ–‰ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์…ฐ์ด๋”๋ฅผ ํ”„๋กœ๊ทธ๋žจ์— ์—ฐ๊ฒฐํ•  ๋•Œ ๊ฐ ์…ฐ์ด๋”์˜ ์ถœ๋ ฅ์„ ๋‹ค์Œ ์…ฐ์ด๋”์˜ ์ž…๋ ฅ์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ถœ๋ ฅ๊ณผ ์ž…๋ ฅ๊ธฐ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด ๋งํฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ๊ทธ๋žจ ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์‰ฝ์Šต๋‹ˆ๋‹ค.

unsigned int shaderProgram;
shaderProgram = glCreateProgram();

glCreateProgram ํ•จ์ˆ˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ƒ์„ฑํ•˜๊ณ  ์ƒˆ๋กœ ์ƒ์„ฑ ๋œ ํ”„๋กœ๊ทธ๋žจ ๊ฐœ์ฒด์— ๋Œ€ํ•œ ID ์ฐธ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ์ด์ „์— ์ปดํŒŒ์ผ ๋œ ์…ฐ์ด๋”๋ฅผ ํ”„๋กœ๊ทธ๋žจ ๊ฐœ์ฒด์— ์—ฐ๊ฒฐ ํ•œ ๋‹ค์Œ glLinkProgram๊ณผ ์—ฐ๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);

์ฝ”๋“œ๋Š” ๋งค์šฐ ์ž๋ช…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์…ฐ์ด๋”๋ฅผ ํ”„๋กœ๊ทธ๋žจ์— ์—ฐ๊ฒฐํ•˜๊ณ  glLinkProgram์„ ํ†ตํ•ด ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

์…ฐ์ด๋” ์ปดํŒŒ์ผ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์…ฐ์ด๋” ํ”„๋กœ๊ทธ๋žจ ์—ฐ๊ฒฐ์ด ์‹คํŒจํ•ด์“ด์ง€ ํ™•์ธํ•˜๊ณ  ํ•ด๋‹น ๋กœ๊ทธ๋ฅผ ๊ฒ€์ƒ‰ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด์ œ glGetshaderiv ๋ฐ glGetShaderInfoLog๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if(!success) {
    glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
    ...
}

๊ฒฐ๊ณผ๋Š” ์ƒˆ๋กœ ์ƒ์„ฑ ๋œ ํ”„๋กœ๊ทธ๋žจ ๊ฐœ์ฒด๋ฅผ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ glUseProgram์„ ํ˜ธ์ถœํ•˜์—ฌ ํ™œ์„ฑํ™” ํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ๊ทธ๋žจ ๊ฐœ์ฒด์ž…๋‹ˆ๋‹ค.

glUseProgram(shaderProgram);

glUseProgram ์ดํ›„์˜ ๋ชจ๋“  ์…ฐ์ด๋” ๋ฐ ๋ Œ๋”๋ง ํ˜ธ์ถœ์€ ์ด์ œ ์ด ํ”„๋กœ๊ทธ๋žจ ๊ฐœ์ฒด (๋ฐ ์…ฐ์ด๋”)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์•„ ๋งž๋‹ค. ์ผ๋‹จ ์ด ์…ฐ์ด๋” ๊ฐœ์ฒด๋ฅผ ํ”„๋กœ๊ทธ๋žจ ๊ฐœ์ฒด์— ์—ฐ๊ฒฐํ–ˆ๋‹ค๋ฉด ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์„ธ์š”! ๋” ์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

์ง€๊ธˆ ์šฐ๋ฆฌ๋Š” ์ž…๋ ฅ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ GPU์— ๋ณด๋‚ด๊ณ  GPU์— ๋ฒ„ํ…์Šค ๋ฐ ํ”„๋ž˜๊ทธ๋จผํŠธ ์…ฐ์ด๋” ๋‚ด์—์„œ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง€์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฑฐ์˜ ๋‹ค ์™”์ง€๋งŒ ์•„์ง ๋‚จ์•˜์Šต๋‹ˆ๋‹ค. OpenGL์€ ์•„์ง ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ํ•ด์„ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ๋ฒ„ํ…์Šค ์…ฐ์ด๋” ์†์„ฑ์— ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•„์ง ๋ชจ๋ฆ…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์นœ์ ˆํ•˜๊ฒŒ OpenGL์—๊ฒŒ ๊ทธ ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฒ„ํƒ์Šค ์†์„ฑ ๋งํ‚น

๋ฒ„ํ…์Šค ์…ฐ์ด๋”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฒ„ํ…์Šค ์†์„ฑ์˜ ํ˜•ํƒœ๋กœ ์›ํ•˜๋Š” ์ž…๋ ฅ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ์œ ์—ฐ์„ฑ์„ ํฌ๊ฒŒ ๋†’ํ˜€์ฃผ์ง€๋งŒ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ์˜ ์–ด๋–ค ๋ถ€๋ถ„์ด ๋ฒ„ํ…์Šค ์…ฐ์ด๋”์˜ ์–ด๋–ค ๋ฒ„ํ…์Šค ์†์„ฑ์œผ๋กœ ์ด๋™ํ•˜๋Š”์ง€ ์ˆ˜๋™์œผ๋กœ ์ง€์ •ํ•ด์•ผ ํ•จ์„ ๋œปํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” OpenGL์ด ๋ Œ๋”๋ง ์ „์— ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ํ•ด์„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง€์ •ํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๋ฒ„ํ…์Šค ๋ฒ„ํผ ๋ฐ์ดํ„ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ์ง€์ •๋ฉ๋‹ˆ๋‹ค.

vertex_attribute_pointer

์œ„์น˜ ๋ฐ์ดํ„ฐ๋Š” 32๋น„ํŠธ (4๋ฐ”์ดํŠธ) ๋ถ€๋™ ์†Œ์ˆ˜์  ๊ฐ’์œผ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

  • ๊ฐ ์œ„์น˜๋Š” 3๊ฐœ์˜ ๊ฐ’์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  • ๊ฐ 3๊ฐœ ๊ฐ’ ์„ธํŠธ ์‚ฌ์ด์—๋Š” ๊ณต๋ฐฑ(๋˜๋Š” ๋‹ค๋ฅธ ๊ฐ’)์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ฐ’์€ ๋ฐฐ์—ด์— ๋นผ๊ณกํžˆ ์••์ถ•๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ์˜ ์ฒซ ๋ฒˆ์งธ ๊ฐ’์€ ๋ฒ„ํผ์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์ง€์‹์„ ๋ฐ”ํƒ•์œผ๋กœ glVertexAttribPointer๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ(๋ฒ„ํ…์Šค ์†์„ฑ ๋‹น)๋ฅผ ํ•ด์„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ OpenGL์—๊ฒŒ ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

glVertexAttribPointer ํ•จ์ˆ˜์—๋Š” ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์ƒ๋‹นํžˆ ๋งŽ์œผ๋ฏ€๋กœ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” ๊ตฌ์„ฑํ•˜๋ ค๋Š” ๋ฒ„ํ…์Šค ์†์„ฑ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. layout (location = 0) ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„ํ…์Šค ์…ฐ์ด๋”์—์„œ ์œ„์น˜ ๋ฒ„ํ…์Šค ์†์„ฑ์˜ ์œ„์น˜๋ฅผ ์ง€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฒ„ํ…์Šค ์†์„ฑ์˜ ์œ„์น˜๋ฅผ 0 ์œผ๋กœ ์„ค์ •ํ•˜๊ณ  ์ด vertex ์†์„ฑ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์— 0 ์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹ค์Œ ์ธ์ˆ˜๋Š” ๋ฒ„ํ…์Šค ์†์„ฑ์˜ ํฌ๊ธฐ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. vertex ์†์„ฑ์€ vec3 ์ด๋ฏ€๋กœ 3 ๊ฐ’์„ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.
  • ์„ธ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” GL_FLOAT ๋ฐ์ดํ„ฐ์˜ ์œ ํ˜•์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. (GLSL์˜ vec* ๋Š” ๋ถ€๋™์†Œ์ˆ˜์  ๊ฐ’์œผ๋กœ ๊ตฌ์„ฑ๋จ).
  • ๋‹ค์Œ ์ธ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ •๊ทœํ™” ํ• ์ง€์˜ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ •์ˆ˜ ๋ฐ์ดํ„ฐ ์œ ํ˜• (int, byte)๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ์ด๋ฅผ GL_TRUE๋กœ ์„ค์ •ํ•˜๋ฉด ์ •์ˆ˜ ๋ฐ์ดํ„ฐ๋Š” 0 (๋˜๋Š” ๋ถ€ํ˜ธ ์žˆ๋Š” ๋ฐ์ดํ„ฐ์ผ ๊ฒฝ์šฐ 1 )๋กœ ์ •๊ทœํ™” ๋˜๊ณ  float์œผ๋กœ ๋ณ€ํ™˜ ๋  ๋•Œ 1 ๋กœ ์ •๊ทœํ™” ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ์™€ ๊ด€๋ จ์ด ์—†์œผ๋ฏ€๋กœ GL_FALSE๋กœ ๋‘๊ฒ ์Šต๋‹ˆ๋‹ค.
  • ๋‹ค์„ฏ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” stride๋กœ ์•Œ๋ ค์ ธ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ์—ฐ์†๋œ ๋ฒ„ํ…์Šค ์†์„ฑ ์‚ฌ์ด์˜ ๊ณต๊ฐ„์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ๋‹ค์Œ ์œ„์น˜ ๋ฐ์ดํ„ฐ ์„ธํŠธ๋Š” float ํฌ๊ธฐ์˜ ์ •ํ™•ํžˆ 3๋ฐฐ ๋–จ์–ด์ ธ ์žˆ์œผ๋ฏ€๋กœ ํ•ด๋‹น ๊ฐ’์„ stride๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐ์—ด์ด ๋นผ๊ณกํžˆ ์••์ถ•๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— (๋‹ค์Œ ๋ฒ„ํ…์Šค ์†์„ฑ ๊ฐ’ ์‚ฌ์ด์— ๊ณต๊ฐ„์ด ์—†์Œ) OpenGL์ด stride๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก stride๋ฅผ 0 ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค ( ๊ฐ’์ด ๋นผ๊ณกํžˆ ์••์ถ• ๋œ ๊ฒฝ์šฐ์—๋งŒ ์ž‘๋™ํ•จ.) ๋” ๋งŽ์€ ๋ฒ„ํ…์Šค ์†์„ฑ์ด ์žˆ์„ ๋•Œ๋งˆ๋‹ค ๊ฐ ๋ฒ„ํ…์Šค ์†์„ฑ ์‚ฌ์ด์˜ ๊ฐ„๊ฒฉ์„ ์‹ ์ค‘ํ•˜๊ฒŒ ์ •์˜ํ•ด์•ผ ํ•˜์ง€๋งŒ, ๋‚˜์ค‘์— ๋” ๋งŽ์€ ์˜ˆ์ œ๋ฅผ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ๋งˆ์ง€๋ง‰ ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” void* ์œ ํ˜•์ด๋ฏ€๋กœ ์ด์ƒํ•œ ์บ์ŠคํŒ…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฒ„ํผ์—์„œ ์œ„์น˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์‹œ์ž‘๋˜๋Š” ์˜คํ”„์…‹์ž…๋‹ˆ๋‹ค. ์œ„์น˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— ์žˆ์œผ๋ฏ€๋กœ ์ด ๊ฐ’์€ 0 ์ž…๋‹ˆ๋‹ค. ์ด ๋งค๊ฐœ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด์„œ๋Š” ๋‚˜์ค‘์— ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ฐ ๋ฒ„ํ…์Šค ์†์„ฑ์€ VBO๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” VBO(์—ฌ๋Ÿฌ VBO๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ)๋Š” glVertexAttribPointer๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ํ˜„์žฌ GL_ARRAY_BUFFER์— ๋ฐ”์ธ๋”ฉ ๋œ VBO์— ์˜ํ•ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. ์ด์ „์— ์ •์˜ ๋œ VBO๋Š” glVertexAttribPointer๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ์—ฌ์ „ํžˆ ๋ฐ”์ธ๋”ฉ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ๋ฒ„ํ…์Šค ์†์„ฑ 0์€ ์ด์ œ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ์™€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

์ด์ œ OpenGL์ด ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ํ•ด์„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง€์ •ํ–ˆ์œผ๋ฏ€๋กœ ๋ฒ„ํ…์Šค์†์„ฑ ์œ„์น˜๋ฅผ ์ธ์ˆ˜๋กœ ์ œ๊ณตํ•˜๋Š” glEnableVertexAttribArray๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„ํ…์Šค ์†์„ฑ๋„ ํ™œ์„ฑํ™”ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํ…์Šค ์†์„ฑ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™” ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ™œ์„ฑํ™”๋ฅผ ๋๋ƒˆ๋‹ค๋ฉด ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ๊ฒƒ์„ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค! ์šฐ๋ฆฌ๋Š” ๋ฒ„ํ…์Šค ๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„ํผ์—์„œ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ , ๋ฒ„ํ…์Šค ๋ฐ ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๋ฅผ ์„ค์ •ํ•˜๊ณ , OpenGL์—๊ฒŒ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ๋ฅผ ๋ฒ„ํ…์Šค ์…ฐ์ด๋”์˜ ๋ฒ„ํ…์Šค ์†์„ฑ๊ณผ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. OpenGL์—์„œ ๊ฐœ์ฒด๋ฅผ ๊ทธ๋ฆฌ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

// 0. OpenGL์ด ์‚ฌ์šฉํ•  ๋ฒ„ํผ์— ์šฐ๋ฆฌ์˜ ๋ฒ„ํ…์Šค ๋ฐฐ์—ด์„ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 1. ๊ทธ๋Ÿฐ๋‹ค์Œ ๋ฒ„ํ…์Šค ์†์„ฑ ํฌ์ธํ„ฐ๋ฅผ ์„ธํŒ…ํ•ฉ๋‹ˆ๋‹ค.
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);  
// 2. ๋ฌผ์ฒด๋ฅผ ๋žœ๋”๋งํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์šฐ๋ฆฌ๊ฐ€ ์ง  ์…ฐ์ด๋” ํ”„๋กœ๊ทธ๋žจ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
glUseProgram(shaderProgram);
// 3. ์ด์ œ ๋ฌผ์ฒด๋ฅผ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
someOpenGLFunctionThatDrawsOurTriangle();   

๋ฌผ์ฒด๋ฅผ ๊ทธ๋ฆฌ๊ณ  ์‹ถ์„๋•Œ๋งˆ๋‹ค ์ด๋Ÿฌํ•œ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ๋งŽ์•„ ๋ณด์ด์ง€ ์•Š์„์ˆ˜๋„ ์žˆ์ง€๋งŒ, 5๊ฐœ ์ด์ƒ์˜ ๋ฒ„ํ…์Šค ์†์„ฑ๊ณผ 100๊ฐœ ์ด์ƒ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด๋ณด์„ธ์š”. ์ ์ ˆํ•œ ๋ฒ„ํผ ๊ฐœ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๊ณ  ๊ฐ ๊ฐœ์ฒด์— ๋Œ€ํ•œ ๋ชจ๋“  ๋ฒ„ํ…์Šค ์†์„ฑ์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์€ ๋ฒˆ๊ฑฐ๋กœ์šด ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ชจ๋“  ์ƒํƒœ ๊ตฌ์„ฑ์„ ๊ฐœ์ฒด์— ์ €์žฅํ•˜๊ณ  ๋‹จ์ˆœํžˆ ์ด ๊ฐœ์ฒด๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜์—ฌ ์ƒํƒœ๋ฅผ ๋ณต์› ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋ฉด ์–ด๋–จ๊นŒ์š”?

Vertex Array Object

๋ฒ„ํ…์Šค ๋ฐฐ์—ด ๊ฐœ์ฒด (VAO๋ผ๊ณ  ํ•จ)๋Š” ๋ฒ„ํ…์Šค ๋ฒ„ํผ ๊ฐœ์ฒด์ฒ˜๋Ÿผ ๋ฐ”์ธ๋”ฉ ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ํ•ด๋‹น ์ง€์ ์—์„œ ์ดํ›„์˜ ๋ชจ๋“  ๋ฒ„ํ…์Šค ์†์„ฑ ํ˜ธ์ถœ์€ VAO ๋‚ด๋ถ€์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฒ„ํ…์Šค ์†์„ฑ ํฌ์ธํ„ฐ๋ฅผ ๊ตฌ์„ฑ ํ•  ๋•Œ ์ด๋Ÿฌํ•œ ํ˜ธ์ถœ์„ ํ•œ ๋ฒˆ๋งŒ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋˜๊ณ  ๊ฐœ์ฒด๋ฅผ ๊ทธ๋ฆด ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น VAO๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์„œ๋กœ ๋‹ค๋ฅธ VAO๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•˜๋Š” ๊ฒƒ ๋งŒํผ ์‰ฝ๊ฒŒ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ์™€ ๋ฒ„ํ…์Šค ์†์„ฑ ๊ตฌ์„ฑ๋“ค ์‚ฌ์ด๋ฅผ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฉ๊ธˆ ์„ค์ •ํ•œ ๋ชจ๋“  ์ƒํƒœ๋Š” VAO ๋‚ด์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

Core OpenGL์€ VAO๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ๋ฒ„ํ…์Šค ์ž…๋ ฅ์œผ๋กœ ๋ฌด์—‡์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ VAO๋ฅผ ๋ฌถ์ง€ ๋ชปํ•œ๋‹ค๋ฉด OpenGL์€ ์–ด๋– ํ•œ ๊ฒƒ๋„ ๊ทธ๋ฆฌ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฒ„ํ…์Šค ๋ฐฐ์—ด ๊ฐœ์ฒด์—๋Š” ๋‹ค์Œ์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

  • glVertexAttribPointer๋ฅผ ํ†ตํ•œ ๋ฒ„ํ…์Šค ์†์„ฑ ๊ตฌ์„ฑ
  • glVertexAttribPointer์— ๋Œ€ํ•œ ํ˜ธ์ถœ๋ณ„ ๋ฒ„ํ…์Šค ์†์„ฑ๊ณผ ์—ฐ๊ด€๋œ ๋ฒ„ํ…์Šค ๋ฒ„ํผ ๊ฐœ์ฒด.

vertex_array_objects

\VAO๋ฅผ ๋งŒ๋“œ๋Š” ํ”„๋กœ์„ธ์Šค๋Š” VBO๋ฅผ ๋งŒ๋“ค์—ˆ์„ ๋•Œ์™€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.

unsigned int VAO;
glGenVertexArrays(1, &VAO);  

VAO๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด glBindVertexArray๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ VAO๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ ์‹œ์ ๋ถ€ํ„ฐ ์šฐ๋ฆฌ๋Š” ํ•ด๋‹น VBO(๋“ค)์™€ ์†์„ฑ ํผ์ธํ„ฐ(๋“ค)์„ ๋ฐ”์ธ๋“œ/๊ตฌ์„ฑ ํ•œ ๋‹ค์Œ ๋‚˜์ค‘์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด VAO๋ฅผ ์–ธ ๋ฐ”์ธ๋“œ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ฒด๋ฅผ ๊ทธ๋ฆฌ๋ ค๋Š” ์ฆ‰์‹œ ๊ฐœ์ฒด๋ฅผ ๊ทธ๋ฆฌ๊ธฐ ์ „์— ์„ ํ˜ธํ•˜๋Š” ์„ค์ •์œผ๋กœ VAO๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ์—์„œ ์ด๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ๊ป๋‹ˆ๋‹ค.

// ..:: ์ดˆ๊ธฐํ™” ์ฝ”๋“œ (ํ•œ ๋ฒˆ๋งŒ ์ˆ˜ํ–‰ (๊ฐœ์ฒด๊ฐ€ ์ž์ฃผ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ํ•œ)) :: ..
// 1. Vertex Array Object ๋ฐ”์ธ๋”ฉ
glBindVertexArray(VAO);
// 2. OpenGL์ด ์‚ฌ์šฉํ•  ๋ฒ„ํผ์— ๋ฒ„ํƒ์Šค ๋ฐฐ์—ด์„ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. ๊ทธ๋Ÿฐ๋‹ค์Œ ์šฐ๋ฆฌ์˜ ๋ฒ„ํ…์Šค ์†์„ฑ ํฌ์ธํ„ฐ๋ฅผ ์„ธํŒ…ํ•ฉ๋‹ˆ๋‹ค.
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);  
  
[...]

// ..:: ๊ทธ๋ฆฌ๋Š” ์ฝ”๋“œ (๋žœ๋” ๋ฃจํ”„์—์„œ) :: ..
// 4. ๋ฌผ์ฒด๋ฅผ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค.
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
someOpenGLFunctionThatDrawsOurTriangle();   

์ด๊ฒŒ ๋‹ค์ž…๋‹ˆ๋‹ค! ์ง€๋‹จ ๋ช‡ ๋ฐฑ๋งŒ ํŽ˜์ด์ง•์„œ ์ˆ˜ํ–‰ ํ•œ ๋ชจ๋“  ์ž‘์—…์€ ๋ฒ„ํ…์Šค ์†์„ฑ ๊ตฌ์„ฑ๊ณผ ์‚ฌ์šฉํ•  VBO๋ฅผ VAO์— ์ €์žฅํ•˜๋Š” ์ด ์ˆœ๊ฐ„๊นŒ์ง€ ์ด์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ๊ทธ๋ฆฌ๋ ค๋Š” ๊ฐœ์ฒด๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ ๋จผ์ € ๋ชจ๋“  VAO (๋ฐ ํ•„์š”ํ•œ VBO ๋ฐ ์†์„ฑ ํฌ์ธํ„ฐ)๋ฅผ ์ƒ์„ฑ / ๊ตฌ์„ฑํ•˜๊ณ  ๋‚˜์ค‘์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ฒด ์ค‘ ํ•˜๋‚˜๋ฅผ ๊ทธ๋ฆฌ๋ ค๋Š” ์ˆœ๊ฐ„ ํ•ด๋‹น VAO๋ฅผ ๊ฐ€์ ธ ์™€์„œ ๋ฐ”์ธ๋”ฉ ํ•œ ๋‹ค์Œ ๊ฐœ์ฒด๋ฅผ ๊ทธ๋ฆฌ๊ณ  VAO๋ฅผ ๋‹ค์‹œ ๋ฐ”์ธ๋”ฉ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ ๋ชจ๋‘๊ฐ€ ๊ธฐ๋‹ค๋ ค ์˜จ ์‚ผ๊ฐํ˜•

์„ ํƒํ•œ ๊ฐœ์ฒด๋ฅผ ๊ทธ๋ฆฌ๊ธฐ ์œ„ํ•ด OpenGL์€ ํ˜„์žฌ ํ™œ์„ฑํ™” ๋œ ์…ฐ์ด๋”, ์ด์ „์— ์ •์˜ ๋œ ๋ฒ„ํ…์Šค ์†์„ฑ ๊ตฌ์„ฑ ๋ฐ VBO์˜ ๋ฒ„ํ…์Šค ๋ฐ์ดํ„ฐ (VAO๋ฅผ ํ†ตํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ๋ฐ”์ธ๋”ฉ ๋จ)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ๋ฅผ ๊ทธ๋ฆฌ๋Š” glDrawArrays ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);

glDrawArrays ํ•จ์ˆ˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๋ฆฌ๋ ค๋Š” OpenGL ๊ธฐ๋ณธ ์œ ํ˜•์„ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ์ทจํ•ฉ๋‹ˆ๋‹ค. ์ฒ˜์Œ์— ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ฆฌ๊ณ  ์‹ถ๋‹ค๊ณ  ๋ง ํ–ˆ์œผ๋‹ˆ GL_TRIANGLES๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๋ฆฌ๋ ค๋Š” ๋ฒ„ํ…์Šค ๋ฐฐ์—ด์˜ ์‹œ์ž‘ ์ธ๋ฑ์Šค๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๊ฒƒ์„ 0 ์œผ๋กœ ๋‘ก๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ์ธ์ˆ˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๋ฆฌ๋Š” ๋ฒ„ํ…์Šค์˜ ์ˆ˜๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, 3 ์ž…๋‹ˆ๋‹ค.(๋ฐ์ดํ„ฐ์—์„œ ์ •ํ™•ํžˆ 3๊ฐœ์˜ ๋ฒ„ํ…์Šค ๊ธธ์ด ์ธ ์‚ผ๊ฐํ˜• 1๊ฐœ๋งŒ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.)

์ด์ œ ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•˜๊ณ  ์˜ค๋ฅ˜๊ฐ€ ๋‚˜๋ฉด ๊ฑฐ๊พธ๋กœ ์ž‘์—…ํ•˜์‹ญ์‹œ์˜ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ปดํŒŒ์ผ ๋˜์ž๋ง์ž ๋‹ค์Œ ๊ฒฐ๊ณผ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

hellotriangle

์ „์ฒด ํ”„๋กœ๊ทธ๋žจ์˜ ์†Œ์Šค ์ฝ”๋“œ๋Š” ์—ฌ๊ธฐ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถœ๋ ฅ์ด ๋˜‘๊ฐ™์ง€ ์•Š๋‹ค๋ฉด ๊ทธ ๊ณผ์ •์—์„œ ๋ญ”๊ฐ€ ์ž˜๋ชปํ–ˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ ์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•˜๊ณ  ๋†“์นœ ๊ฒƒ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”.

Element Buffer Objects (์š”์†Œ ๋ฒ„ํผ ๊ฐœ์ฒด)

๋ฒ„ํ…์Šค๋ฅผ ๋ Œ๋”๋ง ํ•  ๋•Œ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋…ผ์˜ํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ์ด ํ•˜๋‚˜ ์žˆ๋Š”๋ฐ ๊ทธ๊ฒƒ์€ EBO๋กœ ์ถ•์•ฝ๋œ Element Buffer Objects ์ž…๋‹ˆ๋‹ค. ์š”์†Œ ๋ฒ„ํผ ๊ฐœ์ฒด๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ์˜ˆ์ œ๋ฅผ ๋ณด๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ์‚ผ๊ฐํ˜• ๋Œ€์‹  ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆฌ๋ ค๊ณ  ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๊ฐœ์˜ ์‚ผ๊ฐํ˜•์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. (OpenGL์€ ์ฃผ๋กœ ์‚ผ๊ฐํ˜•๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค). ๊ทธ๋Ÿฌ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ผญ์ง“์  ์ง‘ํ•ฉ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

	float vertices[] = {
    // ์ฒซ ์‚ผ๊ฐํ˜•
     0.5f,  0.5f, 0.0f,  // ์˜ค๋ฅธ์ชฝ ์ƒ๋‹จ
     0.5f, -0.5f, 0.0f,  // ์˜ค๋ฅธ์ชฝ ํ•˜๋‹จ
    -0.5f,  0.5f, 0.0f,  // ์™ผ์ชฝ ์ƒ๋‹จ
    // ๋‘๋ฒˆ์งธ ์‚ผ๊ฐํ˜•
     0.5f, -0.5f, 0.0f,  // ์˜ค๋ฅธ์ชฝ ํ•˜๋‹จ
    -0.5f, -0.5f, 0.0f,  // ์™ผ์ชฝ ํ•˜๋‹จ
    -0.5f,  0.5f, 0.0f   // ์™ผ์ชฝ ์ƒ๋‹จ
}; 

๋ณด์‹œ๋‹ค์‹œํ”ผ ์ง€์ •๋œ ๋ฒ„ํ…์Šค์— ์ผ๋ถ€ ๊ฒน์น˜๋Š” ๋ถ€๋ถ„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋ฅธ์ชฝ ํ•˜๋‹จ ๊ณผ ์™ผ์ชฝ ์ƒ๋‹จ์„ ๋‘ ๋ฒˆ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค! ๊ฐ™์€ ์‚ฌ๊ฐํ˜•์ด 6๊ฐœ๊ฐ€ ์•„๋‹Œ 4๊ฐœ์˜ ๋ฒ„ํ…์Šค๋กœ๋งŒ ์ง€์ • ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ 50% ์˜ค๋ฒ„ํ—ค๋“œ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํฐ ๋ฉ์–ด๋ฉ์–ด๋ฆฌ๊ฐ€ ์žˆ๋Š” 1000๊ฐœ ์ด์ƒ์˜ ์‚ผ๊ฐํ˜•์ด ๊ฒน์น˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š” ๋ณต์žกํ•œ ๋ชจ๋ธ์ผ ๊ฒฝ์šฐ ๋” ์•…ํ™”๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋” ๋‚˜์€ ํ•ด๊ฒฐ์ฑ…์€ ๊ณ ์œ  ํ•œ ๋ฒ„ํ…์Šค๋งŒ ์ €์žฅ ํ•œ ๋‹ค์Œ ์ด๋Ÿฌํ•œ ๋ฒ„ํ…์Šค๋ฅผ ๊ทธ๋ฆด ์ˆœ์„œ๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์‚ฌ๊ฐํ˜•์— 4๊ฐœ์˜ ๋ฒ„ํ…์Šค๋งŒ ์ €์žฅ ํ•œ ๋‹ค์Œ ์ˆœ์„œ๋ฅผ ์ง€์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ํ•ด๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. OpenGL์— ์ด์™€ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค๋ฉด ์ข‹์ง€ ์•Š์„๊นŒ์š”?

๊ณ ๋ง™๊ฒŒ๋„, ์š”์†Œ ๋ฒ„ํผ ๊ฐœ์ฒด๊ฐ€ ์ •ํ™•ํžˆ ๊ทธ๋Ÿฌํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„ํ…์Šค ๋ฒ„ํผ ๊ฐœ์ฒด์™€ ๋น„์Šทํ•œ EBO ํผํผ๋Š” ์–ด๋–ค ๋ฒ„ํ…์Šค๋ฅผ OpenGL์ด ๊ทธ๋ ค์•ผ ํ•˜๋Š”์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ์ธ๋ฑ์Šค๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์†Œ์œ„ ์ธ๋ฑ์‹ฑ ๋œ ๋“œ๋กœ์ž‰์ด ๋ฐ”๋กœ ์šฐ๋ฆฌ ๋ฌธ์ œ์˜ ํ•ด๊ฒฐ์ฑ…์ž…๋‹ˆ๋‹ค. ์‹œ์ž‘ํ•˜๋ ค๋ฉด ๋จผ์ € (๊ณ ์œ ํ•œ) ๋ฒ„ํ…์Šค์™€ ์ธ๋ฑ์Šค๋ฅผ ์ง€์ •ํ•˜์—ฌ ์ง์‚ฌ๊ฐํ˜•์œผ๋กœ ๊ทธ๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.

float vertices[] = {
     0.5f,  0.5f, 0.0f,  // ์˜ค๋ฅธ์ชฝ ์ƒ๋‹จ
     0.5f, -0.5f, 0.0f,  // ์˜ค๋ฅธ์ชฝ ํ•˜๋‹จ
    -0.5f, -0.5f, 0.0f,  // ์™ผ์ชฝ ํ•˜๋‹จ
    -0.5f,  0.5f, 0.0f   // ์™ผ์ชฝ ์ƒ๋‹จ 
};
unsigned int indices[] = {  // 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•จ!
    0, 1, 3,   // ์ฒซ๋ฒˆ์งธ ์‚ผ๊ฐํ˜•
    1, 2, 3    // ๋‘๋ฒˆ์งธ ์‚ผ๊ฐํ˜•
};  

์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ 6๊ฐœ ๋Œ€์‹  4๊ฐœ์˜ ๊ผญ์ง€์ ์ด ํ•„์š”ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ์š”์†Œ ๋ฒ„ํผ ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

unsigned int EBO;
glGenBuffers(1, &EBO);

VBO์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ EBO๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๊ณ  glBufferData๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ๋ฑ์Šค๋ฅผ ๋ฒ„ํผ์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ด๋ฒˆ์—๋Š” GL_ELEMENT_ARRAY_BUFFER ๋ฅผ ๋ฒ„ํผ ์œ ํ˜•์œผ๋กœ ์ง€์ •ํ•˜์ง€๋งŒ, ๋ฐ”์ธ๋“œ ๋ฐ ์–ธ๋ฐ”์ธ๋“œ ํ˜ธ์ถœ ์‚ฌ์ด์— ์ด๋Ÿฌํ•œ ํ˜ธ์ถœ์„ ๋„ฃ๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 

์ด์ œ GL_ELEMENT_ARRAY_BUFFER ๋ฅผ ๋ฒ„ํผ ํƒ€๊ฒŸ์œผ๋กœ์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ ํ•  ์ผ์€ glDrawArray ํ˜ธ์ถœ์„ glDrawElements๋กœ ๋Œ€์ฒดํ•˜์—ฌ ์ธ๋ฑ์Šค ๋ฒ„ํผ์—์„œ ์‚ผ๊ฐํ˜• ๋ Œ๋”๋ง์„ ํ•  ๊ฒƒ์ž„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. glDrawElements๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ํ˜„์žฌ ๋ฐ”์ธ๋”ฉ ๋œ ์š”์†Œ ๋ฒ„ํผ ๊ฐœ์ฒด์— ์ œ๊ณต๋œ ์ธ๋ฑ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค.

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” glDrawArrays์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๊ทธ๋ฆด ๋ชจ๋“œ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๋‘๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ๊ทธ๋ฆด ์š”์†Œ์˜ ๊ฐœ์ˆ˜ ๋˜๋Š” ํšŸ์ˆ˜์ž…๋‹ˆ๋‹ค. 6๊ฐœ์˜ ์ธ๋ฑ์Šค๋ฅผ ์ง€์ •ํ–ˆ์œผ๋ฏ€๋กœ ์ด 6๊ฐœ์˜ ์ •์ ์„ ๊ทธ๋ฆฌ๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์„ธ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” GL_UNSIGNED_INT ์œ ํ˜•์˜ ์ธ๋ฑ์Šค ์œ ํ˜•ํž™๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด EBO์—์„œ ์˜คํ”„์…‹์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ(๋˜๋Š” ์ธ๋ฑ์Šค ๋ฐฐ์—ด์„ ์ „๋‹ฌ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์š”์†Œ ๋ฒ„ํผ ๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ) 0์œผ๋กœ ๋‚จ๊ฒจ ๋‘ก๋‹ˆ๋‹ค.

glDrawElements ํ•จ์ˆ˜๋Š” ํ˜„์žฌ GL_ELEMENT_ARRAY_BUFFER ๋Œ€์ƒ์— ๋ฐ”์ธ๋”ฉ ๋œ EBO์—์„œ ์ธ๋ฑ์Šค๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์ธ๋ฑ์Šค๋กœ ๊ฐœ์ฒด๋ฅผ ๋ Œ๋”๋ง ํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น EBO๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ผญ์ง€์  ๋ฐฐ์—ด ๊ฐœ์ฒด๋„ ์š”์†Œ ๋ฒ„ํผ ๊ฐœ์ฒด ๋ฐ”์ธ๋”ฉ์„ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค. VAO๊ฐ€ ๋ฐ”์ธ๋”ฉ ๋œ ๋™์•ˆ ๋ฐ”์ธ๋”ฉ๋˜๋Š” ๋งˆ์ง€๋ง‰ ์š”์†Œ ๋ฒ„ํผ ๊ฐœ์ฒด๋Š” VAO์˜ ์š”์†Œ ๋ฒ„ํผ ๊ฐœ์ฒด๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. VAO์— ๋ฐ”์ธ๋”ฉ ๋˜๋ฉด ํ•ด๋‹น EBO๋„ ์ž๋™์œผ๋กœ ๋ฐ”์ธ๋”ฉ ๋ฉ๋‹ˆ๋‹ค.

vertex_array_objects_ebo

VAO๋Š” ๋Œ€์ƒ์ด GL_ELEMENT_ARRAY_BUFFER ์ผ ๋•Œ glBindBuffer ํ˜ธ์ถœ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋˜ํ•œ ๋ฐ”์ธ๋”ฉ ํ•ด์ œ ํ˜ธ์ถœ์„ ์ €์žฅํ•˜๋ฏ€๋กœ VAO๋ฐ”์ธ๋”ฉ์„ ํ•ด์ œํ•˜๊ธฐ ์ „์— ์š”์†Œ ๋ฐฐ์—ด ๋ฒ„ํผ๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•ด์ œํ•˜์ง€ ์•Š์•˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด EBO๊ฐ€ ๊ตฌ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ ์ดˆ๊ธฐํ™” ๋ฐ ๊ทธ๋ฆฌ๊ธฐ ์ฝ”๋“œ๋Š” ์ด์ œ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

// ..:: Initialization code :: ..
// 1. ๋ฒ„ํƒ์Šค ๋ฐฐ์—ด ๊ฐœ์ฒด ๋ฐ”์ธ๋”ฉ
glBindVertexArray(VAO);
// 2. OpenGL์ด ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฒ„ํƒ์Šค ๋ฒ„ํผ์— ์žˆ๋Š” ๋ฒ„ํƒ์Šค๋“ค์˜ ๋ฐฐ์—ด์„ ๋ณต์‚ฌ
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. OpenGL์ด ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์š”์†Œ ๋ฒ„ํผ์— ์žˆ๋Š” ์ธ๋ฑ์Šค ๋ฐฐ์—ด์„ ๋ณต์‚ฌ
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 4. ๊ทธ๋Ÿฐ๋‹ค์Œ ๋ฒ„ํ…์Šค ์†์„ฑ ํฌ์ธํ„ฐ๋“ค์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);  

[...]
  
// ..:: Drawing code (in render loop) :: ..
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);

ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์ด๋ฏธ์ง€๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์™ผ์ชฝ ์ด๋ฏธ์ง€๋Š” ์ต์ˆ™ํ•ด ๋ณด์ด๊ณ  ์˜ค๋ฅธ์ชฝ ์ด๋ฏธ์ง€๋Š” ์™€์ด์–ด ํ”„๋ ˆ์ž„ ๋ชจ๋“œ์—์„œ ๊ทธ๋ ค์ง„ ์ง์‚ฌ๊ฐํ˜•์ž…๋‹ˆ๋‹ค. ์™€์ด์–ด์–ด ํ”„๋ ˆ์ž„ ์‚ฌ๊ฐํ˜•์€ ์‚ฌ๊ฐํ˜•์ด ์‹ค์ œ๋กœ ๋‘ ๊ฐœ์˜ ์‚ผ๊ฐํ˜•์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

hellotriangle2

์™€์ด์–ดํ”„๋ ˆ์ž„ ๋ชจ๋“œ

์™€์ด์–ดํ”„๋ ˆ์ž„ ๋ชจ๋“œ๋กœ ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ฆฌ๋ฉด ๋„ˆ๋Š” OpenGL์ด glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) ์„ ํ†ตํ•ด ํ”„๋ฆฌ๋ฏธํ‹ฐ๋ธŒ๋ฅผ ๊ทธ๋ฆฌ๋Š” ๋ฐฉ๋ฒ•์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ๋ชจ๋“  ์‚ผ๊ฐํ˜•์˜ ์•ž๋ฉด๊ณผ ๋’ท๋ฉด์— ์ ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๋งํ•˜๊ณ  ๋‘ ๋ฒˆ์งธ ์ธ์ž๋Š” ์„ ์œผ๋กœ ๊ทธ๋ฆฌ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„์˜ ๋ชจ๋“  ๋“œ๋กœ์ž‰ ํ˜ธ์ถœ์€ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋ณธ๊ฐ’์„ ๋‹ค์‹œ ์„ค์ •ํ•  ๋•Œ๊นŒ์ง€ ์™€์ด์–ด ํ”„๋ ˆ์ž„ ๋ชจ๋“œ์—์„œ ์‚ผ๊ฐํ˜•์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

์˜ค๋ฅ˜๊ฐ€ ์žˆ์œผ๋ฉด ๋’ค๋กœ ๋Œ์•„๊ฐ€์„œ ๋†“์นœ ๊ฒƒ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ๋Š” ์—ฌ๊ธฐ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ๊ทธ๋žฌ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์‚ผ๊ฐํ˜•์ด๋‚˜ ์ง์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค๋ฉด ์ถ•ํ•˜ํ•ฉ๋‹ˆ๋‹ค. ํ˜„๋Œ€ OpenGL์˜ ๊ฐ€์žฅ ์–ด๋ ค์šด ๋ถ€๋ถ„ ์ค‘ ํ•˜๋‚˜์ธ ์ฒซ ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ฆด ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ์‚ผ๊ฐํ˜•์„ ๊ทธ๋ฆฌ๊ธฐ ์ „์— ๋งŽ์€ ์–‘์˜ ์ง€์‹์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ ์–ด๋ ค์šด ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ๊ณ ๋ง™๊ฒŒ๋„ ์šฐ๋ฆฌ๋Š” ์ด์ œ ๊ทธ ์žฅ๋ฒฝ์„ ๋„˜์–ด์„œ๊ณ  ๋‹ค์Œ ์žฅ์€ ์ดํ•ดํ•˜๊ธฐ ํ›จ์”ฌ ๋” ์‰ฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Additional resources

Exercises

  1. ๋ฐ์ดํ„ฐ์— ๋” ๋งŽ์€ ์ •์ ์„ ์ถ”๊ฐ€ํ•˜์—ฌ glDrawArrays๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 2๊ฐœ์˜ ์‚ผ๊ฐํ˜•์„ ๋‚˜๋ž€ํžˆ ๊ทธ๋ ค๋ณด์‹ญ์‹œ์˜ค. : ์ •๋‹ต
  2. ์ด์ œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ๋‘ ๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ VAO ๋ฐ VBO๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผํ•œ ๋‘ ๊ฐœ์˜ ์‚ผ๊ฐํ˜•์„ ๋งŒ๋“ค์–ด ๋ณด์„ธ์š” : ์ •๋‹ต
  3. ๋‘ ๋ฒˆ์งธ ํ”„๋กœ๊ทธ๋žจ์ด ๋…ธ๋ž€์ƒ‰์„ ์ถœ๋ ฅํ•˜๋Š” ๋‹ค๋ฅธ ํ”„๋ ˆ๊ทธ๋จผํŠธ ์…ฐ์ด๋”๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋‘ ๊ฐœ์˜ ์…ฐ์ด๋” ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋‘ ์‚ผ๊ฐํ˜•์„ ๋‹ค์‹œ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค. ๋‘ ์‚ผ๊ฐํ˜•์„ ๋ชจ๋‘ ๋…ธ๋ž€์ƒ‰์„ ์ถœ๋ ฅํ•˜๋Š” ๊ณณ์—์„œ ๊ทธ๋ฆฝ๋‹ˆ๋‹ค. : ์ •๋‹ต