简体   繁体   English

OpenGL的SFML着色器错误

[英]SFML shader error with OpenGL

I've been trying to implement very simple shaders into my OpenGL. 我一直在尝试在OpenGL中实现非常简单的着色器。 Unfortunately I keep running into: 不幸的是,我一直遇到:

Cannot access private member declared in class 'sf::NonCopyable

I have tried figuring this out by myself, and I think that somewhere I am re declaring sf::Shader somewhere. 我尝试自己解决这个问题,我认为我在某处声明sf :: Shader。

sf::Shader compile_shaders(void)
{
sf::Shader shader;

const std::string vertex_shader_source = \
    "#version 430 core  "\
    "                   "\
    "void main(void){   "\
    "   gl_position = vec4(0.0, 0.0, 0.5, 1.0);"\
    "}                  ";

const std::string fragment_shader_source = \
    "#version 430 core                  "\
    "                                   "\
    "out vec4 color;                    "\
    "                                   "\
    "void main(void){                   "\
    "   color = vec4(0.0, 0.8, 1.0, 1.0);"\
    "}                                  ";

shader.loadFromMemory(vertex_shader_source, fragment_shader_source);

return shader;
}

int main(){
int width = 800;
int height = 450;
sf::Window window(sf::VideoMode(width, height), "OpenGL Test", sf::Style::Default, sf::ContextSettings(32));

resize(width, height);
init();
window.setVerticalSyncEnabled(true);


sf::Shader shader = compile_shaders();


bool running = true;
while (running){
    sf::Event event;
    while (window.pollEvent(event)){
        if (event.type == sf::Event::Closed)
            running = false;
        else if (event.type == sf::Event::Resized){
            width = event.size.width;
            height = event.size.height;
            resize(width, height);
        }
        else if (event.type == sf::Event::KeyPressed & event.key.code == sf::Keyboard::Escape)
            running = false;
    }
    sf::Shader::bind(&shader);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glTranslatef(-1.5f,0.0f,-6.0f);

    glBegin(GL_TRIANGLES);

        glColor3f(1.0f,0.0f,0.0f);
        glVertex3f( 0.0f, 1.0f, 0.0f);

        glColor3f(0.0f,1.0f,0.0f);
        glVertex3f(-1.0f,-1.0f, 0.0f);

        glColor3f(0.0f,0.0f,1.0f);
        glVertex3f( 1.0f,-1.0f, 0.0f);
    glEnd();

    glTranslatef(3.0f, 0.0f, 0.0f);

    glColor3f(0.5f,0.5f,1.0f);
    glBegin(GL_QUADS);
        glVertex3f(-1.0f, 1.0f, 0.0f);
        glVertex3f( 1.0f, 1.0f, 0.0f);
        glVertex3f( 1.0f,-1.0f, 0.0f);
        glVertex3f(-1.0f,-1.0f, 0.0f);
    glEnd();
    window.display();

    sf::Shader::bind(NULL);
}

return 0;
}

resize() and init() are just setting up some OpenGL variables, so I'm pretty sure they are not the problem. resize()和init()只是设置了一些OpenGL变量,所以我很确定它们不是问题。

Looks like a design oversight by the sfml guys. 看起来像是sfml家伙的设计监督。 This would work if sf::Shader would implement a move constructor. 如果sf::Shader实现了move构造函数,这将起作用。 As it stands you can't move or copy a sf::Shader because its copy constructor is declared private and no move constructor is defined. 就目前而言,您无法移动或复制sf::Shader因为其复制构造函数被声明为私有,并且未定义任何移动构造函数。

All you can do is allocate it on the heap and return a pointer to it from the function. 您所能做的就是在堆上分配它,并从函数返回指向它的指针。

I would recommend you use 我建议您使用

std::unique_ptr<sf::Shader> compile_shaders(void){
    auto shader = std::make_unique<sf::Shader>();
    //or auto shader = std::unique_ptr<sf::Shader>(new sf::Shader()); if you don't have make_unique available

    //... code ommitted                   

    shader->loadFromMemory(vertex_shader_source, fragment_shader_source);

    return shader;
}

and then make the call with 然后用

auto shader = compile_shaders();
//... code omitted
sf::Shader::bind(shader.get());

If you want to pass around the shader some more use a std::shared_ptr instead of std::unique_ptr 如果您想传递着色器更多信息,请使用std::shared_ptr而不是std::unique_ptr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM