2017-05-18 10 views
-1

私はOpenGLを学ぶためにチュートリアルhereを勉強していますが、私はそれを行うべきではないコードで壁に当たっています。私はthisポイントまで、基本的な照明について学んでいます。私のコードは、影付きのキューブを表示していました。しかし、モデル行列を変更しようとしたとき、キューブが原点にあるかのように影が表示されました。モデルマトリックスは拡散シェーディングには影響しません

それがなかったことを確認するために私だけ、私は(ほとんど)チュートリアルで提供されたコードをコピーして、単一の行を追加:

model = glm::translate(model, glm::vec3(3.0, -1.0, 1.0)); 

を...とキューブが移動しますが、シェーディングが滞在しました同じ!どうして?

おそらく私が正しく理解していないコードの中に深刻なものがあるので、ここにコードとシェーダがあります。 (ここでも、それは主に鉱山ではありません) コード:

#include <string> 
#include <iostream> 
#include <cmath> 

#define GLEW_STATIC 
#include <GL/glew.h> 

#include <SOIL/SOIL.h> 
#include <GL/glew.h> 
#include <GLFW/glfw3.h> 

#include <glm/glm.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtc/type_ptr.hpp> 
#include <glm/gtx/projection.hpp> 

#include "Shader.h" 
#include "camera.h" 


// Function prototypes 
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); 
void mouse_callback(GLFWwindow* window, double xpos, double ypos); 
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); 
void do_movement(); 

// Window dimensions 
const GLuint WIDTH = 800, HEIGHT = 600; 

// Camera 
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); 
GLfloat lastX = WIDTH/2.0; 
GLfloat lastY = HEIGHT/2.0; 
bool keys[1024]; 

// Light attributes 
glm::vec3 lightPos(1.2f, 1.0f, 2.0f); 

// Deltatime 
GLfloat deltaTime = 0.0f; // Time between current frame and last frame 
GLfloat lastFrame = 0.0f; // Time of last frame 

// The MAIN function, from here we start the application and run the game loop 
int main() 
{ 
    // Init GLFW 
    glfwInit(); 
    // Set all the required options for GLFW 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); 

    // Create a GLFWwindow object that we can use for GLFW's functions 
    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); 
    glfwMakeContextCurrent(window); 

    // Set the required callback functions 
    glfwSetKeyCallback(window, key_callback); 
    glfwSetCursorPosCallback(window, mouse_callback); 
    glfwSetScrollCallback(window, scroll_callback); 

    // GLFW Options 
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); 

    // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions 
    glewExperimental = GL_TRUE; 
    // Initialize GLEW to setup the OpenGL Function pointers 
    glewInit(); 

    // Define the viewport dimensions 
    glViewport(0, 0, WIDTH, HEIGHT); 

    // OpenGL options 
    glEnable(GL_DEPTH_TEST); 


    // Build and compile our shader program 
    Shader* lightingShader = new Shader("lit_vertex_shader", "lit_fragment_shader"); 
    Shader* lampShader = new Shader("lamp_vertex_shader", "lamp_fragment_shader"); 


    // Set up vertex data (and buffer(s)) and attribute pointers 
    GLfloat vertices[] = { 
    -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 
    0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 
    0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 
    0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 
    -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 
    -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 

    -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 
    0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 
    0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 
    0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 
    -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 
    -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 

    -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 
    -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 
    -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 
    -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 
    -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 
    -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 

    0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 
    0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 
    0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 
    0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 
    0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 
    0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 

    -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 
    0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 
    0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 
    0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 
    -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 
    -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 

    -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 
    0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 
    0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 
    0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 
    -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 
    -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f 
    }; 
    // First, set the container's VAO (and VBO) 
    GLuint VBO, containerVAO; 
    glGenVertexArrays(1, &containerVAO); 
    glGenBuffers(1, &VBO); 

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

    glBindVertexArray(containerVAO); 
    // Position attribute 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); 
    glEnableVertexAttribArray(0); 
    // Normal attribute 
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); 
    glEnableVertexAttribArray(1); 
    glBindVertexArray(0); 

    // Then, we set the light's VAO (VBO stays the same. After all, the vertices are the same for the light object (also a 3D cube)) 
    GLuint lightVAO; 
    glGenVertexArrays(1, &lightVAO); 
    glBindVertexArray(lightVAO); 
    // We only need to bind to the VBO (to link it with glVertexAttribPointer), no need to fill it; the VBO's data already contains all we need. 
    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    // Set the vertex attributes (only position data for the lamp)) 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); // Note that we skip over the normal vectors 
    glEnableVertexAttribArray(0); 
    glBindVertexArray(0); 


    // Game loop 
    while (!glfwWindowShouldClose(window)) 
    { 
    // Calculate deltatime of current frame 
    GLfloat currentFrame = glfwGetTime(); 
    deltaTime = currentFrame - lastFrame; 
    lastFrame = currentFrame; 

    // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions 
    glfwPollEvents(); 
    do_movement(); 

    // Clear the colorbuffer 
    glClearColor(0.1f, 0.1f, 0.1f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // Use cooresponding shader when setting uniforms/drawing objects 
    lightingShader->Use(); 
    GLint objectColorLoc = glGetUniformLocation(lightingShader->getProgram(), "objectColor"); 
    GLint lightColorLoc = glGetUniformLocation(lightingShader->getProgram(), "lightColor"); 
    GLint lightPosLoc = glGetUniformLocation(lightingShader->getProgram(), "lightPos"); 
    glUniform3f(objectColorLoc, 1.0f, 0.5f, 0.31f); 
    glUniform3f(lightColorLoc, 1.0f, 1.0f, 1.0f); 
    glUniform3f(lightPosLoc, lightPos.x, lightPos.y, lightPos.z); 


    // Create camera transformations 
    glm::mat4 view; 
    view = camera.GetViewMatrix(); 
    glm::mat4 projection = glm::perspective(camera.Zoom, (GLfloat)WIDTH/(GLfloat)HEIGHT, 0.1f, 100.0f); 
    // Get the uniform locations 
    GLint modelLoc = glGetUniformLocation(lightingShader->getProgram(), "model"); 
    GLint viewLoc = glGetUniformLocation(lightingShader->getProgram(), "view"); 
    GLint projLoc = glGetUniformLocation(lightingShader->getProgram(), "projection"); 
    // Pass the matrices to the shader 
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); 
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); 

    // Draw the container (using container's vertex attributes) 
    glm::mat4 model; 
    //barring a few bits and pieces, following is the only changed line from the tutorial (I think) 
    model = glm::translate(model, glm::vec3(3.0, -1.0, 1.0)); 
    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); 
    glBindVertexArray(containerVAO); 
    glDrawArrays(GL_TRIANGLES, 0, 36); 
    glBindVertexArray(0); 

    // Also draw the lamp object, again binding the appropriate shader 
    lampShader->Use(); 
    // Get location objects for the matrices on the lamp shader (these could be different on a different shader) 
    modelLoc = glGetUniformLocation(lampShader->getProgram(), "model"); 
    viewLoc = glGetUniformLocation(lampShader->getProgram(), "view"); 
    projLoc = glGetUniformLocation(lampShader->getProgram(), "projection"); 
    // Set matrices 
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); 
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); 
    model = glm::mat4(); 
    model = glm::translate(model, lightPos); 
    model = glm::scale(model, glm::vec3(0.2f)); // Make it a smaller cube 
    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); 
    // Draw the light object (using light's vertex attributes) 
    glBindVertexArray(lightVAO); 
    glDrawArrays(GL_TRIANGLES, 0, 36); 
    glBindVertexArray(0); 

    // Swap the screen buffers 
    glfwSwapBuffers(window); 
    } 

    // Terminate GLFW, clearing any resources allocated by GLFW. 
    glfwTerminate(); 
    return 0; 
} 

// Is called whenever a key is pressed/released via GLFW 
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) 
{ 
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) 
    glfwSetWindowShouldClose(window, GL_TRUE); 
    if (key >= 0 && key < 1024) 
    { 
    if (action == GLFW_PRESS) 
     keys[key] = true; 
    else if (action == GLFW_RELEASE) 
     keys[key] = false; 
    } 
} 

void do_movement() 
{ 
    // Camera controls 
    if (keys[GLFW_KEY_W]) 
    camera.ProcessKeyboard(FORWARD, deltaTime); 
    if (keys[GLFW_KEY_S]) 
    camera.ProcessKeyboard(BACKWARD, deltaTime); 
    if (keys[GLFW_KEY_A]) 
    camera.ProcessKeyboard(LEFT, deltaTime); 
    if (keys[GLFW_KEY_D]) 
    camera.ProcessKeyboard(RIGHT, deltaTime); 
    if(keys[GLFW_KEY_SPACE]) { 
    if(keys[GLFW_KEY_LEFT_SHIFT] or keys[GLFW_KEY_RIGHT_SHIFT]) { 
     camera.ProcessKeyboard(DOWN, deltaTime); 
    } else { 
     camera.ProcessKeyboard(UP, deltaTime); 
    } 
    } 
} 

bool firstMouse = true; 
void mouse_callback(GLFWwindow* window, double xpos, double ypos) 
{ 
    if (firstMouse) 
    { 
    lastX = xpos; 
    lastY = ypos; 
    firstMouse = false; 
    } 

    GLfloat xoffset = xpos - lastX; 
    GLfloat yoffset = lastY - ypos; // Reversed since y-coordinates go from bottom to left 

    lastX = xpos; 
    lastY = ypos; 

    camera.ProcessMouseMovement(xoffset, yoffset); 
} 

void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) 
{ 
    camera.ProcessMouseScroll(yoffset); 
} 

バーテックスシェーダ:

#version 330 core 

layout (location = 0) in vec3 position; 
layout (location = 1) in vec3 normal; 

out vec3 Normal; 
out vec3 FragPos; 

uniform mat4 model; 
uniform mat4 view; 
uniform mat4 projection; 

void main() 
{ 
    gl_Position = projection * view * model * vec4(position, 1.0f); 
    vec3 fragPos = vec3(model*vec4(position, 1.0f)); 
    Normal = mat3(transpose(inverse(model)))*normal; 
} 

フラグメントシェーダ:

#version 330 core 

in vec3 Normal; 
in vec3 FragPos; 

out vec4 color; 

uniform vec3 objectColor; 
uniform vec3 lightColor; 
uniform vec3 lightPos; 

void main() 
{ 

    vec3 norm = normalize(Normal); 
    vec3 lightDir = normalize(lightPos - FragPos); 
    float diff = max(dot(norm, lightDir), 0.0); 
    vec3 diffuse = diff * lightColor; 
    float ambi = 0.05; 
    vec3 ambient = ambi * lightColor; 
    color = vec4((diffuse + ambient) * objectColor, 1.0); 
} 
+0

翻訳は、指向性の光源からの影を変更しません。 – dari

+0

@ダリなぜですか?それが光源の左側にあったら、今度は右側にあるので、立方体の異なる辺を陰にする必要があります。 – CalvinSchwa

+0

あなたのコードを見てみると、シェーダの 'lightPos'がモデル空間にあると予想されるように、つまりモデルに対して相対的であるように見えます。それが同じように見える理由です。あなたは世界の空間にlightPosを持っています。シェーダに渡す前に、C++コードのモデル行列の逆行列で変換する必要があります。チュートリアルに従っているなら、私はあなたに行くことをお勧めします、そして、彼らはたぶん、ある時点でこれを行う方法に行くでしょう。 – dbandstra

答えて

0

私はしばらく前にそれを考え出したが、されていましたそれはおそらく他の誰にとっても役に立たないので、答えを出すことをためらっている。それは数時間かかりました(!)、しかしここにあります。 (私はすでに上記のコメントで述べたタイプミスを修正していたことに注意してください。FragPosが正しく大文字されています。)

#version 330 core 
layout (location = 0) in vec3 position; 
layout (location = 1) in vec3 normal; 

out vec3 Normal; 
out vec3 FragPos; 

uniform mat4 model; 
uniform mat4 view; 
uniform mat4 projection; 

void main() 
{ 
    gl_Position = projection * view * model * vec4(position, 1.0f); 
    vec3 FragPos = vec3(model*vec4(position, 1.0f)); 
    Normal = mat3(transpose(inverse(model)))*normal; 
} 

は何も悪いことを参照してください?いいえ? ...ええ、それはFragPosを独自のローカル変数として再宣言しています。少なくとも私はそう思う。いずれにせよ、vec3 FragPos = ...FragPos = ...に変更してください。 FragPosが常に0であることを明らかにするには、かなり動くものではなかったので、他のすべての「修正」はうまくいくように見えました。

とにかくdbandstraに助けてくれてありがとう。

関連する問題