c++ - 使用 glOrtho() 时 gluLookAt() 不起作用?

标签 c++ opengl glfw glu

我想使用 gluLookAt() 移动我的相机,以便我可以看到整个网格(在代码中是一个立方体)。

我在游戏循环中设置了 ModelView 矩阵。更改 glLookAt()gluPerspective() 对最终图像没有任何影响。我不断收到下面的图片。

我已经尝试使用 glOrtho() 但它仍然无法正常工作...

这个问题是来自着色器,还是其他绘图代码?

enter image description here

#include <GLFW/glfw3.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>

#include <iostream>
#include <fstream>

int window_width = 800, window_height = 600;

GLuint loadShader(const char *vs_path, const char *fs_path);
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";
const char *fragmentShaderSource = "#version 330 core\n"
                                   "out vec4 FragColor;\n"
                                   "void main()\n"
                                   "{\n"
                                   "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
                                   "}\n\0";

int main() {
    if (!glfwInit())
        return -1;
    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);
    GLFWwindow* window;
    window = glfwCreateWindow(window_width, window_height, "Hello World", NULL, NULL);
    if (!window) {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // check for shader compile errors
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // fragment shader
    int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    // check for shader compile errors
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // link shaders
    int shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    // check for linking errors
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    float vertices[] = {
            -1, 0.0,  0.0,
            -1, 0.0,  1.0,
            -1,  1.0,  0.0,
            -1,  1.0,  1.0,
            1.0,  0.0,  0.0,
            1.0,  0.0,  1.0,
            1.0,  1.0,  0.0,
            1.0,  1.0,  1.0,
    };
    unsigned int indices[] = {
            0, 6, 4,
            0, 2, 6,
            0, 3, 2,
            0, 1, 3,
            2, 7, 6,
            2, 3, 7,
            4, 6, 7,
            4, 7, 5,
            0, 4, 5,
            0, 5, 1,
            1, 5, 7,
            1, 7, 3,
    };

    unsigned int VBO, VAO, EBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);
    glBindVertexArray(VAO);

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

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

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

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    while (!glfwWindowShouldClose(window)) {
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        gluLookAt(
                0, 0, 10,
                0, 0, 0,
                0, 1, 0);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-10, 10, -10, 10, 0.1, 10);
        glViewport(0, 0, window_width, window_height);

        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
        //glDrawArrays(GL_TRIANGLES, 0, 6);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        // glBindVertexArray(0); // no need to unbind it every time

        glfwSwapBuffers(window);
        glfwPollEvents();
    }


    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;

}

GLuint loadShader(const char *vs_path, const char *fs_path) {
    GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    std::string vsCode;
    std::ifstream vsStream(vs_path, std::ios::in);
    if (vsStream.is_open()) {
        std::string line;
        while (std::getline(vsStream, line)) {
            vsCode += line + "\n";
        }
        vsStream.close();
    } else {
        std::cerr << "ERROR::GUI::LOAD_SHADER::VERTEX::FILE_OPEN_FAILED\n" << std::endl;
        exit(-1);
    }

    std::string fsCode;
    std::ifstream fsStream(fs_path, std::ios::in);
    if (fsStream.is_open()) {
        std::string line;
        while (std::getline(fsStream, line)) {
            fsCode += line + "\n";
        }
        fsStream.close();
    } else {
        std::cerr << "ERROR::GUI::LOAD_SHADER::FRAGMENT::FILE_OPEN_FAILED\n" << std::endl;
        exit(-1);
    }

    int success;
    char info[1024];

    const char *vs = vsCode.c_str();
    glShaderSource(vertexShaderID, 1, &vs, NULL);
    glCompileShader(vertexShaderID);
    glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(vertexShaderID, 1024, NULL, info);
        std::cerr << "ERROR::GUI::LOAD_SHADER::VERTEX::COMPILATION_FAILED\n" << info << std::endl;
    }

    const char *fs = fsCode.c_str();
    glShaderSource(fragmentShaderID, 1, &fs, NULL);
    glCompileShader(fragmentShaderID);
    glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(fragmentShaderID, 1024, NULL, info);
        std::cerr << "ERROR::GUI::LOAD_SHADER::FRAGMENT::COMPILATION_FAILED\n" << info << std::endl;
    }

    GLuint programID = glCreateProgram();
    glAttachShader(programID, vertexShaderID);
    glAttachShader(programID, fragmentShaderID);

    glLinkProgram(programID);
    glGetProgramiv(programID, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(programID, 1024, NULL, info);
        std::cerr << "ERROR::GUI::LOAD_SHADER::PROGRAM::LINKING_FAILED\n" << info << std::endl;
    }

    glDetachShader(programID, vertexShaderID);
    glDetachShader(programID, fragmentShaderID);
    glDeleteShader(vertexShaderID);
    glDeleteShader(fragmentShaderID);
}

最佳答案

固定函数矩阵堆栈已弃用。参见 Fixed Function PipelineLegacy OpenGL .

当您使用核心配置文件时

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

那么就不能使用固定函数矩阵栈了。

使用Uniform变量。使用投影矩阵统一 (u_proj) 和 View 矩阵统一 (u_view) 创建着色器程序:

#version 330 core

layout (location = 0) in vec3 aPos;

uniform mat4 u_proj;
uniform mat4 u_view;

void main()
{
    gl_Position = u_proj * u_view * vec4(aPos.xyz, 1.0);
}

获取着色器程序链接后统一变量的位置:

 glLinkProgram(shaderProgram);

 GLint projLoc = glGetUniformLocation(shaderProgram, "u_proj");
 GLint viewLoc = glGetUniformLocation(shaderProgram, "u_view");

使用类似 OpenGL Mathematics (GLM) 的库, 初始化投影矩阵和 View 矩阵:

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
glm::mat4 proj = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 10.0f);
glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 5.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

安装程序后设置统一变量的值:

glUseProgram(shaderProgram);

glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(proj));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));

关于c++ - 使用 glOrtho() 时 gluLookAt() 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54192428/

相关文章:

c++ - cppcheck 认为我有 "Redundant code: Found a statement that begins with numeric constant"

opengl - 将spirv与OpenGL一起使用,gl_VertexIndex始终为0

opengl - 绑定(bind)2个纹理,只看到1个

c++ - 解析带有分隔符空格但字符串也包含空格的字符串?

c++ - 将文件扩展名从 c 更改为 cpp 后,如何解决 C++ 中的歧义错误?

qt - 在 QGLWidget 上使用 QPainter 时需要执行哪些步骤才能启用抗锯齿功能?

java - 为什么LWJGL(OpenGL)drawElements不绘制?

c++ - 无法让 GLFW 链接

C OpenGL glfw3 三角形不显示

c++ - 矩阵 37x37 的行列式