2017-06-26 55 views
0

我在跟着this tutorial series一起關注,但也試圖在我走的時候自定義我的解決方案(基本上我試圖渲染一個3D點雲 - 即一堆XYZ點) 。OpenGL/GLFW - 滾輪沒有響應

我已經能夠獲得相機的工作和3D環境。我很樂意自己處理剩下的問題,但是我遇到的問題是滾輪沒有響應。我希望這對某人來說是非常明顯的。似乎只有用戶回調程序正在獲得的是鼠標位置 - 100%的時間 - 這是防止scroll_callback函數形式被聽到。有人可以解釋爲什麼我的滾輪迴調沒有收到。下面的代碼。

讓我知道是否需要任何進一步的信息。

我正在使用Visual Studio 2017社區。

#include <glad/glad.h> 
#include <GLFW/glfw3.h> 

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

#include <Shader.h> 

#include <iostream> 


void framebuffer_size_callback(GLFWwindow* window, int width, int height); 
void mouse_callback(GLFWwindow* window, double xpos, double ypos); 
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); 
void processInput(GLFWwindow *window); 

// settings 
const unsigned int SCR_WIDTH = 800; 
const unsigned int SCR_HEIGHT = 800; 

// camera 
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f); 
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f); 
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f); 

bool firstMouse = true; 
float yaw = -90.0f; // yaw is initialized to -90.0 degrees since a yaw of 0.0 results in a direction vector pointing to the right so we initially rotate a bit to the left. 
float pitch = 0.0f; 
float lastX = 800.0f/2.0; 
float lastY = 600.0/2.0; 
float fov = 45.0f; 

// timing 
float deltaTime = 0.0f; // time between current frame and last frame 
float lastFrame = 0.0f; 


int main() 
{ 
    // glfw: initialize and configure 
    // ------------------------------ 
    glfwInit(); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 
    //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X 

    // glfw window creation 
    // -------------------- 
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); 
    if (window == NULL) 
    { 
     std::cout << "Failed to create GLFW window" << std::endl; 
     glfwTerminate(); 
     return -1; 
    } 
    glfwMakeContextCurrent(window); 
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); 
    glfwSetCursorPosCallback(window, mouse_callback); 
    glfwSetScrollCallback(window, scroll_callback); 

    // tell GLFW to capture our mouse 
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); 

    // glad: load all OpenGL function pointers 
    // --------------------------------------- 
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) 
    { 
     std::cout << "Failed to initialize GLAD" << std::endl; 
     return -1; 
    } 


    // configure global opengl state 
    // ----------------------------- 
    glEnable(GL_DEPTH_TEST); 

    Shader ourShader("VertexShader.vs", "FragShader.fs"); 




// set up vertex data (and buffer(s)) and configure vertex attributes 
// ------------------------------------------------------------------ 
float vertices[] = { 
    -0.5f, -0.5f, 0.0f, // left 
    0.5f, -0.5f, 0.0f, // right 
    0.0f, 0.5f, 0.0f // top 
}; 

struct Point 
{ 
    float x; 
    float y; 
    float z; 
}; 

Point points[500]; 


for (int i = 0; i < 500; i++) 
{ 
    points[i].x = (float)((rand() % SCR_WIDTH) + 1); 
    points[i].y = (float)((rand() % SCR_WIDTH) + 1); 
    points[i].z = (float)((rand() % SCR_WIDTH) + 1); 

    // X Coords to Normalised Device coordinates 
    if (points[i].x > 400) 
    { 
     points[i].x = points[i].x * 0.00125f; 
    } 
    else if (points[i].x < 400) 
    { 
     points[i].x = points[i].x * -0.00125f; 
    } 
    else if (points[i].x == 400) 
    { 
     points[i].x = 0.0f; 
    } 

    // Y Coords to Normalised Device coordinates 
    if (points[i].y > 400) 
    { 
     points[i].y = points[i].y * 0.00125f; 
    } 
    else if (points[i].y < 400) 
    { 
     points[i].y = points[i].y * -0.00125f; 
    } 
    else if (points[i].y == 400) 
    { 
     points[i].y = 0.0f; 
    } 

    // Z Coords to Normalised Device coordinates 
    if (points[i].z > 400) 
    { 
     points[i].z = points[i].z * 0.00125f; 
    } 
    else if (points[i].z < 400) 
    { 
     points[i].z = points[i].z * -0.00125f; 
    } 
    else if (points[i].z == 400) 
    { 
     points[i].z = 0.0f; 
    } 

    //cout << points[i].x << ", " << points[i].y << ", " << points[i].z << endl; 
} 

unsigned int VBO, VAO; 
glGenVertexArrays(1, &VAO); 
glGenBuffers(1, &VBO); 
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). 
glBindVertexArray(VAO); 

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

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

// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind 
glBindBuffer(GL_ARRAY_BUFFER, 0); 

// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other 
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. 
glBindVertexArray(0); 


// uncomment this call to draw in wireframe polygons. 
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 

// render loop 
// ----------- 
while (!glfwWindowShouldClose(window)) 
{ 
    // input 
    // ----- 
    processInput(window); 

    // render 
    // ------ 
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // activate shader 
    ourShader.use(); 

    // create transformations 
    glm::mat4 projection; 
    projection = glm::perspective(glm::radians(95.0f), (float)SCR_WIDTH/(float)SCR_HEIGHT, 0.1f, 100.0f); 
    ourShader.setMat4("projection", projection); // note: currently we set the projection matrix each frame, but since the projection matrix rarely changes it's often best practice to set it outside the main loop only once. 

    // camera/view transformation 
    glm::mat4 view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); 
    ourShader.setMat4("view", view); 

    glm::mat4 model; 
    model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f)); 
    ourShader.setMat4("model", model); 


    // draw our points array 
    //glUseProgram(shaderProgram); 
    glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized 
    glPointSize(3.0f); 
    glDrawArrays(GL_POINTS, 0, 500); 
    // glBindVertexArray(0); // no need to unbind it every time 

    // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) 
    // ------------------------------------------------------------------------------- 
    glfwSwapBuffers(window); 
    glfwPollEvents(); 
} 

// optional: de-allocate all resources once they've outlived their purpose: 
// ------------------------------------------------------------------------ 
glDeleteVertexArrays(1, &VAO); 
glDeleteBuffers(1, &VBO); 

// glfw: terminate, clearing all previously allocated GLFW resources. 
// ------------------------------------------------------------------ 
glfwTerminate(); 
return 0; 
} 

// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly 
// --------------------------------------------------------------------------------------------------------- 
void processInput(GLFWwindow *window) 
{ 
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) 
     glfwSetWindowShouldClose(window, true); 

    float cameraSpeed = 2.5 * deltaTime; 
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) 
     cameraPos += cameraSpeed * cameraFront; 
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) 
     cameraPos -= cameraSpeed * cameraFront; 
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) 
     cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; 
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) 
     cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed; 
} 

// glfw: whenever the window size changed (by OS or user resize) this callback function executes 
// --------------------------------------------------------------------------------------------- 
void framebuffer_size_callback(GLFWwindow* window, int width, int height) 
{ 
    // make sure the viewport matches the new window dimensions; note that width and 
    // height will be significantly larger than specified on retina displays. 
    glViewport(0, 0, width, height); 
} 

// glfw: whenever the mouse moves, this callback is called 
// ------------------------------------------------------- 
void mouse_callback(GLFWwindow* window, double xpos, double ypos) 
{ 
    if (firstMouse) 
    { 
     lastX = xpos; 
     lastY = ypos; 
     firstMouse = false; 
    } 

    float xoffset = xpos - lastX; 
    float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top 
    lastX = xpos; 
    lastY = ypos; 

    float sensitivity = 0.1f; // change this value to your liking 
    xoffset *= sensitivity; 
    yoffset *= sensitivity; 

    yaw += xoffset; 
    pitch += yoffset; 

    // make sure that when pitch is out of bounds, screen doesn't get flipped 
    if (pitch > 89.0f) 
     pitch = 89.0f; 
    if (pitch < -89.0f) 
     pitch = -89.0f; 

    glm::vec3 front; 
    front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch)); 
    front.y = sin(glm::radians(pitch)); 
    front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch)); 
    cameraFront = glm::normalize(front); 
} 

// glfw: whenever the mouse scroll wheel scrolls, this callback is called 
// ---------------------------------------------------------------------- 
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) 
{ 
    if (fov >= 1.0f && fov <= 45.0f) 
     fov -= yoffset; 
    if (fov <= 1.0f) 
     fov = 1.0f; 
    if (fov >= 45.0f) 
     fov = 45.0f; 
} 
+1

這將是一個GLFW問題,而不是OpenGL問題。 – immibis

回答

1

你要捂臉一點:

projection = glm::perspective(glm::radians(95.0f), (float)SCR_WIDTH/(float)SCR_HEIGHT, 0.1f, 100.0f); 

應該是:

projection = glm::perspective(glm::radians(fov), (float)SCR_WIDTH/(float)SCR_HEIGHT, 0.1f, 100.0f); 

我跑你的代碼在調試器和滾動回調函數運行每次但fov價值從未被使用。如果您想通過在函數中的任意位置添加斷點來檢查函數是否正在調用,則可以使用相同的技巧。

+2

**史詩般的facepalm ** – TheLastGIS