【问题标题】:SFML - Opengl VAO issue giving me an (1282) errorSFML - Opengl VAO 问题给我一个(1282)错误
【发布时间】:2015-11-24 17:58:27
【问题描述】:

我在尝试在 SFML 中使用 VAO 时遇到错误,并且不确定它是 SFML 还是我自己的 opengl 代码

GLenum err = glewInit();
if (err != GLEW_OK)
{
    std::cout << "NOT WORKING" << std::endl;
}
    std::vector<sf::Vector3f> g_vertext_buffer_data;
g_vertex_buffer_data.push_back({ -1.0f, -1.0f, 0.0f });
g_vertex_buffer_data.push_back({1.0f, -1.0f, 0.0f});
g_vertex_buffer_data.push_back({ 0.0f, 1.0f, 0.0f });

const char* vertexShaderSource =
    "#version 330\n\
                             in vec4 position;\
                                                  void main(void){\                                                                                     gl_Position = position;\
                                                                                                         }";
// compile fragment shader source
const GLchar* fragmentShaderSource = 
    "#version 330\n\
                                    void main(void) {\
                out vec4 fragcolor;                                         fragcolor= vec4(1.0,1.0,1.0,1.0);\
                                                                                                     }";

/* Creating Shader */
this->programId = glCreateProgram();
this->vId = glCreateShader(GL_VERTEX_SHADER);
this->fId = glCreateShader(GL_FRAGMENT_SHADER);
/* Get Shader Size */
int vertexShaderLength = strlen(vertexShaderSource);
int fragmentShaderLength = strlen(fragmentShaderSource);

/* Loading and binding shader */
glShaderSource(this->vId, 1, &vertexShaderSource, NULL);
glShaderSource(this->fId, 1, &fragmentShaderSource, NULL);

/* Compile Shaders */
glCompileShader(vId);
glCompileShader(fId);
/* Attach Shaders */
glAttachShader(this->programId, this->vId);
glAttachShader(this->programId, this->fId);

/* Linkg program */
glLinkProgram(this->programId);
/* Use and bind attribute */
glUseProgram(this->programId);
this->positionId = glGetAttribLocation(this->programId, "position");
glUseProgram(0);
/* VAO Time */
glGenVertexArrays(1, &this->vaoId);
glBindVertexArray(this->vaoId);

/* VBO Time assigning to VAO */
glGenBuffers(1, &this->vboId);
glBindBuffer(GL_ARRAY_BUFFER, this->vboId);
glBufferData(GL_ARRAY_BUFFER, g_vertex_buffer_data.size() * sizeof(sf::Vector3f), &g_vertex_buffer_data[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(this->positionId);
glVertexAttribPointer(this->positionId, 2, GL_FLOAT, GL_FALSE, sizeof(sf::Vector3f), 0);

/* Close out bindings */
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
  while(1)
  {
glUseProgram(this->programId);
glBindVertexArray(this->vaoId);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);    
 gameWindow.glPushStates();
  }

我得到的错误代码是:opengl error in user code (1282)​

我已经更改了在 blBufferData() 中提出的 size() 问题,但问题仍然存在。

【问题讨论】:

  • 欢迎来到 SO!请把这些代码片段组装成一个MVCE,否则我们将不得不猜测未显示的代码中会发生什么。
  • 这是opengGl代码中使用的所有代码。因为我不确定问题出在哪里,所以我只包含了所有的 OpenGL 代码
  • 这里已经很好地定义了什么被认为是 MVCE,没有它,你的问题就没有发生。我不会花时间编写测试应用程序以使您的代码片段可运行,我怀疑其他人会这样做。

标签: c++ opengl sfml opengl-3 opengl-4


【解决方案1】:

传递给glBufferData的大小至少有问题:

glBufferData(GL_ARRAY_BUFFER,
             sizeof(g_vertex_buffer_data) * sizeof(sf::Vector3f), 
             g_vertex_buffer_data[0], GL_STATIC_DRAW);

sizeof(g_vertex_buffer_data) 等于sizeof(std::vector&lt;?&gt;),这是向量对象的大小,而不是包含的数据的大小。尝试使用

    glBufferData(GL_ARRAY_BUFFER,
             g_vertex_buffer_data.size() * sizeof(sf::Vector3f), 
             g_vertex_buffer_data[0], GL_STATIC_DRAW);

另一件事:在 OpenGL 3.3 Core Profile 中没有 gl_FragColor 变量。您必须定义一个输出变量。

下一步:您的顶点着色器似乎是空的。你必须写信给gl_Position,否则什么都不会显示。

【讨论】:

  • 我编辑了代码,但仍然遇到问题并收到 1282 错误。还有其他想法吗?
  • 找出错误发生在哪一行。尝试移动 glGetError 直到您知道哪个 OpenGL 命令导致错误。
  • 好的,所以我的片段着色器中出现着色器编译错误,但我的顶点着色器没问题。但是 glError() 返回 0
  • 好的,所以我已经解决了一些问题,但我仍然在以下行的用户代码中检测到 1282 opengl 错误:game.gameWindow.pushGLStates();
【解决方案2】:

glGetAttribLocation 的可能错误代码是:

GL_INVALID_OPERATION

没有固定值。尝试使用 gluErrorString() 获取错误字符串或查看标头中的 1282 个映射。

• 检查您的着色器是否正确编译?

• 检查您的着色器是否正确链接?

positionId 是什么类型的?所有对象 id 必须是 GLuint 类型。

顺便说一句,总是启用着色器编译链接错误检查,调试会提供更多信息。

我是这样做的(OpenGL-ES 2.0):

    m_nVertexShader = glCreateShader(GL_VERTEX_SHADER);
    m_nPixelShader = glCreateShader(GL_FRAGMENT_SHADER);


    glShaderSource(m_nVertexShader, 1, &lpszVertexBuffer, NULL);
    glShaderSource(m_nPixelShader, 1, &lpszFragmentBuffer, NULL);

    glCompileShader(m_nVertexShader);

    int iIsOk = 0;

    glGetShaderiv(m_nVertexShader, GL_COMPILE_STATUS, &iIsOk);

    if(!iIsOk)
    {
        GLint infoLen = 0;

        glGetShaderiv(m_nVertexShader, GL_INFO_LOG_LENGTH, &infoLen);

        if(infoLen > 1)
        {
            char* infoLog = (char*)malloc(sizeof(char) * infoLen);

            glGetShaderInfoLog(m_nVertexShader, infoLen, NULL, infoLog);


            QMessageBox::warning(this, QString("Error"),
                                 QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);

            free(infoLog);
        }

        glDeleteShader(m_nVertexShader);

        return;
    }

    glCompileShader(m_nPixelShader);

    glGetShaderiv(m_nPixelShader, GL_COMPILE_STATUS, &iIsOk);

    if(!iIsOk)
    {
        GLint infoLen = 0;

        glGetShaderiv(m_nPixelShader, GL_INFO_LOG_LENGTH, &infoLen);

        if(infoLen > 1)
        {
            char* infoLog = (char*)malloc(sizeof(char) * infoLen);

            glGetShaderInfoLog(m_nPixelShader, infoLen, NULL, infoLog);


            QMessageBox::warning(this, QString("Error"),
                                 QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);

            free(infoLog);
        }

        glDeleteShader(m_nPixelShader);

        return;
    }

    m_nProgram = glCreateProgram();

    glAttachShader(m_nProgram, m_nVertexShader);
    glAttachShader(m_nProgram, m_nPixelShader);

    glBindAttribLocation(m_nProgram, 0, "rm_Vertex");

    glLinkProgram(m_nProgram);

    glGetProgramiv(m_nProgram, GL_LINK_STATUS, &iIsOk);

    // Fail to pass status validation
    if(!iIsOk)
    {
        GLint infoLen = 0;

        glGetProgramiv(m_nProgram, GL_INFO_LOG_LENGTH, &infoLen);

        if(infoLen > 1)
        {
            char* infoLog = (char*)malloc(sizeof(char) * infoLen);

            glGetProgramInfoLog(m_nProgram, infoLen, NULL, infoLog);


            QMessageBox::warning(this, QString("Error"),
                                 QString(infoLog), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);

            free(infoLog);
        }

        glDeleteProgram(m_nProgram);

        return;
    }

    glUseProgram(m_nProgram);

当您使用 GLSL 3.3 时,首先您必须通过调用指定片段渲染目标输出

glBindFragDataLocation(this->programId, 0, "fragcolor");

其次,你的片段着色器必须像

"#version 330
out vec4 fragcolor;

void main(void) {
     fragcolor= vec4(1.0,1.0,1.0,1.0); 
}

使用这种着色器的例子在OpenGL 3.3 + GLSL 1.5 Sample

【讨论】:

  • 好的,所以我继续在 gLinkProgram: glBindAttribLocation(this->programId, 0, "position") ... 但我仍然遇到同样的错误。
  • @user5600884:positionId 有什么类型?
  • 1282 是 GL_INVALID_OPERATION
  • 好的,所以当我使用着色器编译检查顶点着色器编译正常,但片段着色器编译不正常。
  • @user5600884:这是问题,请将您的片段着色器代码粘贴到您的问题中,我们将对其进行调查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多