几何着色器被错误地解释为顶点着色器

Posted

技术标签:

【中文标题】几何着色器被错误地解释为顶点着色器【英文标题】:geometry shader falsely interpreted as vertex shader 【发布时间】:2014-03-12 20:06:13 【问题描述】:

我正在尝试让我的简单几何着色器工作。但我有一些奇怪的错误信息。似乎opengl认为我的几何着色器是我的顶点着色器。 这是错误信息:

0:错误 C7575:OpenGL 不允许顶点着色器中的输入块

但是我的顶点着色器没有输入块。

这是我的顶点着色器

#version 430 

in vec4 s_vPosition;
in vec4 s_vColor;
uniform mat4 mF; //final matrix = mP*mV*mDneu*mM

out VS_OUT

    vec4 color;     //sent color out to next stage
 vs_out;

void main (void) 
    vs_out.color = s_vColor;
    gl_Position = mF*s_vPosition;

几何着色器

#version 430 

layout(triangles) in;
layout(triangle_strip) out;
layout(max_vertices = 3) out;

in VS_OUT

    vec4 color;
 gs_in[];

out GS_OUT 

    vec4 color;
 gs_out;

 void main(void)

   for(int i = 0; i < gl_in.length(); i++)
  
    gl_Position = gl_in[i].gl_Position;

    gs_out.color = gs_in[i].color;
    EmitVertex();
  
  EndPrimitive();

fragmentShader

#version 430                                                  

in GS_OUT                                             
                                                     
    vec4 color;                                       
 fs_in;                                              

out vec4 fColor;

void main(void)                                       
                                                    
    fColor.r = abs(fs_in.color.r);
    fColor.g = abs(fs_in.color.g);
    fColor.b = abs(fs_in.color.b);
    fColor.a = 1.0f;                              

当我运行程序时,几何着色器无法编译。只有当我摆脱它编译的输入块时。

我也认识到,函数...

// Find the position of the variables in the shader
positionID = glGetAttribLocation(shaderProgramID, "s_vPosition");
colorID = glGetAttribLocation(shaderProgramID, "s_vColor");
cout <<"positionID: "<< (int)positionID << endl;
cout <<"colorID   : "<< (int)colorID << endl;

...当几何着色器不包含时返回 0 和 1(对于 positionID 和 colorID),当它包含在着色器程序中时返回 0 和 -1。 所以我认为出了点问题,但我不知道它可能是什么。请帮助 :)

我不知道它是否有用,但这里是制作着色器的代码。

首先我从文本文件中获取着色器代码。然后我调用函数来制作着色器和着色器程序。

// Make a shader
    char* vertexShaderSourceCode = readFile("vertexShader.vsh");
    char* geometryShaderSourceCode = readFile("geometryShader.gsh");
    char* fragmentShaderSourceCode = readFile("fragmentShader.fsh");
    GLuint vertShaderID = makeVertexShader(vertexShaderSourceCode);
    GLuint geometryShaderID = makeVertexShader(geometryShaderSourceCode);
    GLuint fragShaderID = makeFragmentShader(fragmentShaderSourceCode);
    shaderProgramID = makeShaderProgram(vertShaderID, geometryShaderID, fragShaderID);

这是制作着色器的函数。

static char* readFile(const char* filename) 
    // Open the file
    FILE* fp = fopen(filename, "r");
    // Move the file pointer to the end of the file and determing the length
    fseek(fp, 0, SEEK_END);
    long file_length = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    char* contents = new char[file_length + 1];
    // zero out memory
    for (int i = 0; i < file_length + 1; i++) 
        contents[i] = 0;
    
    // Here's the actual read
    fread(contents, 1, file_length, fp);
    // This is how you denote the end of a string in C
    contents[file_length + 1] = '\0';
    fclose(fp);
    return contents;


bool compiledStatus(GLint shaderID)
    GLint compiled = 0;
    glGetShaderiv(shaderID, GL_COMPILE_STATUS, &compiled);
    if (compiled) 
        return true;
    
    else 
        GLint logLength;
        glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLength);
        char* msgBuffer = new char[logLength];
        glGetShaderInfoLog(shaderID, logLength, NULL, msgBuffer);
        printf("%s\n", msgBuffer);
        delete (msgBuffer);
        return false;
    


GLuint makeVertexShader(const char* shaderSource) 
    GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShaderID, 1, (const GLchar**)&shaderSource, NULL);
    glCompileShader(vertexShaderID);
    bool compiledCorrectly = compiledStatus(vertexShaderID);
    if (compiledCorrectly) 
        return vertexShaderID;
    
    return -1;


GLuint makeGeometryShader(const char* shaderSource)
    GLuint geometryShaderID = glCreateShader(GL_GEOMETRY_SHADER);
    glShaderSource(geometryShaderID, 1, (const GLchar**)&shaderSource, NULL);
    glCompileShader(geometryShaderID);
    bool compiledCorrectly = compiledStatus(geometryShaderID);
    if (compiledCorrectly) 
        return geometryShaderID;
    
    return -1;


GLuint makeFragmentShader(const char* shaderSource) 
    GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShaderID, 1, (const GLchar**)&shaderSource, NULL);
    glCompileShader(fragmentShaderID);
    bool compiledCorrectly = compiledStatus(fragmentShaderID);
    if (compiledCorrectly) 
        return fragmentShaderID;
    
    return -1;


GLuint makeShaderProgram(GLuint vertexShaderID, GLuint geometryShaderID, GLuint fragmentShaderID) 
    GLuint shaderID = glCreateProgram();
    glAttachShader(shaderID, vertexShaderID);
    glAttachShader(shaderID, geometryShaderID);
    glAttachShader(shaderID, fragmentShaderID);
    glLinkProgram(shaderID);
    return shaderID;

【问题讨论】:

【参考方案1】:

GLuint geometryShaderID = ma​​keVertexShader(geometryShaderSourceCode); ??

【讨论】:

以上是关于几何着色器被错误地解释为顶点着色器的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL几何着色器三角形不会没有错误地绘制

如果几何着色器处于活动状态,如何将信息从顶点着色器传递到片段着色器?

Unity Shader:几何着色器

渲染管道几何阶段二“顶点着色器”

渲染管道几何阶段二“顶点着色器”

✠OpenGL-13-几何着色器