GLFW是一个免费的开源多平台库,用于打开窗口,创建OpenGL上下文和管理输入。它很容易集成到现有的应用程序中,并没有声称主循环。 GLFW是用C语言编写的,并且对Windows,Mac OS X以及使用X Window系统的许多类Unix系统(例如Linux和FreeBSD)提供原生支持。 GLFW根据zlib / libpng许可证授权。
无法编译Cmake项目外部库(使用GLWF(OpenGL))
我正在尝试编译一个项目来开始学习OpenGl,但是我不能。 当我运行 CMake -G "Unix Makefiles" .. 它会在没有任何警告的情况下生成 MakeFile。 运行 Make 时,它无法
C++ GLSL 着色器:“错误:不支持 GLSL 3.30。支持的版本有:1.10、1.20、1.30、1.00 ES 和 3.00 ES”或黑窗
我在我的简单 OpenGL 项目中添加了非常简单的 GLSL 着色器,但它无法正常工作。 #包括 #包括 #包括 #包括 我在简单的 OpenGL 项目中添加了非常简单的 GLSL 着色器,但它无法正常工作。 #include <python3.6m/Python.h> #include <iostream> #include <GL/glew.h> #include <GLFW/glfw3.h> #include <glm/glm.hpp> #include <vector> #include <fstream> #include <sstream> using namespace glm; GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path){ // Создаем шейдеры GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); // Загружаем код Вершинного Шейдера из файла std::string VertexShaderCode; std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); if (VertexShaderStream.is_open()) { std::stringstream sstr; sstr << VertexShaderStream.rdbuf(); VertexShaderCode = sstr.str(); VertexShaderStream.close(); } // Загружаем код Фрагментного шейдера из файла std::string FragmentShaderCode; std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); if (FragmentShaderStream.is_open()){ std::stringstream sstr; sstr << FragmentShaderStream.rdbuf(); FragmentShaderCode = sstr.str(); FragmentShaderStream.close(); } GLint Result = GL_FALSE; int InfoLogLength; // Компилируем Вершинный шейдер printf("Компиляция шейдера: %s\n", vertex_file_path); char const * VertexSourcePointer = VertexShaderCode.c_str(); glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); glCompileShader(VertexShaderID); // Выполняем проверку Вершинного шейдера glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); if ( InfoLogLength > 0 ){ std::vector<char> VertexShaderErrorMessage(InfoLogLength+1); glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]); } // Компилируем Фрагментный шейдер printf("Компиляция шейдера: %s\n", fragment_file_path); char const * FragmentSourcePointer = FragmentShaderCode.c_str(); glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); glCompileShader(FragmentShaderID); // Проверяем Фрагментный шейдер glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); if ( InfoLogLength > 0 ){ std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1); glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]); } // Создаем шейдерную программу и привязываем шейдеры к ней fprintf(stdout, "Создаем шейдерную программу и привязываем шейдеры к ней\n"); GLuint ProgramID = glCreateProgram(); glAttachShader(ProgramID, VertexShaderID); glAttachShader(ProgramID, FragmentShaderID); glLinkProgram(ProgramID); // Проверяем шейдерную программу glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); if (InfoLogLength > 0) { std::vector<char> ProgramErrorMessage(InfoLogLength+1); glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); fprintf(stdout, "%s\n", &ProgramErrorMessage[0]); } glDeleteShader(VertexShaderID); glDeleteShader(FragmentShaderID); return ProgramID; } int main(int argc, char *argv[]) { // Инициализируем GLFW if (!glfwInit()) { fprintf( stderr, "Ошибка при инициализации GLFW\n" ); return -1; } glfwDefaultWindowHints(); glfwWindowHint(GLFW_SAMPLES, 4); // Включаем сглаживание glEnable(GL_MULTISAMPLE); // glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Мы хотим использовать OpenGL 3.3 // glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Мы не хотим старый OpenGL // Открыть окно и создать в нем контекст OpenGL GLFWwindow* window; // (В сопроводительном исходном коде эта переменная является глобальной) window = glfwCreateWindow(1024, 768, "Tutorial 01", NULL, NULL); if (window == NULL) { fprintf( stderr, "Невозможно открыть окно GLFW. Если у вас Intel GPU, то он не поддерживает версию 3.3. Попробуйте версию уроков для OpenGL 2.1.\n" ); glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // Инициализируем GLEW glewExperimental=true; // Флаг необходим в Core-режиме OpenGL if (glewInit() != GLEW_OK) { fprintf(stderr, "Невозможно инициализировать GLEW\n"); return -1; } GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); // Массив 3 векторов, которые являются вершинами треугольника static const GLfloat g_vertex_buffer_data[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.5f, 1.0f, 0.0f, }; // Это будет идентификатором нашего буфера вершин GLuint vertexbuffer; // Создадим 1 буфер и поместим в переменную vertexbuffer его идентификатор glGenBuffers(1, &vertexbuffer); // Сделаем только что созданный буфер текущим glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); // Передадим информацию о вершинах в OpenGL glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); // Включим режим отслеживания нажатия клавиш, для проверки ниже glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); // Создать и откомпилировать нашу шейдерную программу GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" ); do { // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Устанавливаем наш шейдер текущим // glUseProgram(programID); // Рисуем треугольник... // Указываем, что первым буфером атрибутов будут вершины glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glVertexAttribPointer( 0, // Атрибут 0. Подробнее об этом будет рассказано в части, посвященной шейдерам. 3, // Размер GL_FLOAT, // Тип GL_FALSE, // Указывает, что значения не нормализованы 0, // Шаг (void*) nullptr // Смещение массива в буфере ); // Вывести треугольник! glDrawArrays(GL_TRIANGLES, 0, 3); // Начиная с вершины 0, всего 3 вершины -> один треугольник glDisableVertexAttribArray(0); // Сбрасываем буферы glfwSwapBuffers(window); glfwPollEvents(); } // Проверяем нажатие клавиши Escape или закрытие окна while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0); } 我看到黑色的窗口(如果我写 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 否则我看到错误: 编译着色器:SimpleVertexShader.vertexshader 0:1(10):错误:不支持 GLSL 3.30。支持的版本有:1.10、1.20、1.30、1.00 ES 和 3.00 ES *编译着色器:SimpleFragmentShader.fragmentshader * 创建着色器程序并链接... 错误:链接未编译/未专门化的着色器 ) 顶点着色器: #version 300 es layout(location = 0) in vec3 vertexPosition_modelspace; void main(){ gl_Position.xyz = vertexPosition_modelspace; gl_Position.w = 1.0; } 片段着色器: #version 300 es precision mediump float; layout(location = 0) out vec3 color; void main() { color = vec3(1,0,0); } 这里注意: GLuint programID = ... 您实际上可能成功地创建并链接了您的程序对象,但您从未激活它!您必须在抽签之前的某处添加glUseProgram(programID)。
按住一个键,然后按下一个改变相同变量的键继续修改它,就好像它在第一个键的位置
我正在制作第一人称相机,基于学习更多关于四元数的教程。这个相机有一个更严重的错误,如果按住“空格”并且您按住“左控制和曲...
代码: #include "include/glad/glad.h" #include "include/GLFW/glfw3.h" #包括 主函数() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
我正在用 Kotlin 制作游戏。为此,我必须绘制一张地图,坚持使用几百张图像,这些图像并没有真正改变,但每一帧都会移动到屏幕上,这非常滞后。你有...
C++ GLFW OpenGL 项目,无法创建 GLFW 窗口
我正在开发一个 C++ OpenGL 项目,使用 GLFW 创建窗口。启动 PC 并首次尝试运行后,我收到此错误“无法创建 GLFW 窗口:WGL:驱动程序
我目前正在用 Rust 开发一个简单的程序来在屏幕上绘制一个彩色三角形。我按照 OpenGL 的说明进行操作。我的程序运行良好,三角形按预期呈现...
我尝试使用 CLion 的 CMake 编译 GLFW 站点的示例代码(我之前根本没有使用过)。编译时出现此错误 cmd.exe /C "cd . && C:\MinGW in\g++.exe -g
我的代码应该使用 OpenGL 生成一个 2D 矩形。出于某种原因,虽然我的代码对我来说似乎是正确的(我是一个正在上大学课程的初学者),但它一直在生成一个三角形......
glfwCreateWindow 中断 gdb 会话,发出 SIGSTOP 信号
我在 Ubuntu 操作系统上使用 gdb 调试器来调试我的应用程序。 在调试会话期间,我无法通过 glfwCreateWindow 函数。 当我执行步骤时,我的调试会话被 SIGSTOP 信号中断...
OpenGL着色器错误C7548:错误C0000:...或#version 410 [关闭]
我不知道我的代码或配置有什么问题。我仔细检查了代码和 VS 设置,为我的 GPU 安装了最新的驱动程序,但仍然看到此错误。错误 C0000:... 或 #version 410 和错误
我在 Ubuntu 20.04 LTS 系统上,我无法运行我的 CPP 代码。每次我尝试编译这个: #包括 #包括 #include "glad/glad.h" 在...
glGenVertexArrays(1, &ID) 仅在使用 openGL 3.3 和核心配置文件时导致段错误
我目前在这里使用 OpenGL 教程。函数 glGenVertexArrays(1, &ID);根据 VSCode 调试器的段错误,我认为函数本身是一个问题,因为只使用
我整个下午都在尝试将 GLFW 与 cmake 链接起来,但似乎没有任何效果。这是我当前的 cmake 文件 cmake_minimum_required(版本 3.22.2) 设置(CMAKE_CXX_STANDARD 23) 项目(
这是我的代码: #包括 #包括 诠释主要(无效){ GLFWwindow* 窗口; 如果(!glfwInit()){ 标准::计算<< "Failed to initialize GLFW!&q...
绑定 2 个不同的纹理单元,但只有一个会在 opengl 中渲染 [重复]
有这个简单的代码: #包括 #包括 #包括 #define STB_IMAGE_IMPLEMENTATION #包括 #包括 有这个简单的代码: #include <iostream> #include <glad/glad.h> #include <GLFW/glfw3.h> #define STB_IMAGE_IMPLEMENTATION #include <stb/stb_image.h> #include <test/main/shader.hpp> uint32_t LoadTexture(const std::string& filepath) { int w, h, bits; stbi_set_flip_vertically_on_load(1); uint8_t *pixels = stbi_load(filepath.c_str(), &w, &h, &bits, 4); uint32_t texture_id; glGenTextures(1, &texture_id); glBindTexture(GL_TEXTURE_2D, texture_id); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); stbi_image_free(pixels); return texture_id; } // https://stackoverflow.com/questions/60513272/alternative-for-glbindtextureunit-for-opengl-versions-less-than-4-5 void Bind2DTexture(int unit, uint32_t texture) { glActiveTexture(GL_TEXTURE0 + unit); glBindTexture(GL_TEXTURE_2D, texture); } int main() { glfwInit(); GLFWwindow *window = glfwCreateWindow(960, 540, "test", nullptr, nullptr); if (window == nullptr) { std::cerr << "failed to create GLFW window\n"; } glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, [](GLFWwindow *_, int width, int height) { glViewport(0, 0, width, height); }); if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) { std::cerr << "failed to initialize GLAD\n"; } glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Shader shader("assets/GLSL/test.glsl"); shader.Bind(); int samplers[2] = {0, 1}; shader.SetIntArray("u_textures", samplers, 2); uint32_t quad_va, quad_vb, quad_ib; glGenVertexArrays(1, &quad_va); glBindVertexArray(quad_va); float vertices[] = { // first texture - logo.png -1.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, -1.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // second texture - chessboard.png 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.5f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f }; glGenBuffers(1, &quad_vb); glBindBuffer(GL_ARRAY_BUFFER, quad_vb); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, nullptr); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 6, reinterpret_cast<const void *>(sizeof(float) * 3)); glEnableVertexAttribArray(1); glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(float) * 6, reinterpret_cast<const void *>(sizeof(float) * 5)); glEnableVertexAttribArray(2); uint32_t indices[] = { 0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4 }; glGenBuffers(1, &quad_ib); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_ib); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); uint32_t logo_id = LoadTexture("assets/textures/logo.png"); uint32_t chessboard_id = LoadTexture("assets/textures/chessboard.png"); while (!glfwWindowShouldClose(window)) { glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shader.Bind(); Bind2DTexture(0, logo_id); Bind2DTexture(1, chessboard_id); glBindVertexArray(quad_va); glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, nullptr); glfwSwapBuffers(window); glfwPollEvents(); } } 和着色器: #type vertex #version 450 core layout(location = 0) in vec3 a_pos; layout(location = 1) in vec2 a_texcoord; layout(location = 0) in float a_texindex; out vec2 v_texcoord; out float v_texindex; void main() { v_texcoord = a_texcoord; v_texindex = a_texindex; gl_Position = vec4(a_pos, 1.0); } #type fragment #version 450 core in vec2 v_texcoord; in float v_texindex; uniform sampler2D u_textures[2]; out vec4 color; void main() { int index = int(v_texcoord); color = texture(u_textures[index], v_texcoord); } 未显示的 Shader 类简单地解析包含顶点和片段部分的着色器文件。现在两个纹理通过最后一个属性指针来区分,一个浮点数 0.0f 用于第一个纹理,1.0f 用于第二个纹理(并转换为 int 以用作着色器内的索引)。但是在输出中,只有第一个,即 logo.png(因为它是通过 Bind2DTexture(0, logo_id); 设置的)将被绘制,而 chessboard.png 不会被绘制。但是两个纹理都是通过 Bind2DTexture 设置为单位的。那么为什么chessborad.png 不是画出来的吗? PS:为了完整起见,这里是着色器类: 标题: #ifndef TEST_SHADER_HPP #define TEST_SHADER_HPP #include <string> #include <glm/glm.hpp> class Shader { public: explicit Shader(const std::string& filepath); void Bind() const; void SetInt(const std::string& name, int value) const; void SetIntArray(const std::string& name, int *values, int count); void SetFloat(const std::string& name, float value) const; void SetVec3(const std::string& name, const glm::vec3& vec) const; void SetVec4(const std::string& name, const glm::vec4& vec) const; void SetMat4(const std::string& name, const glm::mat4& mat) const; private: static void CheckCompileErrors(uint32_t shader_id, const std::string& type, const std::string& filepath); uint32_t id_; }; #endif //TEST_SHADER_HP 来源: #include <test/main/shader.hpp> #include <iostream> #include <fstream> #include <sstream> #include <glad/glad.h> void Shader::CheckCompileErrors(uint32_t shader_id, const std::string& type, const std::string& filepath) { int success; char infoLog[1024]; if (type != "PROGRAM") { glGetShaderiv(shader_id, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(shader_id, 1024, nullptr, infoLog); std::cout << "ERROR::SHADER::COMPILATION_ERROR of type: " << type << "\n" << infoLog << "filepath: " << filepath; } } else { glGetProgramiv(shader_id, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shader_id, 1024, nullptr, infoLog); std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "filepath: " << filepath; } } } Shader::Shader(const std::string& filepath) { // 1. divide vertex and fragment part enum class ShaderType { NONE = -1, VERTEX = 0, FRAGMENT = 1 }; std::ifstream stream(filepath); std::string line; std::stringstream ss[2]; ShaderType type = ShaderType::NONE; while (getline(stream, line)) { if (line.find("#type") != std::string::npos) { if (line.find("vertex") != std::string::npos) { type = ShaderType::VERTEX; } else if (line.find("fragment") != std::string::npos) { type = ShaderType::FRAGMENT; } else { std::cout << "Unknown shader: " << line << '\n'; } } else { if (type == ShaderType::NONE) { std::cout << "No shader defined" << '\n'; } else { ss[(int) type] << line << '\n'; } } } std::string vertex_code = ss[(int) ShaderType::VERTEX].str(); std::string fragment_code = ss[(int) ShaderType::FRAGMENT].str(); // 2. convert, compile and link sources to shader program // 2.1 convert string to c str const char *vertex_str = vertex_code.c_str(); const char *fragment_str = fragment_code.c_str(); // 2.2.1 vertex shader uint32_t vertex_id = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_id, 1, &vertex_str, nullptr); glCompileShader(vertex_id); CheckCompileErrors(vertex_id, "VERTEX", filepath); // 2.2.2 fragment shader uint32_t fragment_id = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_id, 1, &fragment_str, nullptr); glCompileShader(fragment_id); CheckCompileErrors(fragment_id, "FRAGMENT", filepath); // 2.3 shader program id_ = glCreateProgram(); glAttachShader(id_, vertex_id); glAttachShader(id_, fragment_id); glLinkProgram(id_); CheckCompileErrors(id_, "PROGRAM", filepath); // 2.4 delete the shaders as they're linked into program and no longer necessary glDeleteShader(vertex_id); glDeleteShader(fragment_id); } void Shader::Bind() const { glUseProgram(id_); } void Shader::SetInt(const std::string& name, int value) const { glUniform1i(glGetUniformLocation(id_, name.c_str()), value); } void Shader::SetIntArray(const std::string& name, int *values, int count) { glUniform1iv(glGetUniformLocation(id_, name.c_str()), count, values); } void Shader::SetFloat(const std::string& name, float value) const { glUniform1f(glGetUniformLocation(id_, name.c_str()), value); } void Shader::SetVec4(const std::string& name, const glm::vec4& vec) const { glUniform4f(glGetUniformLocation(id_, name.c_str()), vec.x, vec.y, vec.z, vec.w); } void Shader::SetVec3(const std::string& name, const glm::vec3& vec) const { glUniform3f(glGetUniformLocation(id_, name.c_str()), vec.x, vec.y, vec.z); } void Shader::SetMat4(const std::string& name, const glm::mat4& mat) const { glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, &mat[0][0]); }
有这个简单的代码: #包括 #包括 #包括 #包括 #包括 #包括 有这个简单的代码: #include <iostream> #include <memory> #include <glad/glad.h> #include <GLFW/glfw3.h> #include <glm/glm.hpp> #include <test/main/shader.hpp> class Foo { public: void OnAttach() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); window_ = glfwCreateWindow(960, 540, "test", nullptr, nullptr); if (window_ == nullptr) { std::cerr << "failed to create GLFW window\n"; } glfwMakeContextCurrent(window_); glfwSetFramebufferSizeCallback(window_, [](GLFWwindow *_, int width, int height) { glViewport(0, 0, width, height); }); if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) { std::cerr << "failed to initialize GLAD\n"; } glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); shader_ = std::make_shared<Shader>("assets/GLSL/test.glsl"); glGenVertexArrays(1, &quad_va_); glBindVertexArray(quad_va_); float vertices[] = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.5f, 0.5f, 0.0f, -0.5f, 0.5f, 0.0f }; glGenBuffers(1, &quad_vb_); glBindBuffer(GL_ARRAY_BUFFER, quad_vb_); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, nullptr); glEnableVertexAttribArray(0); uint32_t indices[] = {0, 1, 2, 2, 3, 0}; glGenBuffers(1, &quad_ib_); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_ib_); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); } void OnUpdate() { glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shader_->Bind(); shader_->SetVec3("u_color", square_color_); glBindVertexArray(quad_va_); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); } GLFWwindow *GetWindow() const { return window_; } private: GLFWwindow *window_; std::shared_ptr<Shader> shader_; uint32_t quad_va_, quad_vb_, quad_ib_; glm::vec4 square_color_ = {0.8f, 0.2f, 0.3f, 1.0f}; }; void Run(Foo *foo) { foo->OnAttach(); while (!glfwWindowShouldClose(foo->GetWindow())) { foo->OnUpdate(); glfwSwapBuffers(foo->GetWindow()); glfwPollEvents(); } } int main() { Run(new Foo); } 和着色器: #type vertex #version 330 core layout(location = 0) in vec3 a_pos; uniform mat4 u_view_projection; void main() { gl_Position = vec4(a_pos, 1.0); } #type fragment #version 330 core out vec4 color; uniform vec4 u_color; void main() { color = u_color; } 未显示的 Shader 类简单地解析包含顶点和片段部分的着色器文件。并在帧循环中简单地设置制服。我只看到空窗口,没有正方形。但一切似乎都已注定。出了什么问题? PS:为了完整起见,这里是着色器类: 标题: #ifndef TEST_SHADER_HPP #define TEST_SHADER_HPP #include <string> #include <glm/glm.hpp> class Shader { public: explicit Shader(const std::string& filepath); void Bind() const; void SetInt(const std::string& name, int value) const; void SetFloat(const std::string& name, float value) const; void SetVec3(const std::string& name, const glm::vec3& vec) const; void SetVec4(const std::string& name, const glm::vec4& vec) const; void SetMat4(const std::string& name, const glm::mat4& mat) const; private: static void CheckCompileErrors(uint32_t shader_id, const std::string& type, const std::string& filepath); uint32_t id_; }; #endif //TEST_SHADER_HP 来源: #include <test/main/shader.hpp> #include <iostream> #include <fstream> #include <sstream> #include <glad/glad.h> void Shader::CheckCompileErrors(uint32_t shader_id, const std::string& type, const std::string& filepath) { int success; char infoLog[1024]; if (type != "PROGRAM") { glGetShaderiv(shader_id, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(shader_id, 1024, nullptr, infoLog); std::cout << "ERROR::SHADER::COMPILATION_ERROR of type: " << type << "\n" << infoLog << "filepath: " << filepath; } } else { glGetProgramiv(shader_id, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shader_id, 1024, nullptr, infoLog); std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "filepath: " << filepath; } } } Shader::Shader(const std::string& filepath) { // 1. divide vertex and fragment part enum class ShaderType { NONE = -1, VERTEX = 0, FRAGMENT = 1 }; std::ifstream stream(filepath); std::string line; std::stringstream ss[2]; ShaderType type = ShaderType::NONE; while (getline(stream, line)) { if (line.find("#type") != std::string::npos) { if (line.find("vertex") != std::string::npos) { type = ShaderType::VERTEX; } else if (line.find("fragment") != std::string::npos) { type = ShaderType::FRAGMENT; } else { std::cout << "Unknown shader: " << line << '\n'; } } else { if (type == ShaderType::NONE) { std::cout << "No shader defined" << '\n'; } else { ss[(int) type] << line << '\n'; } } } std::string vertex_code = ss[(int) ShaderType::VERTEX].str(); std::string fragment_code = ss[(int) ShaderType::FRAGMENT].str(); // 2. convert, compile and link sources to shader program // 2.1 convert string to c str const char *vertex_str = vertex_code.c_str(); const char *fragment_str = fragment_code.c_str(); // 2.2.1 vertex shader uint32_t vertex_id = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_id, 1, &vertex_str, nullptr); glCompileShader(vertex_id); CheckCompileErrors(vertex_id, "VERTEX", filepath); // 2.2.2 fragment shader uint32_t fragment_id = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_id, 1, &fragment_str, nullptr); glCompileShader(fragment_id); CheckCompileErrors(fragment_id, "FRAGMENT", filepath); // 2.3 shader program id_ = glCreateProgram(); glAttachShader(id_, vertex_id); glAttachShader(id_, fragment_id); glLinkProgram(id_); CheckCompileErrors(id_, "PROGRAM", filepath); // 2.4 delete the shaders as they're linked into program and no longer necessary glDeleteShader(vertex_id); glDeleteShader(fragment_id); } void Shader::Bind() const { glUseProgram(id_); } void Shader::SetInt(const std::string& name, int value) const { glUniform1i(glGetUniformLocation(id_, name.c_str()), value); } void Shader::SetFloat(const std::string& name, float value) const { glUniform1f(glGetUniformLocation(id_, name.c_str()), value); } void Shader::SetVec4(const std::string& name, const glm::vec4& vec) const { glUniform4f(glGetUniformLocation(id_, name.c_str()), vec.x, vec.y, vec.z, vec.w); } void Shader::SetVec3(const std::string& name, const glm::vec3& vec) const { glUniform3f(glGetUniformLocation(id_, name.c_str()), vec.x, vec.y, vec.z); } void Shader::SetMat4(const std::string& name, const glm::mat4& mat) const { glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, &mat[0][0]); }
我正在使用 glfw 来设置 OpenGL 可视化。我想将回调函数设置为非静态函数来访问类变量。但是,当我执行以下操作时,出现错误“
这里是: 技术栈:glfw、opengl、ubuntu 我的目标是同时渲染两个东西,一个 3d 模型和一个 yuv420p 视频(使用两个不同的着色器程序)。 如果我只渲染其中之一...