是什么导致了这个段错误?是Glchar * vertexShaderSource 和GLchar *fragmentShaderSource 吗?

问题描述 投票:0回答:1

我在之前的《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 中。我收到一个错误,它们没有定义,所以我把它们放回原处。

c++ opengl glfw
1个回答
0
投票

主要问题是

ourShader
类型的
Shader
是在文件(全局)范围内声明的,因此其构造函数在
main
函数之前运行。 Shader的构造函数使用的
OpenGL函数指针
此时尚未初始化仅在 GLEW 初始化后初始化。该程序当前将尝试使用位于内存位置 0x0 等处的函数指针,这会导致分段错误。

解决方案是

move Shader ourShader(...)

after 调用 glewInit()
。此外,具有 main 函数的文件和着色器类都包含从着色器源创建着色器程序的代码。假设我们的想法是为此使用一个单独的类,请删除代码 
after 将视口设置为 before 从主文件中定义顶点。

还有其他 OpenGL 问题,与分段错误无关。如果您也想解决这些问题,请通过评论告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.