Я столкнулся с этой ошибкой при попытке использовать шейдер с базовым c треугольником с OpenGL. Он отображается только во время выполнения в консоли, когда я зарегистрировал данные, и не вызывает ошибки компиляции. LOG_ERROR в строке 35 шейдера. cpp - это то, что записывает ошибку. Я понятия не имею, как решить проблему.
шейдер. cpp
#include "engine_pch.h"
#include "shader.h"
#include "glad/glad.h"
namespace Engine {
Shader::Shader(const std::string& vertexSrc, const std::string& fragmentSrc)
{
// Create an empty vertex shader handle
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
// Send the vertex shader source code to GL
// Note that std::string's .c_str is NULL character terminated.
const GLchar* source = vertexSrc.c_str();
glShaderSource(vertexShader, 1, &source, 0);
// Compile the vertex shader
glCompileShader(vertexShader);
GLint isCompiled = 0;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> infoLog(maxLength);
glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]);
// We don't need the shader anymore.
glDeleteShader(vertexShader);
// Use the infoLog as you see fit.
LOG_ERROR("{0}", infoLog.data());
// In this simple program, we'll just leave
return;
}
// Create an empty fragment shader handle
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
// Send the fragment shader source code to GL
// Note that std::string's .c_str is NULL character terminated.
source = fragmentSrc.c_str();
glShaderSource(fragmentShader, 1, &source, 0);
// Compile the fragment shader
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> infoLog(maxLength);
glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]);
// We don't need the shader anymore.
glDeleteShader(fragmentShader);
// Either of them. Don't leak shaders.
glDeleteShader(vertexShader);
// Use the infoLog as you see fit.
LOG_ERROR("{0}", infoLog.data());
// In this simple program, we'll just leave
return;
}
// Vertex and fragment shaders are successfully compiled.
// Now time to link them together into a program.
// Get a program object.
m_renderingID = glCreateProgram();
GLuint program = m_renderingID;
// Attach our shaders to our program
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
// Link our program
glLinkProgram(program);
// Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked);
if (isLinked == GL_FALSE)
{
GLint maxLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> infoLog(maxLength);
glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
// We don't need the program anymore.
glDeleteProgram(program);
// Don't leak shaders either.
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// Use the infoLog as you see fit.
// In this simple program, we'll just leave
return;
}
// Always detach shaders after a successful link.
glDetachShader(program, vertexShader);
glDetachShader(program, fragmentShader);
}
Shader::~Shader()
{
glDeleteProgram(m_renderingID);
}
void Shader::bind() const
{
glUseProgram(m_renderingID);
}
void Shader::unbind() const
{
glUseProgram(0);
}
}
shader.h
#pragma once
#include <string>
namespace Engine {
class Shader {
public:
Shader(const std::string& vertexSrc, const std::string& fragmentSrc);
~Shader();
void bind() const;
void unbind() const;
private:
uint32_t m_renderingID;
};
}
приложение. cpp
/** \file application.cpp
*/
#include "engine_pch.h"
#pragma region TempIncludes
// temp includes
#include <glad/glad.h>
#include <gl/GL.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#pragma endregion TempIncludes
#include "core/application.h"
namespace Engine {
Application* Application::s_instance = nullptr;
std::shared_ptr<Timestep> frameTimer(new Timestep());
Application::Application()
{
if (s_instance == nullptr)
{
s_instance = this;
}
log::log();
m_window = std::unique_ptr<Window>(Window::create());
m_window->setEventCallback(std::bind(&Application::onEvent, this, std::placeholders::_1));
glGenVertexArrays(1, &m_vertexArray);
glBindVertexArray(m_vertexArray);
glGenBuffers(1, &m_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
float vertices[3 * 3] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
glGenBuffers(1, &m_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
unsigned int indices[3] = { 0, 1, 2 };
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
std::string vertexSrc = R"(
#version 440 core
layout(location = 0) in vec3 position;
void main(){
gl_Position = vec4(position + 0.3, 1.0);
)"
;
std::string fragmentSrc = R"(
#version 440 core
layout(location = 0) out vec4 colour;
void main(){
colour = vec4(1.0, 0.2, 1.0, 1.0);
)"
;
m_shader = std::make_unique<Shader>(Shader(vertexSrc, fragmentSrc));
}
Application::~Application()
{
}
void Application::run()
{
while (s_instance) {
glClearColor(0.8, 0.4, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
m_shader->bind();
glBindVertexArray(m_vertexArray);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
glm::vec2 a = InputPoller::getMousePosition();
float x = a.x;
float y = a.y;
LOG_INFO("{0}, {1}", x, y);
m_window->onUpdate();
}
}
void Application::onEvent(Event& e)
{
EventDispatcher dispatcher(e);
dispatcher.dispatch<WindowCloseEvent>(std::bind(&Application::onClose, this, std::placeholders::_1));
dispatcher.dispatch<WindowResizeEvent>(std::bind(&Application::onResize, this, std::placeholders::_1));
dispatcher.dispatch<KeyPressedEvent>(std::bind(&Application::onKeyPress, this, std::placeholders::_1));
}
bool Application::onClose(WindowCloseEvent & e)
{
LOG_INFO("Closing Application");
s_instance = false;
return true;
}
bool Application::onResize(WindowResizeEvent & e)
{
LOG_INFO("Resize window to {0} * {1}", e.GetWidth(), e.GetHeight());
return true;
}
bool Application::onKeyPress(KeyPressedEvent& e) {
LOG_INFO(e.getKeyCode());
return true;
}
}
application.h
/** \file application.h
*/
#pragma once
#include "systems/log.h"
#include "core/timestep.h"
#include "systems/events/keyEvent.h"
#include "systems/events/MouseEvent.h"
#include "systems/events/WindowEvent.h"
#include "windows/window.h"
#include "Platform/win/winWindow.h"
#include "core/keyCodes.h"
#include "core/mouseCodes.h"
#include "systems/events/InputPoller.h"
#include "Platform/OpenGL/shader.h"
#include <glm/glm.hpp>
namespace Engine {
/**
\class Application
Fundemental class of the engine. A singleton which runs the game loop infinitely.
Provides ...
*/
class Application
{
protected:
Application(); //!< Constructor
private:
static Application* s_instance; //!< Singleton instance of the application
std::unique_ptr<Window> m_window;
unsigned int m_vertexArray, m_vertexBuffer, m_indexBuffer;
std::unique_ptr<Shader> m_shader;
public:
virtual ~Application(); //!< Deconstructor
inline static Application& getInstance() { return *s_instance; } //!< Instance getter from singleton pattern
void run(); //!< Main loop
void onEvent(Event& e);
bool onClose(WindowCloseEvent& e);
bool onResize(WindowResizeEvent& e);
bool onKeyPress(KeyPressedEvent& e);
inline Window& getWindow() { return *m_window; }
};
// To be defined in users code
Application* startApplication(); //!< Function definition which provides an entry hook
}
РЕДАКТИРОВАТЬ: я понял, что код ошибки показывался из-за пропущенных '}' в основных функциях шейдеров. Однако теперь, даже если ошибка исчезла, шейдеры не влияют на мою визуализированную форму.