Anonymous
Как перевести точечный свет и повернуть направленный свет OpenGL?
Сообщение
Anonymous » 31 май 2024, 22:53
Я намерен реализовать затенение по Гуро с двумя источниками света (точечный свет и направленный свет)
Я хочу перевести точечный свет и повернуть направленный свет с помощью функции обратного вызова клавиатуры OpenGL.
Но согласно моему текущему коду свет не движется.
Это мой main.cpp:
Код: Выделить всё
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include // rotate(), scale(), translate()
#include
#include
using namespace std;
GLuint VertexArrayID;
GLuint programID;
GLint modelLoc;
GLint viewLoc;
GLint projLoc;
float sx = 0;
float sy = 0;
float sz = 0;
float translationStep = 0.1f;
float rotationAngle = 0.0f;
float rotationStep = 5.0f;
bool projMode = true; // true: perspective, false: ortho
GLint pointLightPosLoc;
GLint pointLightColorLoc;
GLuint directLightDirLoc;
GLuint directLightColorLoc;
glm::vec3 pointLightPos;
glm::vec3 pointLightColor;
glm::vec3 directLightDir;
glm::vec3 directLightColor;
GLfloat cubeVertices[] = {
0.1f, 0.1f, 0.1f, // v0
-0.1f, 0.1f, 0.1f, // v1
-0.1f, -0.1f, 0.1f, // v2
0.1f, -0.1f, 0.1f, // v3
0.1f, -0.1f, -0.1f, // v4
0.1f, 0.1f, -0.1f, // v5
-0.1f, 0.1f, -0.1f, // v6
-0.1f, -0.1f, -0.1f // v7
};
GLfloat cubeColors[] = {
1.0f, 0.0f, 0.0f, 1.0f, // Red
0.0f, 1.0f, 0.0f, 1.0f, // Green
0.0f, 0.0f, 1.0f, 1.0f, // Blue
1.0f, 1.0f, 0.0f, 1.0f, // Yellow
1.0f, 0.0f, 1.0f, 1.0f, // Magenta
0.0f, 1.0f, 1.0f, 1.0f, // Cyan
};
GLint cubeIndices[] = {
//front
0,1,2,
0,2,3,
//right
0,3,4,
0,4,5,
//up
0,1,6,
0,6,5,
//left
1,2,7,
1,7,6,
//down
3,7,4,
3,2,7,
//back
5,7,6,
5,4,7,
};
GLfloat cubeNormals[] = {
0.0f, 0.0f, 1.0f, // front
1.0f, 0.0f, 0.0f, // right
0.0f, 1.0f, 0.0f, // up
-1.0f, 0.0f, 0.0f, // left
0.0f, -1.0f, 0.0f, // down
0.0f, 0.0f, -1.0f, // back
};
GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path)
{
//create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
GLint Result = GL_FALSE;
int InfoLogLength;
//Read the vertex shader code from the file
string VertexShaderCode;
ifstream VertexShaderStream(vertex_file_path, ios::in);
if (VertexShaderStream.is_open())
{
string Line = "";
while (getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
}
//Compile Vertex Shader
char const* VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
glCompileShader(VertexShaderID);
printf("Compiling shader : %s\n", vertex_file_path);
//Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
vector VertexShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
}
//Read the fragment shader code from the file
string FragmentShaderCode;
ifstream FragmentShaderStream(fragment_file_path, ios::in);
if (FragmentShaderStream.is_open())
{
string Line = "";
while (getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}
//Compile Fragment Shader
char const* FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
glCompileShader(FragmentShaderID);
printf("Compiling shader : %s\n", fragment_file_path);
//Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
vector FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
}
//Link the program
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
fprintf(stdout, "Linking program\n");
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
vector ProgramErrorMessage(max(InfoLogLength, int(1)));
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
void renderScene(void)
{
//Clear all pixels
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Let's draw something here
glBindVertexArray(VertexArrayID);
//define the size of point and draw a point.
int numCubes = 10;
for (int i = 0; i < numCubes; i++) {
glm::mat4 model = glm::mat4(1.0f);
glm::vec3 translateVec(0.0f + sx, i * 0.3f + sy, 0.0f + sz);
model = glm::translate(model, translateVec);
glm::vec3 rotationAxis = glm::vec3(0.0f, 1.0f, 0.0f);
model = glm::rotate(model, glm::radians(rotationAngle), rotationAxis);
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glDrawElements(GL_TRIANGLES, sizeof(cubeIndices) / sizeof(GLint), GL_UNSIGNED_INT, 0);
}
//Double buffer
glutSwapBuffers();
}
void translationKeyboard(unsigned char key, int x, int y) {
switch (key) {
case 'q':
sx += translationStep;
break;
case 'w':
sx -= translationStep;
break;
case 'a':
sy += translationStep;
break;
case 's':
sy -= translationStep;
break;
case 'z':
sz += translationStep;
break;
case 'x':
sz -= translationStep;
break;
case 'o':
printf("%d\n", pointLightPos.x); //temporary
pointLightPos.x += translationStep;
break;
case 'p':
pointLightPos.x -= translationStep;
break;
case 'k':
pointLightPos.y += translationStep;
break;
case 'l':
pointLightPos.y -= translationStep;
break;
case 'n':
pointLightPos.z += translationStep;
break;
case 'm':
pointLightPos.z -= translationStep;
break;
}
glutPostRedisplay();
}
void rotationKeyboard(int key, int x, int y) {
switch (key) {
case GLUT_KEY_LEFT:
rotationAngle -= rotationStep;
break;
case GLUT_KEY_RIGHT:
rotationAngle += rotationStep;
break;
case GLUT_KEY_UP:
directLightDir.y += rotationStep;
break;
case GLUT_KEY_DOWN:
directLightDir.y -= rotationStep;
break;
}
glutPostRedisplay();
}
void setProjectionMatrix() {
glm::mat4 proj;
int width = glutGet(GLUT_WINDOW_WIDTH);
int height = glutGet(GLUT_WINDOW_HEIGHT);
if (projMode) {
// perspective projection
proj = glm::perspective(glm::radians(45.0f), (float)width / (float)height, 0.1f, 100.0f);
}
else {
// orthogonal projection
proj = glm::ortho(-3.0f, 3.0f, -3.0f, 3.0f, -15.0f, 15.0f);
}
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(proj));
}
void ProjecionModeMouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
projMode = !projMode;
setProjectionMatrix();
glutPostRedisplay();
}
}
void init()
{
//initilize the glew and check the errors.
GLenum res = glewInit();
if (res != GLEW_OK)
{
fprintf(stderr, "Error: '%s' \n", glewGetErrorString(res));
}
//select the background color
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthRange(0.0f, 1.0f);
}
int main(int argc, char** argv)
{
//init GLUT and create Window
//initialize the GLUT
glutInit(&argc, argv);
//GLUT_DOUBLE enables double buffering (drawing to a background buffer while the other buffer is displayed)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
//These two functions are used to define the position and size of the window.
glutInitWindowPosition(200, 200);
glutInitWindowSize(480, 480);
//This is used to define the name of the window.
glutCreateWindow("Simple OpenGL Window");
//call initization function
init();
//0.
programID = LoadShaders("GVertexShader.txt", "GFragmentShader.txt");
glUseProgram(programID);
/**************************************************/
// 모델, 뷰, 프로젝션 행렬을 셰이더에 전달
modelLoc = glGetUniformLocation(programID, "model");
viewLoc = glGetUniformLocation(programID, "view");
projLoc = glGetUniformLocation(programID, "proj");
// 뷰 행렬 설정
glm::vec3 cameraPosition(5.0f, 3.0f, 5.0f); // 카메라 위치
glm::vec3 targetPosition(2.0f, 2.0f, 2.0f); // 타겟(큐브) 위치
glm::vec3 upVector(0.0f, 1.0f, 0.0f); // 업 벡터
glm::mat4 view = glm::lookAt(cameraPosition, targetPosition, upVector);
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
// 프로젝션 행렬 설정
setProjectionMatrix();
glm::vec3 pointLightPos(2.0f, 2.0f, 2.0f);
glm::vec3 pointLightColor(1.0f, 1.0f, 1.0f);
glm::vec3 directLightDir(-2.0f, -2.0f, -2.0f);
glm::vec3 directLightColor(1.0f, 1.0f, 1.0f);
// 점 광원의 위치, 색상을 셰이더에 전달
pointLightPosLoc = glGetUniformLocation(programID, "pointLightPos");
glUniform3fv(directLightDirLoc, 1, glm::value_ptr(directLightDir));
pointLightColorLoc = glGetUniformLocation(programID, "pointLightColor");
glUniform3fv(pointLightColorLoc, 1, glm::value_ptr(pointLightColor));
// 방향 광원의 위치, 색상을 셰이더에 전달
GLuint directLightDirLoc = glGetUniformLocation(programID, "directLightDir");
glUniform3fv(directLightDirLoc, 1, glm::value_ptr(directLightDir));
GLuint directLightColorLoc = glGetUniformLocation(programID, "directLightColor");
glUniform3fv(directLightColorLoc, 1, glm::value_ptr(directLightColor));
/**************************************************/
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
GLuint VBOs[3];
glGenBuffers(3, VBOs);
GLuint EBO[1];
glGenBuffers(1, EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);
GLuint posAttribLoc = glGetAttribLocation(programID, "inPos");
glVertexAttribPointer(posAttribLoc, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(0));
glEnableVertexAttribArray(posAttribLoc);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeColors), cubeColors, GL_STATIC_DRAW);
GLuint colorAttribLoc = glGetAttribLocation(programID, "inColor");
glVertexAttribPointer(colorAttribLoc, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(0));
glEnableVertexAttribArray(colorAttribLoc);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeNormals), cubeNormals, GL_STATIC_DRAW);
GLuint normalAttribLoc = glGetAttribLocation(programID, "inNormal");
glVertexAttribPointer(normalAttribLoc, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(0));
glEnableVertexAttribArray(normalAttribLoc);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, GL_STATIC_DRAW);
glutDisplayFunc(renderScene);
glutKeyboardFunc(translationKeyboard); // translate cube and point light
glutSpecialFunc(rotationKeyboard); // rotate cube and directional light
glutMouseFunc(ProjecionModeMouse); // switch projection mode
//enter GLUT event processing cycle
glutMainLoop();
glDeleteVertexArrays(1, &VertexArrayID);
return 1;
}
А это мой GVertexShader.txt:
Код: Выделить всё
#version 400 core
in vec3 inPos;
in vec4 inColor;
in vec3 inNormal;
out vec4 vColor;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;
uniform vec3 pointLightPos;
uniform vec3 pointLightColor;
uniform vec3 directLightDir;
uniform vec3 directLightColor;
void main()
{
vec4 vPos = vec4(inPos, 1.0);
vPos = proj * view * model * vPos;
vec3 tNormal = normalize(mat3(transpose(inverse(model))) * inNormal);
vec3 pointLightDir = normalize(pointLightPos - vPos.xyz);
float pointDiffuseStrength = max(dot(pointLightDir, tNormal), 0.0);
vec3 pointDiffuse = pointDiffuseStrength * pointLightColor;
float directDiffuseStrength = max(dot(-directLightDir, tNormal), 0.0);
vec3 directDiffuse = directDiffuseStrength * directLightColor;
vec3 reflectedLight = reflect(-pointLightDir, tNormal);
float specularStrength = pow(max(dot(reflectedLight, normalize(vec3(0, 0, 1))), 0.0), 1.0);
vec3 specular = specularStrength * vec3(1, 1, 1);
vColor = vec4(inColor.rgb * (pointDiffuse + directDiffuse) + specular, inColor.a);
gl_Position = vPos;
}
...и GFragmentShader.txt:
Код: Выделить всё
#version 400 core
in vec4 vColor;
out vec4 fColor;
void main()
{
fColor = vColor;
}
Может быть, я думаю, что есть какие-то проблемы с объявлением и формой точки (например, «pointLightPos», «directLightDir»)
Я пытаюсь напечатать pointLightPos. x при нажатии клавиши «o». тогда результатом будет случайное число.
Как показано ниже:
Код: Выделить всё
0
-1610612736
-1610612736
1073741824
-1610612736
0
1073741824
-2147483648
-1073741824
0
536870912
-1073741824
1610612736
0
-1610612736
1073741824
Помогите мне решить эту проблему.
Подробнее здесь:
https://stackoverflow.com/questions/785 ... ght-opengl
1717185229
Anonymous
Я намерен реализовать затенение по Гуро с двумя источниками света (точечный свет и направленный свет) Я хочу перевести точечный свет и повернуть направленный свет с помощью функции обратного вызова клавиатуры OpenGL. Но согласно моему текущему коду свет не движется. Это мой main.cpp: [code]#include #include #include #include #include #include #include #include #include #include #include // rotate(), scale(), translate() #include #include using namespace std; GLuint VertexArrayID; GLuint programID; GLint modelLoc; GLint viewLoc; GLint projLoc; float sx = 0; float sy = 0; float sz = 0; float translationStep = 0.1f; float rotationAngle = 0.0f; float rotationStep = 5.0f; bool projMode = true; // true: perspective, false: ortho GLint pointLightPosLoc; GLint pointLightColorLoc; GLuint directLightDirLoc; GLuint directLightColorLoc; glm::vec3 pointLightPos; glm::vec3 pointLightColor; glm::vec3 directLightDir; glm::vec3 directLightColor; GLfloat cubeVertices[] = { 0.1f, 0.1f, 0.1f, // v0 -0.1f, 0.1f, 0.1f, // v1 -0.1f, -0.1f, 0.1f, // v2 0.1f, -0.1f, 0.1f, // v3 0.1f, -0.1f, -0.1f, // v4 0.1f, 0.1f, -0.1f, // v5 -0.1f, 0.1f, -0.1f, // v6 -0.1f, -0.1f, -0.1f // v7 }; GLfloat cubeColors[] = { 1.0f, 0.0f, 0.0f, 1.0f, // Red 0.0f, 1.0f, 0.0f, 1.0f, // Green 0.0f, 0.0f, 1.0f, 1.0f, // Blue 1.0f, 1.0f, 0.0f, 1.0f, // Yellow 1.0f, 0.0f, 1.0f, 1.0f, // Magenta 0.0f, 1.0f, 1.0f, 1.0f, // Cyan }; GLint cubeIndices[] = { //front 0,1,2, 0,2,3, //right 0,3,4, 0,4,5, //up 0,1,6, 0,6,5, //left 1,2,7, 1,7,6, //down 3,7,4, 3,2,7, //back 5,7,6, 5,4,7, }; GLfloat cubeNormals[] = { 0.0f, 0.0f, 1.0f, // front 1.0f, 0.0f, 0.0f, // right 0.0f, 1.0f, 0.0f, // up -1.0f, 0.0f, 0.0f, // left 0.0f, -1.0f, 0.0f, // down 0.0f, 0.0f, -1.0f, // back }; GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) { //create the shaders GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); GLint Result = GL_FALSE; int InfoLogLength; //Read the vertex shader code from the file string VertexShaderCode; ifstream VertexShaderStream(vertex_file_path, ios::in); if (VertexShaderStream.is_open()) { string Line = ""; while (getline(VertexShaderStream, Line)) VertexShaderCode += "\n" + Line; VertexShaderStream.close(); } //Compile Vertex Shader char const* VertexSourcePointer = VertexShaderCode.c_str(); glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL); glCompileShader(VertexShaderID); printf("Compiling shader : %s\n", vertex_file_path); //Check Vertex Shader glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); if (InfoLogLength > 0) { vector VertexShaderErrorMessage(InfoLogLength); glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]); } //Read the fragment shader code from the file string FragmentShaderCode; ifstream FragmentShaderStream(fragment_file_path, ios::in); if (FragmentShaderStream.is_open()) { string Line = ""; while (getline(FragmentShaderStream, Line)) FragmentShaderCode += "\n" + Line; FragmentShaderStream.close(); } //Compile Fragment Shader char const* FragmentSourcePointer = FragmentShaderCode.c_str(); glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL); glCompileShader(FragmentShaderID); printf("Compiling shader : %s\n", fragment_file_path); //Check Fragment Shader glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); if (InfoLogLength > 0) { vector FragmentShaderErrorMessage(InfoLogLength); glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]); } //Link the program GLuint ProgramID = glCreateProgram(); glAttachShader(ProgramID, VertexShaderID); glAttachShader(ProgramID, FragmentShaderID); glLinkProgram(ProgramID); fprintf(stdout, "Linking program\n"); // Check the program glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); vector ProgramErrorMessage(max(InfoLogLength, int(1))); glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); fprintf(stdout, "%s\n", &ProgramErrorMessage[0]); glDeleteShader(VertexShaderID); glDeleteShader(FragmentShaderID); return ProgramID; } void renderScene(void) { //Clear all pixels glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Let's draw something here glBindVertexArray(VertexArrayID); //define the size of point and draw a point. int numCubes = 10; for (int i = 0; i < numCubes; i++) { glm::mat4 model = glm::mat4(1.0f); glm::vec3 translateVec(0.0f + sx, i * 0.3f + sy, 0.0f + sz); model = glm::translate(model, translateVec); glm::vec3 rotationAxis = glm::vec3(0.0f, 1.0f, 0.0f); model = glm::rotate(model, glm::radians(rotationAngle), rotationAxis); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glDrawElements(GL_TRIANGLES, sizeof(cubeIndices) / sizeof(GLint), GL_UNSIGNED_INT, 0); } //Double buffer glutSwapBuffers(); } void translationKeyboard(unsigned char key, int x, int y) { switch (key) { case 'q': sx += translationStep; break; case 'w': sx -= translationStep; break; case 'a': sy += translationStep; break; case 's': sy -= translationStep; break; case 'z': sz += translationStep; break; case 'x': sz -= translationStep; break; case 'o': printf("%d\n", pointLightPos.x); //temporary pointLightPos.x += translationStep; break; case 'p': pointLightPos.x -= translationStep; break; case 'k': pointLightPos.y += translationStep; break; case 'l': pointLightPos.y -= translationStep; break; case 'n': pointLightPos.z += translationStep; break; case 'm': pointLightPos.z -= translationStep; break; } glutPostRedisplay(); } void rotationKeyboard(int key, int x, int y) { switch (key) { case GLUT_KEY_LEFT: rotationAngle -= rotationStep; break; case GLUT_KEY_RIGHT: rotationAngle += rotationStep; break; case GLUT_KEY_UP: directLightDir.y += rotationStep; break; case GLUT_KEY_DOWN: directLightDir.y -= rotationStep; break; } glutPostRedisplay(); } void setProjectionMatrix() { glm::mat4 proj; int width = glutGet(GLUT_WINDOW_WIDTH); int height = glutGet(GLUT_WINDOW_HEIGHT); if (projMode) { // perspective projection proj = glm::perspective(glm::radians(45.0f), (float)width / (float)height, 0.1f, 100.0f); } else { // orthogonal projection proj = glm::ortho(-3.0f, 3.0f, -3.0f, 3.0f, -15.0f, 15.0f); } glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(proj)); } void ProjecionModeMouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { projMode = !projMode; setProjectionMatrix(); glutPostRedisplay(); } } void init() { //initilize the glew and check the errors. GLenum res = glewInit(); if (res != GLEW_OK) { fprintf(stderr, "Error: '%s' \n", glewGetErrorString(res)); } //select the background color glClearColor(1.0, 1.0, 1.0, 1.0); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glDepthRange(0.0f, 1.0f); } int main(int argc, char** argv) { //init GLUT and create Window //initialize the GLUT glutInit(&argc, argv); //GLUT_DOUBLE enables double buffering (drawing to a background buffer while the other buffer is displayed) glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); //These two functions are used to define the position and size of the window. glutInitWindowPosition(200, 200); glutInitWindowSize(480, 480); //This is used to define the name of the window. glutCreateWindow("Simple OpenGL Window"); //call initization function init(); //0. programID = LoadShaders("GVertexShader.txt", "GFragmentShader.txt"); glUseProgram(programID); /**************************************************/ // 모델, 뷰, 프로젝션 행렬을 셰이더에 전달 modelLoc = glGetUniformLocation(programID, "model"); viewLoc = glGetUniformLocation(programID, "view"); projLoc = glGetUniformLocation(programID, "proj"); // 뷰 행렬 설정 glm::vec3 cameraPosition(5.0f, 3.0f, 5.0f); // 카메라 위치 glm::vec3 targetPosition(2.0f, 2.0f, 2.0f); // 타겟(큐브) 위치 glm::vec3 upVector(0.0f, 1.0f, 0.0f); // 업 벡터 glm::mat4 view = glm::lookAt(cameraPosition, targetPosition, upVector); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); // 프로젝션 행렬 설정 setProjectionMatrix(); glm::vec3 pointLightPos(2.0f, 2.0f, 2.0f); glm::vec3 pointLightColor(1.0f, 1.0f, 1.0f); glm::vec3 directLightDir(-2.0f, -2.0f, -2.0f); glm::vec3 directLightColor(1.0f, 1.0f, 1.0f); // 점 광원의 위치, 색상을 셰이더에 전달 pointLightPosLoc = glGetUniformLocation(programID, "pointLightPos"); glUniform3fv(directLightDirLoc, 1, glm::value_ptr(directLightDir)); pointLightColorLoc = glGetUniformLocation(programID, "pointLightColor"); glUniform3fv(pointLightColorLoc, 1, glm::value_ptr(pointLightColor)); // 방향 광원의 위치, 색상을 셰이더에 전달 GLuint directLightDirLoc = glGetUniformLocation(programID, "directLightDir"); glUniform3fv(directLightDirLoc, 1, glm::value_ptr(directLightDir)); GLuint directLightColorLoc = glGetUniformLocation(programID, "directLightColor"); glUniform3fv(directLightColorLoc, 1, glm::value_ptr(directLightColor)); /**************************************************/ glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); GLuint VBOs[3]; glGenBuffers(3, VBOs); GLuint EBO[1]; glGenBuffers(1, EBO); glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); GLuint posAttribLoc = glGetAttribLocation(programID, "inPos"); glVertexAttribPointer(posAttribLoc, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(0)); glEnableVertexAttribArray(posAttribLoc); glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeColors), cubeColors, GL_STATIC_DRAW); GLuint colorAttribLoc = glGetAttribLocation(programID, "inColor"); glVertexAttribPointer(colorAttribLoc, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(0)); glEnableVertexAttribArray(colorAttribLoc); glBindBuffer(GL_ARRAY_BUFFER, VBOs[2]); glBufferData(GL_ARRAY_BUFFER, sizeof(cubeNormals), cubeNormals, GL_STATIC_DRAW); GLuint normalAttribLoc = glGetAttribLocation(programID, "inNormal"); glVertexAttribPointer(normalAttribLoc, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(0)); glEnableVertexAttribArray(normalAttribLoc); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO[0]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, GL_STATIC_DRAW); glutDisplayFunc(renderScene); glutKeyboardFunc(translationKeyboard); // translate cube and point light glutSpecialFunc(rotationKeyboard); // rotate cube and directional light glutMouseFunc(ProjecionModeMouse); // switch projection mode //enter GLUT event processing cycle glutMainLoop(); glDeleteVertexArrays(1, &VertexArrayID); return 1; } [/code] А это мой GVertexShader.txt: [code]#version 400 core in vec3 inPos; in vec4 inColor; in vec3 inNormal; out vec4 vColor; uniform mat4 model; uniform mat4 view; uniform mat4 proj; uniform vec3 pointLightPos; uniform vec3 pointLightColor; uniform vec3 directLightDir; uniform vec3 directLightColor; void main() { vec4 vPos = vec4(inPos, 1.0); vPos = proj * view * model * vPos; vec3 tNormal = normalize(mat3(transpose(inverse(model))) * inNormal); vec3 pointLightDir = normalize(pointLightPos - vPos.xyz); float pointDiffuseStrength = max(dot(pointLightDir, tNormal), 0.0); vec3 pointDiffuse = pointDiffuseStrength * pointLightColor; float directDiffuseStrength = max(dot(-directLightDir, tNormal), 0.0); vec3 directDiffuse = directDiffuseStrength * directLightColor; vec3 reflectedLight = reflect(-pointLightDir, tNormal); float specularStrength = pow(max(dot(reflectedLight, normalize(vec3(0, 0, 1))), 0.0), 1.0); vec3 specular = specularStrength * vec3(1, 1, 1); vColor = vec4(inColor.rgb * (pointDiffuse + directDiffuse) + specular, inColor.a); gl_Position = vPos; } [/code] ...и GFragmentShader.txt: [code]#version 400 core in vec4 vColor; out vec4 fColor; void main() { fColor = vColor; } [/code] Может быть, я думаю, что есть какие-то проблемы с объявлением и формой точки (например, «pointLightPos», «directLightDir») Я пытаюсь напечатать pointLightPos. x при нажатии клавиши «o». тогда результатом будет случайное число. Как показано ниже: [code]0 -1610612736 -1610612736 1073741824 -1610612736 0 1073741824 -2147483648 -1073741824 0 536870912 -1073741824 1610612736 0 -1610612736 1073741824 [/code] Помогите мне решить эту проблему. Подробнее здесь: [url]https://stackoverflow.com/questions/78561107/how-to-translate-point-light-and-rotate-directional-light-opengl[/url]