【问题标题】:GLSL 330 core not supported不支持 GLSL 330 内核
【发布时间】:2018-07-09 16:49:43
【问题描述】:

所以我基本上是 OpenGL 的初学者,我试图创建自己的着色器来形成一个简单的三角形。在这样做的过程中,我使用 SDL 创建窗口(正如您在随附的屏幕截图中看到它已成功加载),即使本教程使用了 glfw3 并且很高兴(我不得不求助于 SDL,因为我无法有效地包含后者库)。它一直给我以下错误

"不支持 GLSL。支持的版本有:1.10, 1.20, 1.30, ... 3.20 ES"

SDL 是问题的原因吗?

操作系统:Ubuntu 18.04; IDE:代码块;

main.cpp

#include <iostream>
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include "display.h"

using namespace std;
const char *vertexShaderSource = "#version 330 core\n"
    "layout (location = 0) in vec3 aPos;\n"
    "void main()\n"
    "{\n"
        "gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0f)\n"
    "}\0";
const char *fragmentShaderSource = "#version 330 core\n"
    "out vec4 FragColor;\n"
    "void main()\n"
    "{\n"
        "FragColor = vec4(1.0f,0.5f,0.2f,1.0f);\n"
    "}\0";
int main()
{
    Display display(800,600,"Moiz");
    while(!display.isClosed())
    {
        glClearColor(0.0f,0.15f,0.3f,1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        display.Update();
        int vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1 , &vertexShaderSource, NULL);
        glCompileShader(vertexShader);
        int success;
        char infoLog[512];
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
        }
        int 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::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
        }
    }
    return 0;
}

显示.cpp

#include <iostream>
#include <string>
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include "display.h"

using namespace std;

Display::Display(int width, int height,const string &title)
{
    SDL_Init(SDL_INIT_EVERYTHING);


    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
    SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    m_window = SDL_CreateWindow(title.c_str(),SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,width,height,SDL_WINDOW_OPENGL);
    m_glContext = SDL_GL_CreateContext(m_window);
    GLenum status = glewInit();
    if(status != GLEW_OK)
    {
        std::cerr << "GLEW FAILED TO INITIALIZE" << endl;
    }
}
bool Display::isClosed(){
    return m_isClosed;
}
void Display::Update()
{
    SDL_GL_SwapWindow(m_window);
    SDL_Event e;
    while(SDL_PollEvent(&e))
    {
        if(e.type == SDL_QUIT)
        {
            m_isClosed = true;
        }
    }
}

Display::~Display()
{
    SDL_GL_DeleteContext(m_glContext);
    SDL_DestroyWindow(m_window);
    SDL_Quit();
}

Display::Display(const Display& other)
{
    //copy ctor
}

Display& Display::operator=(const Display& rhs)
{
    if (this == &rhs) return *this; // handle self assignment
    //assignment operator
    return *this;
}

:错误图片

Error Screenshot

【问题讨论】:

  • 查找您的图形驱动程序规格。这会有所帮助。
  • Supported versions are: 1.10, 1.20, 1.30, ... 3.20 ES 尝试其中之一。
  • minimal reproducible example 中编辑。无法说出“Display”可能犯了什么罪。据我们所知,它可能根本不会请求 Core 上下文。
  • 我没有看到你提前打电话给SDL_Init,也没有看到你用来请求GL 3.3核心上下文的参数。
  • 查看wiki example,了解如何使用 SDL 创建 Core Profile 上下文

标签: c++ opengl glsl shader sdl


【解决方案1】:
  • 在您的顶点着色器中,vec4 后面缺少一个分号
  • 如果您使用 Mesa,请注意(从历史上看;在过去几周/几个月中,某些驱动程序已经发生了变化),如果您请求 Core 上下文,它只会分发 >3.0 的 GL 上下文。您可以使用SDL_GL_SetAttribute() 使SDL_CreateWindow() 请求一个:

    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 );
    SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
    

所有在一起(这就是我所说的MCVE:单个文件,仅取决于 SDL/GLEW/GLM/GLFW 等知名库):

#include <iostream>
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include <iostream>
#include <string>

class Display
{
public:
    Display( int width, int height, const std::string &title )
        : m_isClosed( false )
    {
        SDL_Init( SDL_INIT_EVERYTHING );

        SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
        SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
        SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
        SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
        SDL_GL_SetAttribute( SDL_GL_BUFFER_SIZE, 32 );
        SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

        SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
        SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 3 );
        SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );

        m_window = SDL_CreateWindow
            (
            title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
            width, height,
            SDL_WINDOW_OPENGL
            );
        m_glContext = SDL_GL_CreateContext( m_window );
        GLenum status = glewInit();
        if( status != GLEW_OK )
        {
            std::cerr << "GLEW FAILED TO INITIALIZE" << std::endl;
        }
    }

    bool isClosed()
    {
        return m_isClosed;
    }

    void Update()
    {
        SDL_GL_SwapWindow( m_window );
        SDL_Event e;
        while( SDL_PollEvent( &e ) )
        {
            if( e.type == SDL_QUIT )
            {
                m_isClosed = true;
            }
        }
    }

    ~Display()
    {
        SDL_GL_DeleteContext( m_glContext );
        SDL_DestroyWindow( m_window );
        SDL_Quit();
    }

    Display( const Display& other )
    {
        //copy ctor
    }

    Display& operator=( const Display& rhs )
    {
        if( this == &rhs ) return *this; // handle self assignment
        //assignment operator
        return *this;
    }

private:
    SDL_Window* m_window;
    SDL_GLContext m_glContext;
    bool m_isClosed;
};

const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0f);\n"
"}\0";
const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(1.0f,0.5f,0.2f,1.0f);\n"
"}\0";

int main( int argc, char** argv )
{
    Display display( 800, 600, "Moiz" );
    while( !display.isClosed() )
    {
        glClearColor( 0.0f, 0.15f, 0.3f, 1.0f );
        glClear( GL_COLOR_BUFFER_BIT );
        display.Update();
        int vertexShader = glCreateShader( GL_VERTEX_SHADER );
        glShaderSource( vertexShader, 1, &vertexShaderSource, NULL );
        glCompileShader( vertexShader );
        int success;
        char infoLog[ 512 ];
        glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &success );
        if( !success )
        {
            glGetShaderInfoLog( vertexShader, 512, NULL, infoLog );
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
        }
        int 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::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
        }
    }
    return 0;
}

此外,请务必检查 SDL_CreateWindow()SDL_GL_CreateContext() 是否返回有效值。

【讨论】:

  • 哦,它成功了。谢啦。听听这一行做了什么 SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
  • @MoizSohail:见SDL_GL_SetAttribute() wiki docs。这在 SDL 内部设置了一点,当它创建窗口时,通过来自操作系统的系统适当的 ARB_create_context 扩展,使下一个 SDL_CreateWindow() 调用请求成为 Core GL context
猜你喜欢
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
  • 2012-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多