我在之前的《Learn OpenGL by packt》示例中制作了一个橙色三角形。当我使用shader.h、core.vs和core.frag将代码更新到下一个示例时,我编译得很好,但出现了段错误。与 GLchar *fragmentShaderSource 和 GLchar*vertexShaderSource 有关吗?我注意到它们已从 coloredtriangle.cpp 中删除,并且 #version 330 核心已移至 core.frag 和 core.vs 中。我收到一个错误,它们没有定义,所以我把它们放回去。我有:
#include <iostream>
#define GLEW_STATIC
#include "shader.h"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
Shader ourShader("core.vs", "core.frag");
const GLchar *vertexShaderSource = "#version 330 core\n";
const GLchar *fragmentShaderSource = "#version 330 core\n";
const GLuint WIDTH = 800, HEIGHT = 600;
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow *window =
glfwCreateWindow(WIDTH, HEIGHT, "Learn OpenGL", nullptr, nullptr);
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
if (nullptr == window) {
std::cout << "Failed to create glfw window!\n";
glfwTerminate();
return EXIT_FAILURE;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if (GLEW_OK != glewInit()) {
std::cout << "Failed to initialize glew!" << std::endl;
return EXIT_FAILURE;
}
glViewport(0, 0, screenWidth, screenHeight);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLint success;
GLchar infoLog(512);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED" << infoLog
<< std::endl;
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION::FAILED\n"
<< infoLog << std::endl;
}
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING::FAILED\n"
<< infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
GLfloat vertices[] = {0.5f, -0.5f, 0.0f, -0.5f, -0.5f,
0.0f, 0.0f, 0.5f, 0.0f};
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat),
(GLvoid *)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat),
(GLvoid *)(3 * sizeof(GLfloat)));
glBindVertexArray(0);
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ourShader.Use();
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return EXIT_SUCCESS;
}
#ifndef SHADER_H
#define SHADER_H
#include <GL/glew.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
class Shader {
public:
GLuint Program;
Shader(const GLchar *vertexPath, const GLchar *fragmentPath) {
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
vShaderFile.exceptions(std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::badbit);
try {
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
vShaderFile.close();
fShaderFile.close();
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
} catch (std::ifstream::failure e) {
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl;
}
const GLchar *vShaderCode = vertexCode.c_str();
const GLchar *fShaderCode = fragmentCode.c_str();
GLuint vertex, fragment;
GLint success;
GLchar infoLog[512];
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED" << infoLog
<< std::endl;
}
this->Program = glCreateProgram();
glAttachShader(this->Program, vertex);
glAttachShader(this->Program, fragment);
glLinkProgram(this->Program);
glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n"
<< infoLog << std::endl;
}
glDeleteShader(vertex);
glDeleteShader(fragment);
}
void Use() { glUseProgram(this->Program); }
};
#endif
#version 330 core
in vec3 ourColor;
out vec4 color;
void main()
{
color vec4(ourColor, 1.0f);
}
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;"
out vec3 ourColor"
void main()
{
glPosition = vec 4 (position, 1.0f);
ourColor = color;}"
我在之前的《Learn OpenGL by packt》示例中制作了一个橙色三角形。当我使用shader.h、core.vs和core.frag将代码更新到下一个示例时,我编译得很好,但出现了段错误。与 GLchar *fragmentShaderSource 和 GLchar*vertexShaderSource 有关吗?我注意到它们已从 coloredtriangle.cpp 中取出,并且 #version 330 核心已移至 core.frag 和 core.vs 中。我收到一个错误,它们没有定义,所以我把它们放回原处。
主要问题是
ourShader
类型的 Shader
是在文件(全局)范围内声明的,因此其构造函数在 main
函数之前运行。 Shader
的构造函数使用的OpenGL函数指针此时尚未初始化。 仅在 GLEW 初始化后初始化。该程序当前将尝试使用位于内存位置 0x0 等处的函数指针,这会导致分段错误。 解决方案是
move Shader ourShader(...)
到after 调用
glewInit()
。此外,具有 main 函数的文件和着色器类都包含从着色器源创建着色器程序的代码。假设我们的想法是为此使用一个单独的类,请删除代码after 将视口设置为 before 从主文件中定义顶点。 还有其他 OpenGL 问题,与分段错误无关。如果您也想解决这些问题,请通过评论告诉我。