【问题标题】:glAttribLocation returning -1 even though vertex shader is actively using thatglAttribLocation 返回 -1 即使顶点着色器正在积极使用它
【发布时间】:2018-08-21 15:37:06
【问题描述】:

在 Stack Overflow 上搜索类似问题以寻找我的解决方案,但似乎没有得到解决。

main.cpp:

#include"reader.h"
#include"window.h"
#include"shader.h"
int main() {

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

Window window;

GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

Shader shader;
shader.addShader("./src/shaders/basic.vtx",GL_VERTEX_SHADER);
shader.addShader("./src/shaders/basic.frg", GL_FRAGMENT_SHADER);
shader.compile();
shader.enable();


GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,GL_STATIC_DRAW);

GLint pos_in = glGetAttribLocation(shader.getProgram(), "pos_in");
if (pos_in < 0) {
    std::cout << "pos_in not found\n";
}
glVertexAttribPointer(pos_in, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
glEnableVertexAttribArray(pos_in);


while (!window.closed()) {
    window.update();
    glDrawArrays(GL_TRIANGLES,0,3);
}
return 0;
}

着色器.h:

#pragma once
#include<glad/glad.h>
#include<iostream>
#include<vector>
#include"reader.h"

class Shader {
std::vector<GLuint*> shaders;
GLuint program;

public :

GLuint& getProgram() { 
    return program; 
}

Shader() {
    program = glCreateProgram();
}
void addShader(const char * path, GLenum type) {

    std::string data = ShaderReader(path).read_shader();
    const char * chardata = data.c_str();
    GLuint shader = glCreateShader(type);
    glShaderSource(shader, 1, &chardata , nullptr);
    glCompileShader(shader);

    int success;
    char buffer[512];
    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(shader, 512, NULL, buffer);
        std::cout << buffer << std::endl;
        return;
    }
    std::cout << "shader inserted into vector\n";

    shaders.push_back(&shader);
}

void compile(){
    for (int i = 0; i != shaders.size();i++) {
        glAttachShader(program, *shaders[i]);
    }
    glLinkProgram(program);
    glValidateProgram(program);
    glUseProgram(program);
    int status;
    glGetProgramiv(program, GL_COMPILE_STATUS, &status);

    char buffer[512];
    if (!status) {
        glGetProgramInfoLog(program,512,NULL,buffer);
        std::cout << buffer << std::endl;
        return;
    }
    std::cout << "shader compilation successful\n";
}
void enable() {
    glUseProgram(program);
}
void disable() {
    glUseProgram(0);
}
~Shader() {
    for (int i = 0; i != shaders.size();i++) {
        glDeleteShader(*shaders[i]);
    }
}

};

用 basic.vtx 编写的顶点着色器:

#version 400 

layout (location = 0 ) in vec3 pos_in ;

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

用 basic.frg 编写的片段着色器:

#version 400

out vec4 color;

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

在调用 glGetAttribLocation 时,顶点着色器正在使用 pos_in 属性设置 gl_Position ,但它返回 -1 。 调用 glGetAttribLocation() 时也不会渲染三角形;或使用直接属性指针值(如 0 、 1 )呈现白色,并带有 openGL 1281 错误。

【问题讨论】:

    标签: c++ opengl


    【解决方案1】:

    绝对无效的一件事是shaders.push_back(&amp;shader)

    void addShader(const char * path, GLenum type) {
        // ....
    
        GLuint shader = glCreateShader(type);
    
        // ....
    
        shaders.push_back(&shader);
    }
    

    使用shaders.push_back(&amp;shader),您可以将局部变量的地址推回shaders 向量。所以glAttachShader(program, *shaders[i]); 会导致未定义的行为。

    shader 仅包含一个数字 id,因此无需获取指向它的指针,只需将 std::vector&lt;GLuint*&gt; shaders 更改为 std::vector&lt;GLuint&gt; shaders,使用 shaders.push_back(shader) 并将所有 *shaders[i] 替换为 shaders[i]

    您没有收到链接错误的原因很可能是因为您从&amp;shader 获得的地址处的内容在您执行glAttachShader(program, *shaders[i]) 之前没有被覆盖,并且着色器向量中的两个条目保持相同堆栈的地址。结果是glAttachShader每次都在同一个id上被调用,所以你只将片段着色器绑定到程序。

    【讨论】:

    • 非常感谢您的帮助....我按照您说的做了,之前的错误消失了。但是这一次,一个openGL错误1280被触发了。尝试在每一行中放置断点,似乎在绘图循环下调用 glDrawArrays() 是触发错误的原因。矩形还没有出现。
    • @pragi23 抱歉不知道,因此我需要仔细查看代码。但无论如何,这是一个不同的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多