【问题标题】:OpenGl does not render MeshOpenGL 不渲染网格
【发布时间】:2021-10-30 02:55:41
【问题描述】:

我尝试将我的 OpenGL 代码抽象到类中,到目前为止效果很好。它会一直呈现,直到我最近构建了一个 Game 类,它是 Window2 类的派生类(我也是最近才创建的)。 我很确定在 Mesh、Shader、PointLight 或 Material 类中找不到该错误(因为它们在过去正常工作)。 该窗口确实出现并且具有正确的背景颜色。在游戏循环中也调用了渲染函数,所以我不确定问题是什么。这是代码...

Game.h

#ifndef GAME_H
#define GAME_H


#include <iostream>
#include <stdio.h>
#include <vector>
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>

#include "GameBlock.h"
#include "blocks/NormalGameBlock.h"
#include <PointLight.h>
#include <Window2.h>
#include <memory>
#include <Renderer.h>
#include <Mesh.h>
#include <Shader.h>
#include <Material.h>
#include <Utils.h>

class Game : private Window2 {
private:


    Mesh* mesh;
    Shader* shader;
    Material* material;

    PointLight* pointLight;

    glm::mat4 projection;
    glm::vec3 viewPosition;
    glm::mat4 view;

public:
    Game();
    ~Game();
    void initialize();
    void start();
    void stop();

    // override the functions provided by base class Window2
    void input(Keys k) override;
    void update() override;
    void render() override;
};

#endif

Game.cpp

#include "Game.h"

Game::Game()
    :
    Window2((int)(1080 * 0.7f), (int)(1920 * 0.7f), "Game", false)
{
    PRINT_FUNC;
    pointLight = new PointLight
    (
        glm::vec3(0.0, 0.0, 1.0),
        glm::vec3(1.0, 1.0, 1.0) * 0.0f,
        glm::vec3(1.0, 1.0, 1.0) * 0.3f,
        glm::vec3(1.0, 1.0, 1.0) * 1.0f,
        1.0f,
        0.01f,
        0.01f
    );

    material = new Material
    (
        glm::vec3(0.0f, 0.0f, 1.0f) * 1.0f,
        glm::vec3(0.0f, 0.0f, 1.0f) * 1.0f,
        glm::vec3(0.0f, 0.0f, 1.0f) * 1.0f,
        1.0f,
        256.0f,
        1.0f
    );
}

Game::~Game() {
    PRINT_FUNC;
    delete mesh;
    delete shader;
    delete material;
    delete pointLight;
}

void Game::initialize() {
    PRINT_FUNC;

    Window2::intitialize2();

    mesh = new Mesh(Mesh::loadVertices("assets/box2.obj", false));
    shader = new Shader("shaders/vertex_shader copy.glsl", "shaders/fragment_shader copy.glsl");

    projection = glm::perspective(glm::radians(35.0f), 9.0f / 16.0f, 0.1f, 1000.0f);
    viewPosition = glm::vec3(0, 1, 0);
    view = glm::lookAt(
        viewPosition,          // Camera is at (4,3,3), in World Space
        glm::vec3(0, 0, 0),    // and looks at the origin
        glm::vec3(0, 1, 0)     // Head is up (set to 0,-1,0 to look upside-down)
    );

    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

}

void Game::start() {
    run();
}

void Game::stop() {
    close();
}

void Game::input(Keys k) {

}

void Game::update() {

}

void Game::render() {

    shader->activate();
    shader->setMat4("P", projection);
    shader->setMat4("V", view);
    shader->setVec3("viewPos", viewPosition);

    Renderer::render(mesh, shader, material, pointLight);

}

Window2.h

#ifndef WINDOW_2_H
#define WINDOW_2_H

#define GLEW_STATIC

#include <GL/glew.h> // include GLEW and new version of GL on Windows
#include <glfw3.h>   // GLFW helper library

#include <iostream>

struct Keys {
    bool W, A, S, D;
    bool Left, Right, Up, Down;
    bool N0, N1, N2, N3, N4, N5, N6, N7, N8, N9;
    bool Space, Esc;
    bool Shift;
};

class Window2 {
private:

    GLFWmonitor* m_monitor;

    unsigned int m_width;
    unsigned int m_height;
    int m_posX;
    int m_posY;
    const char* m_title;
    const bool m_fullscreen;

    float aspectRatio;

public:

    GLFWwindow* m_window;

    Window2(unsigned int width, unsigned int height, const char* title, const bool fullscreen);
    ~Window2();

    void intitialize2();

    void run();

    void close();

    // override functions
    virtual void input(Keys k);

    virtual void update();

    virtual void render();

    void setResizeCallback(void(*ptr)(GLFWwindow*, int, int));

    void setSize(int width, int height);

    float getAspectRatio();

    void makeCurrent() const;

    // clear window
    void clear(float r, float g, float b);

    // swap
    void swap();

    // poll events
    void poll();

    // get time in milliseconds
    static unsigned int getTimeMS();
};

#endif

Window2.cpp

#include "Window2.h"

#include <iostream>
#include <chrono>
#include <Utils.h>

Window2::Window2
(
    unsigned int width,
    unsigned int height,
    const char* title,
    const bool fullscreen
)
    :
    m_width(width),
    m_height(height),
    m_title(title),
    m_fullscreen(fullscreen)
{
    PRINT_FUNC;
}

Window2::~Window2() {
    PRINT_FUNC;
    glfwDestroyWindow(m_window);
}

void Window2::intitialize2() {
    PRINT_FUNC;
    if (!glfwInit())
    {
        fprintf(stderr, "ERROR: could not start GLFW3\n");
        return;
    }

    const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    m_width = m_fullscreen ? mode->width : m_width;
    m_height = m_fullscreen ? mode->height : m_height;
    aspectRatio = (float)m_width / (float)m_height;
    m_window = glfwCreateWindow(m_width, m_height, m_title, m_fullscreen ? glfwGetPrimaryMonitor() : NULL, NULL);
    if (!m_window) {
        fprintf(stderr, "ERROR: could not open Window2 with GLFW3\n");
        glfwTerminate();
        return;
    }
    glfwMakeContextCurrent(m_window);

    // start GLEW extension handler
    glewExperimental = GL_TRUE;
    glewInit();

    //setSize(m_width, m_height);

    // get version info
    const GLubyte* renderer = glGetString(GL_RENDERER);
    const GLubyte* version = glGetString(GL_VERSION);
    printf("Renderer: %s\n", renderer);
    printf("OpenGL version supported %s\n\n", version);
}

void Window2::run() {

    PRINT_FUNC;

    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    unsigned int previous = getTimeMS();
    unsigned int lag = 0;
    const unsigned int msPerUpdate = 1000 / 60;

    while (!glfwWindowShouldClose(m_window)) {

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0.8, 0.8, 0.8, 1);

        unsigned int current = getTimeMS();
        unsigned int elapsed = current - previous;
        previous = current;
        lag += elapsed;

        const Keys k{
            glfwGetKey(m_window, GLFW_KEY_W) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_A) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_S) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_D) == GLFW_PRESS,

            glfwGetKey(m_window, GLFW_KEY_LEFT) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_RIGHT) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_UP) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_DOWN) == GLFW_PRESS,

            glfwGetKey(m_window, GLFW_KEY_0) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_1) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_2) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_3) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_4) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_5) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_6) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_7) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_8) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_9) == GLFW_PRESS,

            glfwGetKey(m_window, GLFW_KEY_SPACE) == GLFW_PRESS,
            glfwGetKey(m_window, GLFW_KEY_ESCAPE) == GLFW_PRESS,

            glfwGetKey(m_window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS
        };

        //input
        input(k);

        while (lag >= msPerUpdate)
        {
            // update
            update();

            lag -= msPerUpdate;
        }

        // render
        render();

        glfwSwapBuffers(m_window);
        glfwPollEvents();
    }
}

void Window2::input(Keys k) {

}

void Window2::update() {

}

void Window2::render() {

}

void Window2::close() {
    glfwSetWindowShouldClose(m_window, GLFW_TRUE);
}

void Window2::setSize(int width, int height) {
    m_width = width;
    m_height = height;
    aspectRatio = (float)m_width / (float)m_height;
    glViewport(0, 0, width, height);
}

void Window2::setResizeCallback(void(*ptr)(GLFWwindow*, int, int)) {
    glfwSetWindowSizeCallback(m_window, ptr);
}

void Window2::makeCurrent() const {
    glfwMakeContextCurrent(m_window);
}

float Window2::getAspectRatio() {
    return aspectRatio;
}

unsigned int Window2::getTimeMS() {
    std::chrono::milliseconds mt = std::chrono::duration_cast<std::chrono::milliseconds> (std::chrono::system_clock::now().time_since_epoch());
    return mt.count();
}

这是在 Main.cpp 中创建类的方式:

int main(int argc, char* argv[])
{

  Game game;
  game.initialize();
  game.start();

  glfwTerminate();
  return 0;
}

【问题讨论】:

    标签: c++ c++11 opengl glfw glm-math


    【解决方案1】:

    只是猜测,我希望您在glfwInit() 之后设置 OpenGL 的版本。比如设置为3.3,我用的是4.6:

        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    

    一般的渲染例程如下所示。检查 glUseProgram 在哪里以及是否在某处被调用,以及是否被调用:

        glUseProgram(progId);
        glBindVertexArray(vao); //vertex array object here, (not vertex buffer object)
        glDrawXXX(GL_XXX, args); //for instance glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 3);
    

    我想着色器已编译并且程序已成功链接。到目前为止,很难从提供的代码中猜测出来。其他猜测可能会丢失一些转换,或者在绘制之前丢失任何绑定。 MVP 转换可能会因为一个小错误而将对象发送到窗口之外。将 GL 例程转换为 OOP 应该分小步完成。它的实现方式确实显示了对它的理解程度。

    【讨论】:

    • 感谢您的回答@armagedescu。它工作正常,无需提供之前的版本。我也相信问题不在于事件的顺序(如绑定缓冲区......),因为我已经在代码中使用 PRINT_FUNC 宏看到了这一点。
    猜你喜欢
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    • 2018-02-11
    • 2012-06-13
    • 2018-09-02
    • 2011-10-22
    • 1970-01-01
    相关资源
    最近更新 更多