// sb6.h 헤더 파일을 포함시킨다.
#include <sb7.h>
#include <vmath.h>
#include <shader.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
// sb6::application을 상속받는다.
class my_application : public sb7::application
{
public:
// 쉐이더 컴파일한다.
// basic lighting shader
GLuint compile_shader2(void)
{
// 버텍스 쉐이더를 생성하고 컴파일한다.
GLuint vertex_shader = sb7::shader::load("basic_lighting_vs.glsl", GL_VERTEX_SHADER);
// 프래그먼트 쉐이더를 생성하고 컴파일한다.
GLuint fragment_shader = sb7::shader::load("basic_lighting_fs.glsl", GL_FRAGMENT_SHADER);
// 프로그램을 생성하고 쉐이더를 Attach시키고 링크한다.
GLuint program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
// 이제 프로그램이 쉐이더를 소유하므로 쉐이더를 삭제한다.
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
return program;
}
// simple color shader
GLuint compile_shader3(void)
{
// 버텍스 쉐이더를 생성하고 컴파일한다.
GLuint vertex_shader = sb7::shader::load("simple_color_vs.glsl", GL_VERTEX_SHADER);
// 프래그먼트 쉐이더를 생성하고 컴파일한다.
GLuint fragment_shader = sb7::shader::load("simple_color_fs.glsl", GL_FRAGMENT_SHADER);
// 프로그램을 생성하고 쉐이더를 Attach시키고 링크한다.
GLuint program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
// 이제 프로그램이 쉐이더를 소유하므로 쉐이더를 삭제한다.
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
return program;
}
// 애플리케이션 초기화 수행한다.
virtual void startup()
{
// 쉐이더 프로그램 컴파일 및 연결
shader_programs[1] = compile_shader2();
shader_programs[2] = compile_shader3();
// VAO, VBO, EBO, texture 생성
glGenVertexArrays(3, VAOs);
glGenBuffers(3, VBOs);
glGenBuffers(2, EBOs);
glGenTextures(3, textures);
stbi_set_flip_vertically_on_load(true);
// 두 번째 객체 정의 : 박스 --------------------------------------------------
glBindVertexArray(VAOs[1]);
// 박스 점들의 위치와 컬러, 텍스처 좌표를 정의한다.
float box_s = 1.0f, box_t = 1.0f;
GLfloat box_vertices[] = {
// 뒷면
-0.25f, 0.5f, -0.25f, 1.0f, 0.0f, 0.0f, box_s, box_t, 0.0f, 0.0f, -1.0f,
0.25f, 0.0f, -0.25f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f,
-0.25f, 0.0f, -0.25f, 1.0f, 0.0f, 0.0f, box_s, 0.0f, 0.0f, 0.0f, -1.0f,
0.25f, 0.0f, -0.25f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f,
-0.25f, 0.5f, -0.25f, 1.0f, 0.0f, 0.0f, box_s, box_t, 0.0f, 0.0f, -1.0f,
0.25f, 0.5f, -0.25f, 1.0f, 0.0f, 0.0f, 0.0f, box_t, 0.0f, 0.0f, -1.0f,
// 우측면
0.25f, 0.0f, -0.25f, 0.0f, 1.0f, 0.0f, box_s, 0.0f, 1.0f, 0.0f, 0.0f,
0.25f, 0.5f, -0.25f, 0.0f, 1.0f, 0.0f, box_s, box_t, 1.0f, 0.0f, 0.0f,
0.25f, 0.0f, 0.25f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.25f, 0.0f, 0.25f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.25f, 0.5f, -0.25f, 0.0f, 1.0f, 0.0f, box_s, box_t, 1.0f, 0.0f, 0.0f,
0.25f, 0.5f, 0.25f, 0.0f, 1.0f, 0.0f, 0.0f, box_t, 1.0f, 0.0f, 0.0f,
// 정면
0.25f, 0.0f, 0.25f, 0.0f, 0.0f, 1.0f, box_s, 0.0f, 0.0f, 0.0f, 1.0f,
0.25f, 0.5f, 0.25f, 0.0f, 0.0f, 1.0f, box_s, box_t, 0.0f, 0.0f, 1.0f,
-0.25f, 0.0f, 0.25f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.25f, 0.0f, 0.25f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.25f, 0.5f, 0.25f, 0.0f, 0.0f, 1.0f, box_s, box_t, 0.0f, 0.0f, 1.0f,
-0.25f, 0.5f, 0.25f, 0.0f, 0.0f, 1.0f, 0.0f, box_t, 0.0f, 0.0f, 1.0f,
// 좌측면
-0.25f, 0.0f, 0.25f, 1.0f, 0.0f, 1.0f, box_s, 0.0f, -1.0f, 0.0f, 0.0f,
-0.25f, 0.5f, 0.25f, 1.0f, 0.0f, 1.0f, box_s, box_t, -1.0f, 0.0f, 0.0f,
-0.25f, 0.0f, -0.25f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.25f, 0.0f, -0.25f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.25f, 0.5f, 0.25f, 1.0f, 0.0f, 1.0f, box_s, box_t, -1.0f, 0.0f, 0.0f,
-0.25f, 0.5f, -0.25f, 1.0f, 0.0f, 1.0f, 0.0f, box_t, -1.0f, 0.0f, 0.0f,
// 바닥면
-0.25f, 0.0f, 0.25f, 1.0f, 1.0f, 0.0f, box_s, 0.0f, 0.0f, -1.0f, 0.0f,
0.25f, 0.0f, -0.25f, 1.0f, 1.0f, 0.0f, 0.0f, box_t, 0.0f, -1.0f, 0.0f,
0.25f, 0.0f, 0.25f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
0.25f, 0.0f, -0.25f, 1.0f, 1.0f, 0.0f, 0.0f, box_t, 0.0f, -1.0f, 0.0f,
-0.25f, 0.0f, 0.25f, 1.0f, 1.0f, 0.0f, box_s, 0.0, 0.0f, -1.0f, 0.0f,
-0.25f, 0.0f, -0.25f, 1.0f, 1.0f, 0.0f, box_s, box_t, 0.0f, -1.0f, 0.0f,
// 윗면
-0.25f, 0.5f, -0.25f, 0.0f, 1.0f, 1.0f, 0.0f, box_t, 0.0f, 1.0f, 0.0f,
0.25f, 0.5f, 0.25f, 0.0f, 1.0f, 1.0f, box_s, 0.0f, 0.0f, 1.0f, 0.0f,
0.25f, 0.5f, -0.25f, 0.0f, 1.0f, 1.0f, box_s, box_t, 0.0f, 1.0f, 0.0f,
0.25f, 0.5f, 0.25f, 0.0f, 1.0f, 1.0f, box_s, 0.0f, 0.0f, 1.0f, 0.0f,
-0.25f, 0.5f, -0.25f, 0.0f, 1.0f, 1.0f, 0.0f, box_t, 0.0f, 1.0f, 0.0f,
-0.25f, 0.5f, 0.25f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
//=================================================================================
1.75f, 0.5f, -0.25f, 1.0f, 0.0f, 0.0f, box_s, box_t, 0.0f, 0.0f, -1.0f,
2.25f, 0.0f, -0.25f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f,
1.75f, 0.0f, -0.25f, 1.0f, 0.0f, 0.0f, box_s, 0.0f, 0.0f, 0.0f, -1.0f,
2.25f, 0.0f, -0.25f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f,
1.75f, 0.5f, -0.25f, 1.0f, 0.0f, 0.0f, box_s, box_t, 0.0f, 0.0f, -1.0f,
2.25f, 0.5f, -0.25f, 1.0f, 0.0f, 0.0f, 0.0f, box_t, 0.0f, 0.0f, -1.0f,
// 우측면
2.25f, 0.0f, -0.25f, 0.0f, 1.0f, 0.0f, box_s, 0.0f, 1.0f, 0.0f, 0.0f,
2.25f, 0.5f, -0.25f, 0.0f, 1.0f, 0.0f, box_s, box_t, 1.0f, 0.0f, 0.0f,
2.25f, 0.0f, 0.25f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
2.25f, 0.0f, 0.25f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
2.25f, 0.5f, -0.25f, 0.0f, 1.0f, 0.0f, box_s, box_t, 1.0f, 0.0f, 0.0f,
2.25f, 0.5f, 0.25f, 0.0f, 1.0f, 0.0f, 0.0f, box_t, 1.0f, 0.0f, 0.0f,
// 정면
2.25f, 0.0f, 0.25f, 0.0f, 0.0f, 1.0f, box_s, 0.0f, 0.0f, 0.0f, 1.0f,
2.25f, 0.5f, 0.25f, 0.0f, 0.0f, 1.0f, box_s, box_t, 0.0f, 0.0f, 1.0f,
1.75f, 0.0f, 0.25f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
1.75f, 0.0f, 0.25f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
2.25f, 0.5f, 0.25f, 0.0f, 0.0f, 1.0f, box_s, box_t, 0.0f, 0.0f, 1.0f,
1.75f, 0.5f, 0.25f, 0.0f, 0.0f, 1.0f, 0.0f, box_t, 0.0f, 0.0f, 1.0f,
// 좌측면
1.75f, 0.0f, 0.25f, 1.0f, 0.0f, 1.0f, box_s, 0.0f, -1.0f, 0.0f, 0.0f,
1.75f, 0.5f, 0.25f, 1.0f, 0.0f, 1.0f, box_s, box_t, -1.0f, 0.0f, 0.0f,
1.75f, 0.0f, -0.25f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
1.75f, 0.0f, -0.25f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
1.75f, 0.5f, 0.25f, 1.0f, 0.0f, 1.0f, box_s, box_t, -1.0f, 0.0f, 0.0f,
1.75f, 0.5f, -0.25f, 1.0f, 0.0f, 1.0f, 0.0f, box_t, -1.0f, 0.0f, 0.0f,
// 바닥면
1.75f, 0.0f, 0.25f, 1.0f, 1.0f, 0.0f, box_s, 0.0f, 0.0f, -1.0f, 0.0f,
2.25f, 0.0f, -0.25f, 1.0f, 1.0f, 0.0f, 0.0f, box_t, 0.0f, -1.0f, 0.0f,
2.25f, 0.0f, 0.25f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
2.25f, 0.0f, -0.25f, 1.0f, 1.0f, 0.0f, 0.0f, box_t, 0.0f, -1.0f, 0.0f,
1.75f, 0.0f, 0.25f, 1.0f, 1.0f, 0.0f, box_s, 0.0, 0.0f, -1.0f, 0.0f,
1.75f, 0.0f, -0.25f, 1.0f, 1.0f, 0.0f, box_s, box_t, 0.0f, -1.0f, 0.0f,
// 윗면
1.75f, 0.5f, -0.25f, 0.0f, 1.0f, 1.0f, 0.0f, box_t, 0.0f, 1.0f, 0.0f,
2.25f, 0.5f, 0.25f, 0.0f, 1.0f, 1.0f, box_s, 0.0f, 0.0f, 1.0f, 0.0f,
2.25f, 0.5f, -0.25f, 0.0f, 1.0f, 1.0f, box_s, box_t, 0.0f, 1.0f, 0.0f,
2.25f, 0.5f, 0.25f, 0.0f, 1.0f, 1.0f, box_s, 0.0f, 0.0f, 1.0f, 0.0f,
1.75f, 0.5f, -0.25f, 0.0f, 1.0f, 1.0f, 0.0f, box_t, 0.0f, 1.0f, 0.0f,
1.75f, 0.5f, 0.25f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f
};
// VBO를 생성하여 vertices 값들을 복사
glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(box_vertices), box_vertices, GL_STATIC_DRAW);
// VBO를 나누어서 각 버텍스 속성으로 연결
// 위치 속성 (location = 0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// 컬러 속성 (location = 1)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// 텍스처 좌표 속성 (location = 2)
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
// 노멀 속성 (location = 3)
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(8 * sizeof(float)));
glEnableVertexAttribArray(3);
// VBO 및 버텍스 속성을 다 했으니 VBO와 VAO를 unbind한다.
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// 세 번째 객체 정의 : 피라미드 --------------------------------------------------
glBindVertexArray(VAOs[2]);
// 피라미드 점들의 위치와 컬러, 텍스처 좌표를 정의한다.
GLfloat pyramid_vertices[] = {
1.0f, 0.0f, -1.0f, // 우측 상단
-1.0f, 0.0f, -1.0f, // 좌측 상단
-1.0f, 0.0f, 1.0f, // 좌측 하단
1.0f, 0.0f, 1.0f, // 우측 하단
0.0f, 1.0f, 0.0f, // 상단 꼭지점
0.0f, -1.0f, 0.0f, // 하단 꼭지점
};
// 삼각형으로 그릴 인덱스를 정의한다.
GLuint pyramid_indices[] = {
4, 0, 1,
4, 1, 2,
4, 2, 3,
4, 3, 0,
5, 1, 0,
5, 2, 1,
5, 3, 2,
5, 0, 3,
};
// VBO를 생성하여 vertices 값들을 복사
glBindBuffer(GL_ARRAY_BUFFER, VBOs[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(pyramid_vertices), pyramid_vertices, GL_STATIC_DRAW);
// VBO를 나누어서 각 버텍스 속성으로 연결
// 위치 속성 (location = 0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// EBO를 생성하고 indices 값들을 복사
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBOs[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(pyramid_indices), pyramid_indices, GL_STATIC_DRAW);
// VBO 및 버텍스 속성을 다 했으니 VBO와 VAO를 unbind한다.
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
// 애플리케이션 끝날 때 호출된다.
virtual void shutdown()
{
glDeleteTextures(2, textures);
glDeleteBuffers(2, EBOs);
glDeleteBuffers(3, VBOs);
glDeleteVertexArrays(3, VAOs);
glDeleteProgram(shader_programs[1]);
glDeleteProgram(shader_programs[2]);
}
// 렌더링 virtual 함수를 작성해서 오버라이딩한다.
virtual void render(double currentTime)
{
const GLfloat black[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, black);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
//GLint uniform_transform2 = glGetUniformLocation(shader_programs[1], "transform");
// 카메라 매트릭스 계산
float distance = 2.f;
vmath::vec3 eye((float)cos(currentTime * 1.f) * distance, 1.0, (float)sin(currentTime * 1.f) * distance);
vmath::vec3 center(0.0, 0.0, 0.0);
vmath::vec3 up(0.0, 1.0, 0.0);
vmath::mat4 lookAt = vmath::lookat(eye, center, up);
float fov = 50.f;
vmath::mat4 projM = vmath::perspective(fov, info.windowWidth / (float)info.windowHeight, 0.1f, 1000.0f);
// 라이팅 설정 ---------------------------------------
vmath::vec3 lightPos = vmath::vec3(0.0f, 0.25f, 0.0f);// (0.0f, 0.5f, 0.0f);
vmath::vec3 lightColor(1.0f, 1.0f, 1.0f);
vmath::vec3 viewPos = eye;
vmath::vec3 yellowboxColor(1.0f, 0.5f, 0.0f);
vmath::vec3 puppleboxColor(0.5f, 0.0f, 1.0f);
// 박스 그리기 ---------------------------------------
float angle = currentTime * 100;
vmath::mat4 transform = vmath::translate(-1.0f, 0.0f, 0.0f) *
vmath::rotate(angle, 0.0f, 1.0f, 0.0f);
glUseProgram(shader_programs[1]);
glUniformMatrix4fv(glGetUniformLocation(shader_programs[1], "projection"), 1, GL_FALSE, projM);
glUniformMatrix4fv(glGetUniformLocation(shader_programs[1], "view"), 1, GL_FALSE, lookAt);
glUniformMatrix4fv(glGetUniformLocation(shader_programs[1], "model"), 1, GL_FALSE, transform);
glUniform3fv(glGetUniformLocation(shader_programs[1], "lightPos"), 1, lightPos);
glUniform3fv(glGetUniformLocation(shader_programs[1], "viewPos"), 1, viewPos);
glUniform3fv(glGetUniformLocation(shader_programs[1], "lightColor"), 1, lightColor);
glUniform3fv(glGetUniformLocation(shader_programs[1], "boxColor"), 1, yellowboxColor);
glUniform1f(glGetUniformLocation(shader_programs[1], "shininess"), 64.f);
glBindVertexArray(VAOs[1]);
glDrawArrays(GL_TRIANGLES, 0, 36);
transform = vmath::translate(1.0f, 0.0f, 0.0f) * vmath::rotate(angle, 0.0f, 1.0f, 0.0f);
glUniformMatrix4fv(glGetUniformLocation(shader_programs[1], "model"), 1, GL_FALSE, transform);
glUniform3fv(glGetUniformLocation(shader_programs[1], "boxColor"), 1, puppleboxColor);
glUniform1f(glGetUniformLocation(shader_programs[1], "shininess"), 1.f);
glDrawArrays(GL_TRIANGLES, 0, 36);
//-----------------------------광원위치오브젝트
float scaleFactor2 = 0.05f;
vmath::mat4 rotateM2 = vmath::translate(0.0f, 0.5f, 0.0f) *
vmath::rotate(angle, 0.0f, 1.0f, 0.0f) * vmath::scale(scaleFactor2, scaleFactor2, scaleFactor2);
glUseProgram(shader_programs[2]);
glUniform3fv(glGetUniformLocation(shader_programs[2], "color"), 1, lightColor);
glUniformMatrix4fv(glGetUniformLocation(shader_programs[2], "projection"), 1, GL_FALSE, projM);
glUniformMatrix4fv(glGetUniformLocation(shader_programs[2], "view"), 1, GL_FALSE, lookAt);
glUniformMatrix4fv(glGetUniformLocation(shader_programs[2], "model"), 1, GL_FALSE, rotateM2);
glBindVertexArray(VAOs[2]);
glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
}
private:
GLuint shader_programs[3];
GLuint VAOs[3], VBOs[3], EBOs[2];
GLuint textures[3];
};
// DECLARE_MAIN의 하나뿐인 인스턴스
DECLARE_MAIN(my_application)
//<<<basic_lighting_vs.glsl>>>
#version 430 core
//상자
layout (location = 0) in vec3 pos;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoord;
layout (location = 3) in vec3 normal; //노멀벡터
out vec3 vsPos;
out vec3 vsNormal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
vsPos = vec3(model * vec4(pos, 1.0));
vsNormal = mat3(transpose(inverse(model))) * normal;
gl_Position = projection * view * vec4(vsPos, 1.0);
}
//<<<basic_lighting_fs.glsl>>>
#version 430 core
in vec3 vsNormal;
in vec3 vsPos;
//상자
uniform vec3 lightPos;
uniform vec3 viewPos;
uniform vec3 lightColor;
uniform vec3 boxColor;
uniform float shininess;
out vec4 fragColor;
void main()
{
// ambient 은은한 빛
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
// diffuse 명암
vec3 norm = normalize(vsNormal);
vec3 lightDir = normalize(lightPos - vsPos);//빛의 방향 = 빛 위치 - 점 위치
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
// specular 반사 산란 정도
float specularStrength = 1.0;
vec3 viewDir = normalize(viewPos - vsPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess);
vec3 specular = specularStrength * spec * lightColor;
vec3 result = (ambient + diffuse + specular) * boxColor;
fragColor = vec4(result, 1.0);
}
//<<<simple_color_vs.glsl>>>
#version 430 core
//피라미드 광원
layout (location = 0) in vec3 pos;
out vec3 vsColor;
uniform vec3 color;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(pos, 1.0);
vsColor = color;
}
#version 430 core
//피라미드 광원
in vec3 vsColor;
out vec4 fragColor;
void main()
{
fragColor = vec4(vsColor, 1.0);
}
Phong 조명 모델 = ambient(전체적으로 은은한 빛) + diffuse(거리, 방향에 따른 명암) + specular(빛 반사)이다
이 떄 diffuse를 구하기 위해 면의 방향, 즉 노멀 벡터가 필요하므로 VBO 노멀속성으로 버테스쉐이더로 보낸다.
버텍스쉐이더에서 받아온 노멀벡터는 diffuse계산을 위해 처리하고 프래그먼트 쉐이더로 보내준다.
render에서 라이팅에 관련된 변수들을 선언한다
lightPos = 광원 위치
lightColor = 빛의 색상 (1, 1, 1) = 백색광
viewPos = 빛을 보는 위치
yellowboxColor = 박스의 색상
puppleboxColor = 박스의 색상
설정한 벡터 및 변수들은 uniform을 통해 프래그먼트 쉐이더로 보내준다.
프래그먼트 쉐이더에서 각각 ambient diffuse specular 값을 구해준 뒤 박스의 색상을 곱해 최종 벡터를 구한 뒤 출력한다.
'opengl' 카테고리의 다른 글
opengl spot,point 라이팅 (0) | 2023.01.05 |
---|---|
opengl 텍스처 겹치기 / 컴파일 쉐이더, 텍스처로드 함수화 (0) | 2023.01.05 |
opengl 텍스처 (0) | 2023.01.04 |
opengl 시점변환 원근투영 - opengl라이브러리 (0) | 2022.09.06 |
opengl 시점변환 원근투영 - 하드코딩 (0) | 2022.09.06 |