glGetAttribLocation在检索现有着色器属性时返回-1 [英] glGetAttribLocation returns -1 when retrieving existing shader attribute

查看:1681
本文介绍了glGetAttribLocation在检索现有着色器属性时返回-1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图传递属性到我的顶点着色器,但由于某种原因它不断给我一个-1的第三个属性位置我要求openGl通过glGetAttribLocation()检索。目前它给我一个-1的texCoord属性,如果我切换texAttrib和colAttrib(切换代码中的行),它给我一个-1颜色属性,而不是纹理,我不知道为什么?因为-1被传递给glVertexAttribPointer,我得到了1281的OpenGL错误:GL_INVALID_VALUE。



我的顶点着色器:

  #version 150 

在vec3位置;
in vec3 color;
in vec2 texcoord;

out vec3颜色
out vec2 Texcoord;

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

OpenGL代码:

  basicShader.Use(); 

//缓冲区和着色器
glGenVertexArrays(1,& vao);
glBindVertexArray(vao);

glGenBuffers(1,& vbo);
//使其有效vbo
glBindBuffer(GL_ARRAY_BUFFER,vbo);

//构建基本三角形
float vertices [] = {
//位置//颜色//纹理
-0.5f,0.5f,0.5f, 1.0f,0.0f,0.0f,0.0f,0.0f,//左上角
0.5f,0.5f,0.5f,0.0f,1.0f,0.0f,1.0f,0.0f,右上角
0.5f,-0.5f,0.5f,0.0f,0.0f,1.0f,1.0f,1.0f,//右下角
-0.5f,-0.5f,0.5 f,1.0f,1.0f,1.0f,0.0f,1.0f //左下
};
GLuint elements [] = {
0,1,2,
2,3,0
};

glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);

GLint posAttrib = glGetAttribLocation(basicShader.shaderProgram,position);
glEnableVertexAttribArray(posAttrib); //在指定属性之前启用属性
glVertexAttribPointer(posAttrib,3,GL_FLOAT,GL_FALSE,8 * sizeof(float),0); // 6 float sizes is every new vertex

GLint colAttrib = glGetAttribLocation(basicShader.shaderProgram,color);
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib,3,GL_FLOAT,GL_FALSE,8 * sizeof(float),(void *)(3 * sizeof(float))); // same for color + offset

GLint texAttrib = glGetAttribLocation(basicShader.shaderProgram,texcoord); // Returns -1
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib,2,GL_FLOAT,GL_FALSE,8 * sizeof(float),(void *)(6 * sizeof(float))) // 6 offset from beginning

[..]


解决方案

您应该停止使用 glGetAttribLocation 分配每个属性的位置,可以使用 glBindAttribLocation code>在链接程序或显式属性位置之前,如果这是可用的。



这样,如果编译器优化一个属性发生在这里;你的片段着色器可能不使用内插值之一),你不会在乎。您将使用属性索引的标准约定,正常设置数组。此外,您不必每次都想要使用不同的程序来询问什么是属性位置;

如果您不能/不会,那么您无法执行任何操作。如果你实际上没有使用它们,编译器会优化属性。你唯一可以做的就是检测它返回-1,而不是为该属性设置数组。


I'm trying to pass in attributes to my vertex shader but for some reason it keeps giving me a -1 on the 3rd attribute location I'm asking openGl to retrieve via glGetAttribLocation(). Currently it keeps giving me a -1 for the texCoord attribute and if I switch the texAttrib and colAttrib around (switching the lines in code) it gives me a -1 on the color property instead of the texture and I have no idea why? Since a -1 is being passed to glVertexAttribPointer I get the 1281 OpenGL error: GL_INVALID_VALUE.

My vertex shader:

#version 150

in vec3 position;
in vec3 color;
in vec2 texcoord;

out vec3 Color;
out vec2 Texcoord;

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

OpenGL code:

basicShader.Use();

// Buffers and shaders
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glGenBuffers(1, &vbo);
// Make it active vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo);

// Build basic triangle
float vertices[] = {
    // position         // color          // textures
    -0.5f,  0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left
     0.5f,  0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right
     0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right
    -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f// Bottom-left
};
GLuint elements[] = {
    0, 1, 2,
    2, 3, 0
};

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

GLint posAttrib = glGetAttribLocation(basicShader.shaderProgram, "position");
glEnableVertexAttribArray(posAttrib); // Enable attribute first before specifiying attributes
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), 0); // 6 float sizes is every new vertex

GLint colAttrib = glGetAttribLocation(basicShader.shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); // same for color + offset

GLint texAttrib = glGetAttribLocation(basicShader.shaderProgram, "texcoord"); // Returns -1
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); // 6 offset from beginning

[..]

解决方案

You should stop using glGetAttribLocation. Assign each attribute a location, either with glBindAttribLocation before linking the program or with explicit attribute locations, if that's available to you.

That way, if the compiler optimizes an attribute away (which is what's happening here; your fragment shader probably doesn't use one of the interpolated values), you won't care. You'll set up your arrays as normal, using a standard convention for attribute indices. Plus, you won't have to keep asking what an attribute location is every time you want to render with a different program; you know what location it is because you assigned it.

If you can't/won't, then there's nothing you can do. The compiler will optimize away attributes if you're not actually using them. The only thing you can do is detect that it returns -1 and not set up the array for that attribute.

这篇关于glGetAttribLocation在检索现有着色器属性时返回-1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆