在将一个库从头库转移到一个简单库(通过 cmake 组装,类型 *.a)时,我遇到了一个问题。调用Program类后,出现错误error: no shaders attached to the program。这是程序类的旧实现(我将仅显示更改)和新实现,以及着色器类。代码:
#include <iostream>
#include <vector>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
using namespace std;
const GLchar* shader1 = "#version 460 core\nout vec4 FragColor;\nvoid main() { FragColor = vec4(1.0); }";
const GLchar* shader2 = "#version 460 core\nvoid main() { gl_Position = vec4(1.0); }";
#define LogSize 1024
// class Shader
class Shader
{
public:
GLuint shader;
Shader(GLenum type, const GLchar* source)
{
shader = glCreateShader(type);
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
GLint error = 0; GLchar log[LogSize];
glGetShaderiv(shader, GL_COMPILE_STATUS, &error);
if (error == GL_FALSE)
{
glGetShaderInfoLog(shader, LogSize, NULL, log);
printf("%s", log);
}
}
void del() { glDeleteShader(shader); }
};
class Program
{
public:
GLuint ID;
Program(vector<Shader> &shaders);
Program(Shader* shaders, size_t len);
};
// new class Program
Program::Program(vector<Shader> &shaders)
{
ID = glCreateProgram();
for (size_t i = 0; i < shaders.size(); i++) glAttachShader(ID, shaders[i].shader);
glLinkProgram(ID);
GLint error = 0; GLchar log[LogSize]; // LogSize = 1024
glGetProgramiv(ID, GL_LINK_STATUS, &error);
if (error == GL_FALSE)
{
glGetProgramInfoLog(ID, LogSize, NULL, log);
printf("%s", log);
}
}
// old class Program
Program::Program(Shader* shaders, size_t len)
{
ID = glCreateProgram();
for (size_t i = 0; i < len; i++) glAttachShader(ID, shaders[i].shader);
glLinkProgram(ID);
GLint error = 0; GLchar log[LogSize]; // LogSize = 1024
glGetProgramiv(ID, GL_LINK_STATUS, &error);
if (error == GL_FALSE)
{
glGetProgramInfoLog(ID, LogSize, NULL, log);
printf("%s", log);
}
}
void framebuffer_size_callback(GLFWwindow* win, int a, int b) {}
void mouse_callback(GLFWwindow*, double a, double b) {}
void processInput(GLFWwindow* win) {}
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
GLFWwindow* window = glfwCreateWindow(400, 400, "", NULL, NULL);
if (window == NULL)
{
std::cout << "Fail to create window!";
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetCursorPosCallback(window, mouse_callback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
std::cout << "Failed to initialize GLAD" << std::endl;
// main
Shader shader1(GL_VERTEX_SHADER, "path to shader");
Shader shader2(GL_FRAGMENT_SHADER, "path to shader");
// new program
vector<Shader> shaders = {shader1, shader2};
Program program(shaders);
// old program
Shader shaders2[] = {shader1, shader2};
Program program2(shaders2, 2);
// и в старой и в новой
shader1.del();
shader2.del();
}
正如您所看到的,代码几乎没有改变,但是现在,当返回到旧版本时,没有任何作用。请帮忙,我不明白为什么它停止工作,需要一点说明,我使用glad、glfw3和OpenGL 4.6。这是编译 g++(或任何其他编译器) main.cpp -o main -I path_to_glfw3_headers_and_glad -L path_to_glfw3_library_and_glad -lglad -lglfw3 的命令
好吧,经过这么多次尝试,TS 终于在代码中添加了这样的内容,以便我们可以假设那里出了什么问题,但是,我想说,问题没有重现,也许又是,TS 隐藏了一些东西,并没有说什么。
编写工作代码:
主.cxx:
着色器.hxx:
着色器.cxx:
程序.hxx:
程序.cxx:
fragment_shader.hxx:
fragment_shader.cxx:
vertex_shader.hxx:
vertex_shader.cxx:
utils.hxx:
感谢@evo,在他的话之后“复制视频卡资源,包括着色器,是不可能的,你不能复制着色器类,它必须是唯一的,就像程序类一样,你可能已经在析构函数中删除了着色器,并且之后它不可用”。听完他的话,我决定更改我的代码。和以前一样(有错误):
这是错误的选择。我传递给程序的不是着色器的链接,而是着色器的副本,因此,调用析构函数,从视频卡的内存中删除着色器。在新版本中,我传递了对着色器的引用,因此不会调用析构函数。现在是这样(没有错误):
现在没有错误了,感谢@evo 的帮助。