本文介绍了在OpenGL着色器文件三角形中获取随机错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到随机错误.

这是一个OpenGL着色器文件三角形,我同时包含主着色器和GLSL着色器.

This is a OpenGL shader file triangle i am including both the main and the GLSL shader.

这是我在一个文件中的顶点和片段

#shader vertex
#version 330 core

layout(location = 0) in vec3 position;

void main()
{
    gl_Position = vec4(position.x, position.y, position.z, 1.0);
};

#shader fragment
#version 330 core;

out vec4 color;

void main()
{
    color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
};

这是我的主要应用

// GLEW
#define GLEW_STATIC
#include <GL/glew.h>


struct Shaderprogramsource {
    std::string VertexSouce;
    std::string FragmentSource;
};


static Shaderprogramsource Parseshader(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 int CompileShader(unsigned int type, const std::string& Source) {
    unsigned int id = glCreateShader(type);
    const char* src = Source.c_str();
    glShaderSource(id, 1, &src, nullptr);
    glCompileShader(id);

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

    if (result == GL_FALSE) {

        int length;
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);

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

        std::cout << message ;

        return 0;
    }

    return id;
}

static unsigned int CreateShader(const std::string& Vertexshader, const std::string& Fragmentshader) 
{
    unsigned int program = glCreateProgram();
    unsigned int vertex = CompileShader(GL_VERTEX_SHADER, Vertexshader);
    unsigned int fragment = CompileShader(GL_FRAGMENT_SHADER, Fragmentshader);

    glAttachShader(program, vertex);
    glAttachShader(program, fragment);

    glLinkProgram(program);
    glValidateProgram(program);

    return program;
}

int main(void)
{
    GLFWwindow* window;

    /* Initialize the library */
    if (!glfwInit())
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    if (GLEW_OK == glewInit())
    {

    }


    float vertices[6] = {
        -0.5, -0.5,
        0.0, 0.5,
        0.5, 0.5
    };

    unsigned int buffer1;

    glGenBuffers(1, &buffer1);
    glBindBuffer(GL_ARRAY_BUFFER, buffer1);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

    glEnableVertexAttribArray(0);

    Shaderprogramsource source = Parseshader("res/shaders/Basic.Shader");

    unsigned int shader = CreateShader(source.VertexSouce, source.FragmentSource);
    glUseProgram(shader);


    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(shader);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glDeleteProgram(shader);

    glfwTerminate();
    return 0;
}

推荐答案

#version 330 core;
                 ^ wut

#version行上没有分号.

Parseshader()也是相当脆弱的,因为如果着色器文件以除#shader vertex#shader fragment之外的其他任何文件开头,它将尝试访问ss[-1],索引到la-la land.将Shadertype::NONE设置为2并增大ss的大小:

Parseshader() is also rather fragile, since if a shader file starts with anything other than #shader vertex or #shader fragment it'll try to access ss[-1], indexing off into la-la land. Set Shadertype::NONE to 2 instead and bump up the size of ss:

static Shaderprogramsource Parseshader( const std::string& filepath )
{
    std::ifstream stream( filepath );

    enum class Shadertype
    {
        VERTEX = 0,
        FRAGMENT = 1,
        NONE = 2,
    };

    std::string line;
    std::stringstream ss[ 3 ];

    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 Shaderprogramsource{ ss[ 0 ].str(), ss[ 1 ].str() };
}

一起:


Basic.Shader:

#shader vertex
#version 330 core

layout(location = 0) in vec3 position;

void main()
{
    gl_Position = vec4(position.x, position.y, position.z, 1.0);
};

#shader fragment
#version 330 core

out vec4 color;

void main()
{
    color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
};

主程序:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>

struct Shaderprogramsource
{
    std::string VertexSouce;
    std::string FragmentSource;
};

static Shaderprogramsource Parseshader( const std::string& filepath )
{
    std::ifstream stream( filepath );

    enum class Shadertype
    {
        VERTEX = 0,
        FRAGMENT = 1,
        NONE = 2,
    };

    std::string line;
    std::stringstream ss[ 3 ];

    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 Shaderprogramsource{ ss[ 0 ].str(), ss[ 1 ].str() };
}

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

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

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

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

        std::cout << message;

        return 0;
    }

    return id;
}

static unsigned int CreateShader(
    const std::string& Vertexshader,
    const std::string& Fragmentshader )
{
    unsigned int program = glCreateProgram();
    unsigned int vertex = CompileShader( GL_VERTEX_SHADER, Vertexshader );
    unsigned int fragment = CompileShader( GL_FRAGMENT_SHADER, Fragmentshader );

    glAttachShader( program, vertex );
    glAttachShader( program, fragment );

    glLinkProgram( program );
    glValidateProgram( program );

    return program;
}

int main( void )
{
    GLFWwindow* window;

    /* Initialize the library */
    if( !glfwInit() )
        return -1;

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow( 640, 480, "Hello World", NULL, NULL );
    if( !window )
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent( window );

    if( GLEW_OK == glewInit() )
    {
    }

    float vertices[ 6 ] = { -0.5, -0.5, 0.0, 0.5, 0.5, 0.5 };

    unsigned int buffer1;

    glGenBuffers( 1, &buffer1 );
    glBindBuffer( GL_ARRAY_BUFFER, buffer1 );
    glBufferData(
        GL_ARRAY_BUFFER, 6 * sizeof( float ), vertices, GL_STATIC_DRAW );

    glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof( float ) * 2, 0 );

    glEnableVertexAttribArray( 0 );

    Shaderprogramsource source = Parseshader( "Basic.Shader" );

    unsigned int shader =
        CreateShader( source.VertexSouce, source.FragmentSource );
    glUseProgram( shader );

    /* Loop until the user closes the window */
    while( !glfwWindowShouldClose( window ) )
    {
        /* Render here */
        glClearColor( 0.2f, 0.3f, 0.3f, 1.0f );
        glClear( GL_COLOR_BUFFER_BIT );

        glUseProgram( shader );
        glDrawArrays( GL_TRIANGLES, 0, 3 );

        /* Swap front and back buffers */
        glfwSwapBuffers( window );

        /* Poll for and process events */
        glfwPollEvents();
    }

    glDeleteProgram( shader );

    glfwTerminate();
    return 0;
}

这篇关于在OpenGL着色器文件三角形中获取随机错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-27 15:57