0:1(1):错误:语法错误,意外的文件结尾

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

各位程序员大家好。

我对我的 opengl 项目中的这个概念感到非常困惑。 我在编译中收到以下错误:

[Error]: failed to compile vertex shader.

[Log]: 0:1(1): error: syntax error, unexpected end of file

[Error]: failed to compile fragment shader.

[Log]: 0:1(1): error: syntax error, unexpected end of file

我有一个 main.cpp 一个 util/debug.hpp 和 util/debug.cpp 用于调试目的以及 res/shaders/basic.shader

main.cpp:

#include <GLFW/glfw3.h>

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>

#include "util/debug.hpp"

struct ShaderProgramSource
{
    std::string vertex_source;
    std::string fragment_source;
};

static ShaderProgramSource parse_shader(const std::string& filepath)
{
    std::ifstream stream(filepath);

    enum class ShaderType
    {
        NONE = -1, VERTEX = 0, FRAGMENT = 1
    };

    std::string line;
    std::stringstream ss[2];
    ShaderType type = ShaderType::NONE;

    while (getline(stream, line))
    {
        if (line.find("#shader") != 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
        {
            ss[(int)type] << line << '\n';
        }
    }

    return { ss[0].str(), ss[1].str() };
}

static unsigned int compile_shader(unsigned int type, const std::string& source)
{
    GLCall(unsigned int id = glCreateShader(type));
    const char *src = source.c_str();
    GLCall(glShaderSource(id, 1, &src, nullptr));
    GLCall(glCompileShader(id));

    int result;
    GLCall(glGetShaderiv(id, GL_COMPILE_STATUS, &result));

    if (result == GL_FALSE) 
    {
        int length;
        GLCall(glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length));

        char* message = (char*)alloca(length * sizeof(char));
        GLCall(glGetShaderInfoLog(id, length, &length, message));

        util::error(std::string("failed to compile ") + (type == GL_VERTEX_SHADER ? "vertex" : "fragment") + " shader.");
        util::log(message);

        GLCall(glDeleteShader(id));
        return 0;
    }

    return id;
}

static unsigned int create_shader(const std::string& vertex_shader, const std::string& fragment_shader) 
{
    GLCall(unsigned int program = glCreateProgram());
    unsigned int vs = compile_shader(GL_VERTEX_SHADER, vertex_shader);
    unsigned int fs = compile_shader(GL_FRAGMENT_SHADER, fragment_shader);

    GLCall(glAttachShader(program, vs));
    GLCall(glAttachShader(program, fs));
    GLCall(glLinkProgram(program));
    GLCall(glValidateProgram(program));

    GLCall(glDeleteShader(vs));
    GLCall(glDeleteShader(fs));

    return program;
}

int main(void)
{
    GLFWwindow* window;

    if (!glfwInit())
        util::error_exit("failed to initialize glfw.", -1);

    window = glfwCreateWindow(640, 480, "Simple Window", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    glfwSwapInterval(1);

    if (glewInit() != GLEW_OK)
        util::error_exit("failed to initialize glew.", -1);

    std::cout << "[OpenGL Information]" << std::endl;
    util::info("Version: " + std::string((const char*)glGetString(GL_VERSION)));
    util::info("Renderer: " + std::string((const char*)glGetString(GL_RENDERER)));
    util::info("Vendor: " + std::string((const char*)glGetString(GL_VENDOR)));

    float positions[] = {
        -0.5f, -0.5f, // 0
         0.5f, -0.5f, // 1
         0.5f,  0.5f, // 2
        -0.5f,  0.5f  // 3
    };

    unsigned int indices[] = {
        0, 1, 2,
        2, 3, 0
    };

    unsigned int buffer;
    GLCall(glGenBuffers(1, &buffer));
    GLCall(glBindBuffer(GL_ARRAY_BUFFER, buffer));
    GLCall(glBufferData(GL_ARRAY_BUFFER, 6 * 2 * sizeof(float), positions, GL_STATIC_DRAW));

    GLCall(glEnableVertexAttribArray(0));
    GLCall(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0));
    
    unsigned int ibo;
    GLCall(glGenBuffers(1, &ibo));
    GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo));
    GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), indices, GL_STATIC_DRAW));

    ShaderProgramSource source = parse_shader("res/shaders/basic.shader");
    unsigned int shader = create_shader(source.vertex_source, source.fragment_source);
    GLCall(glUseProgram(shader));

    GLCall(int location = glGetUniformLocation(shader, "u_Color"));
    ASSERT(location != -1);
    GLCall(glUniform4f(location, 0.2f, 0.3f, 0.8f, 1.0f));

    float r = 0.0f;
    float increment = 0.05f;

    while (!glfwWindowShouldClose(window))
    {
        /* Render */
        GLCall(glClear(GL_COLOR_BUFFER_BIT));

        GLCall(glUniform4f(location, r, 0.3f, 0.8f, 1.0f));
        GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr));

        if (r > 1.0f)
            increment = -0.05f;
        if (r < 0.0f)
            increment = 0.05f;

        r += increment;

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    GLCall(glDeleteProgram(shader));

    glfwTerminate();
    return 0;
}

util/debug.hpp:

#pragma once

#include <iostream>

#ifdef _WIN32
    #include <intrin.h>
    #define DEBUGBREAK() __debugbreak()
#else
    #include <csignal>
    #define DEBUGBREAK() raise(SIGTRAP)
#endif

#define ASSERT(x) if (!(x)) { DEBUGBREAK(); }
#define GLCall(x) util::GLClearError();\
    x;\
    ASSERT(util::GLLogCall(#x, __FILE__, __LINE__))

namespace util {
    void log(const std::string& msg);
    void warn(const std::string& msg);
    void info(const std::string& msg);
    void error(const std::string& msg);

    int error_exit(const std::string& msg, int err_code) ;

    void GLClearError();
    bool GLLogCall(const char* function, const char* file, int line);
}

util/debug.cpp:

#include "debug.hpp"
#include <GL/glew.h>

namespace util 
{
    void log(const std::string& msg) { std::cout << "[Log]: " << msg << std::endl; }
    void warn(const std::string& msg) { std::cout << "[Warn]: " << msg << std::endl; }
    void info(const std::string& msg) { std::cout << "[Info]: " << msg << std::endl; }
    void error(const std::string& msg) { std::cout << "[Error]: " << msg << std::endl; }

    int error_exit(const std::string& msg, int err_code) 
    {
        error(msg);
        return err_code;
    }

    void GLClearError()
    {
        while (glGetError() != GL_NO_ERROR);
    }

    bool GLLogCall(const char* function, const char* file, int line)
    {
        while (GLenum error = glGetError())
        {
            std::cout << "[OpenGL Error]: " << error << std::endl;
            std::cout << "[Function]: " << function << std::endl;
            std::cout << "[File]: " << file << std::endl;
            std::cout << "[Line]: " << line << std::endl;

            return false;
        }

        return true;
    }
}

res/shaders/basic.shader:

#shader vertex
#version 460 compatibility

layout(location = 0) in vec4 position;

void main()
{
    gl_Position = position;
}

#shader fragment
#version 460 compatibility

layout(location = 0) out vec4 color;

uniform vec4 u_Color;

void main()
{
    color = u_Color;
}

我不知道我的着色器代码有什么问题,它看起来很好,实际上,当我将程序切换到 CLion - JetBrains IDE 时,我就遇到了这些错误。 我来自 vscode,当我使用 make 时它可以工作,并且着色器代码看起来很好。

为了好奇,这里是 makefile,文件结构在我的 vscode 项目中有点不同,但我可以保证我当前正在编译的代码正在读取正确的路径。

生成文件:

CXX = g++
CXFLAGS = -Iinc/ -lglfw -lGLEW -lGL -ldl

SRC = $(wildcard src/*.cpp) $(wildcard src/*/*.cpp)
OBJ = $(SRC:.cpp=.o)
BIN = bin
EXEC = $(BIN)/main

all: $(EXEC)

$(EXEC): $(OBJ)
    @mkdir -p $(BIN)
    $(CXX) $^ -o $@ $(CXFLAGS)

%.o: %.cpp
    $(CXX) -c $< -o $@ $(CXFLAGS)

run: $(EXEC)
    @./$(EXEC)

clean:
    @rm -rf $(BIN)

旧项目的完整输出(程序有效):

ralph@wolf:~/Desktop/Dev/C++/Backup$ make
g++ src/main.o src/util/debug.o -o bin/main -Iinc/ -lglfw -lGLEW -lGL -ldl
ralph@wolf:~/Desktop/Dev/C++/Backup$ make run
[OpenGL Information]
[Info]: Version: 4.6 (Compatibility Profile) Mesa 23.2.1-1ubuntu3.1~22.04.2
[Info]: Renderer: Mesa Intel(R) UHD Graphics 630 (CML GT2)
[Info]: Vendor: Intel
ralph@wolf:~/Desktop/Dev/C++/Backup$ 

JetBrains CMake 的新输出 - Ninja(不起作用):

/home/ralph/Desktop/Dev/C++/OpenGL/cmake-build-debug/OpenGL
[OpenGL Information]
[Info]: Version: 4.6 (Compatibility Profile) Mesa 23.2.1-1ubuntu3.1~22.04.2
[Info]: Renderer: Mesa Intel(R) UHD Graphics 630 (CML GT2)
[Info]: Vendor: Intel
[Error]: failed to compile vertex shader.
[Log]: 0:1(1): error: syntax error, unexpected end of file

[Error]: failed to compile fragment shader.
[Log]: 0:1(1): error: syntax error, unexpected end of file

[OpenGL Error]: 1281
[Function]: glAttachShader(program, vs)
[File]: /home/ralph/Desktop/Dev/C++/OpenGL/main.cpp
[Line]: 82

Process finished with exit code 133 (interrupted by signal 5:SIGTRAP)
c++ opengl shader
1个回答
0
投票

1281 opengl 错误表示空数据或错误数据作为函数参数传递给 GlAttachShader 程序。

您是否在 CMakeList.txt 中包含着色器文件? add_executable(MyOpenGLProject main.cpp 着色器.cpp)

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