c++ - GLSL语法问题: unexpected NEW_IDENTIFIER

标签 c++ opengl glsl glfw

我刚刚开始学习OpenGL,正在关注this教程。我在编译本教程使用的 GLSL 文件时遇到困难。

最初,当我尝试编译它们时,编译器说 mesa 不支持 GLSL 版本 330,因此我将 #version 330 core 更改为 #version 130。现在,当我运行它时,出现以下错误:

3.0 Mesa 10.0.20Compiling shader : SimpleVertexShader.vertexshader
0:3(1): error: syntax error, unexpected NEW_IDENTIFIER

Compiling shader : SimpleFragmentShader.fragmentshader

Linking program
error: linking with uncompiled shader

我在谷歌上搜索过,没有找到有这个问题的人。无论如何,这里是所有有问题的文件:

SimpleVertexShader.vertexshader:

#version 130
layout(location = 0) in vec3 vertexPosition_modelspace;

void main(){
    gl_Position.xyz = vertexPosition_modelspace;
    gl_Position.w = 1.0;
}

SimpleFragmentShader.fragmentshader:

#version 130
out vec3 color;

void main() {
    color = vec3(1,0,0);
}

loadShader.cpp:

#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
#include <stdlib.h>
#include <string.h>

#include <GL/glew.h>

GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){

    // Create the shaders
    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    // Read the Vertex Shader code from the file
    std::string VertexShaderCode;
    std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
    if(VertexShaderStream.is_open())
    {
        std::string Line = "";
        while(getline(VertexShaderStream, Line))
            VertexShaderCode += "\n" + Line;
        VertexShaderStream.close();
    }

    // Read the Fragment Shader code from the file
    std::string FragmentShaderCode;
    std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
    if(FragmentShaderStream.is_open()){
        std::string Line = "";
        while(getline(FragmentShaderStream, Line))
            FragmentShaderCode += "\n" + Line;
        FragmentShaderStream.close();
    }

    GLint Result = GL_FALSE;
    int InfoLogLength;

    // Compile Vertex Shader
    printf("Compiling shader : %s\n", vertex_file_path);
    char const * VertexSourcePointer = VertexShaderCode.c_str();
    glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
    glCompileShader(VertexShaderID);

    // Check Vertex Shader
    glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> VertexShaderErrorMessage(InfoLogLength);
    glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
    fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);

    // Compile Fragment Shader
    printf("Compiling shader : %s\n", fragment_file_path);
    char const * FragmentSourcePointer = FragmentShaderCode.c_str();
    glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
    glCompileShader(FragmentShaderID);

    // Check Fragment Shader
    glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
    glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
    fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);

    // Link the program
    fprintf(stdout, "Linking program\n");
    GLuint ProgramID = glCreateProgram();
    glAttachShader(ProgramID, VertexShaderID);
    glAttachShader(ProgramID, FragmentShaderID);
    glLinkProgram(ProgramID);

    // Check the program
    glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
    glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> ProgramErrorMessage( max(InfoLogLength, int(1)) );
    glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
    fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);

    glDeleteShader(VertexShaderID);
    glDeleteShader(FragmentShaderID);

    return ProgramID;
}

main.cpp:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
//#define GLFW_DLL // maybe some glu problems - look up
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>

GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path);

int main()
{
    GLFWwindow * window;

    if (!glfwInit()) {
        std::cout << "Failed to initiate GLFW\n";
        return -1;
    }

    glfwWindowHint(GLFW_SAMPLES, 4); //4x antialiasing
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //version 3

    //open a window and create context
    window=glfwCreateWindow(1024,768,"Lerning", glfwGetPrimaryMonitor(), NULL);
    if (!window) {
        std::cout << "Failed to open window\n";
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);
    std::cout << glGetString(GL_VERSION);

    // initialize GLEW
    glewExperimental=GL_TRUE; //needed
    GLenum err = glewInit();
    std::cout << err;
    if (err != GLEW_OK) {
        std::cout << "Failed to initialize\n" << glewGetErrorString(err);
        return -1;
    }

    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

    static const GLfloat g_vertex_buffer_data[] = {
        -1.0f, -1.0f, 0.0f,
        1.0f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
    };

    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data),
            g_vertex_buffer_data, GL_STATIC_DRAW);

    GLuint programID = LoadShaders("SimpleVertexShader.vertexshader",
            "SimpleFragmentShader.fragmentshader");

    while (!glfwWindowShouldClose(window)) {

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(programID);

        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glVertexAttribPointer(
                0,
                3,
                GL_FLOAT,
                GL_FALSE,
                0,
                (void*)0
        );

        glDrawArrays(GL_TRIANGLES, 0, 3);
        glDisableVertexAttribArray(0);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

最佳答案

layout(location = 0) 在 GLSL 1.30 中无效。 GLSL 1.40 中引入了布局限定符。在链接着色器之前,您需要在 C++ 代码中手动绑定(bind)该顶点属性位置。

// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);

// Create the program
fprintf(stdout, "Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);

// Setup Vertex Attributes  [NEW]
glBindAttribLocation (ProgramID, 0, "vertexPosition_modelspace");

// Link the program
glLinkProgram(ProgramID);

一旦您删除布局(位置 = 0),该属性就有可能会被 GLSL 实现自动分配0,但您应该继续并绑定(bind)位置以正确方式执行操作。

关于c++ - GLSL语法问题: unexpected NEW_IDENTIFIER,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21354301/

相关文章:

c++ - 如何在 C++ 中创建一个独立的可执行程序?

java - 带有 OBJ 文件的顶点纹理

c++ - `resize`减少 vector 容量会有风险吗?

c++ - 我怎样才能解决这些 Qt 错误

c++ - GLFW 无响应全屏窗口

opengl - openGL 3.1中如何实现glEdgeFlag的功能?

opengl - GLSL/HLSL - 多单行条件语句而不是单 block

c++ - GLSL 删除使用过的变量

opengl-es - 如何在 GLSL ES 中确定纹理的偶数/奇数线

c++ - 战舰游戏 - 跟踪船只