【发布时间】: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