Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 属性被编译器删除,但我可以';我不明白为什么_Opengl_Shader - Fatal编程技术网

Opengl 属性被编译器删除,但我可以';我不明白为什么

Opengl 属性被编译器删除,但我可以';我不明白为什么,opengl,shader,Opengl,Shader,我正在尝试编写一组着色器,以使用多个灯光和纹理进行逐顶点照明。我想我遇到了着色器编译器优化掉了“v_纹理”,这是我的属性变量之一,因为glVertexAttributeLocation无法找到它 以下是我的顶点着色器代码: attribute vec3 v_position; attribute vec3 v_normal; attribute vec2 v_texture; varying vec4 color; varying vec2 texCoord; const int MAX_L

我正在尝试编写一组着色器,以使用多个灯光和纹理进行逐顶点照明。我想我遇到了着色器编译器优化掉了“v_纹理”,这是我的属性变量之一,因为glVertexAttributeLocation无法找到它

以下是我的顶点着色器代码:

attribute vec3 v_position;
attribute vec3 v_normal;
attribute vec2 v_texture;

varying vec4 color;
varying vec2 texCoord;

const int MAX_LIGHTS = 8;

uniform struct lightSource
    {
    vec4 position;
    vec4 color;
    vec3 coneDirection;
    float coneAngle;
    float ambientFactor;
    } sceneLights[MAX_LIGHTS];

uniform mat4 modelView;
uniform mat4 Projection;
uniform float shininess;
uniform int numLights;

vec4 applyLight(lightSource light)
{
vec4 outColor;
float attenuation;

vec3 surfacePos = (modelView * vec4(v_position.xyz, 1.0)).xyz;

vec3 toLight;

if(light.position.w == 0.0)
    {
    toLight = normalize(light.position.xyz);
    attenuation = 1.0;
    }

else
    {
    toLight = normalize(light.position.xyz - surfacePos);

    float distanceToLight = length(light.position.xyz - surfacePos);
    float lightAngle = degrees(acos(dot(-surfacePos, normalize(light.coneDirection))));

    if(lightAngle > light.coneAngle)
        {
        attenuation = 0.0;
        }

    else
        {
        attenuation = 1.0/(1.0 + (0.1 * pow(distanceToLight, 2.0)));
        }
    }

vec3 Eye = normalize(-surfacePos);
vec3 Halfway = normalize(toLight + Eye);

vec3 worldNormal = normalize(modelView * vec4(v_normal, 0.0)).xyz;

vec4 ambient = vec4(light.ambientFactor * vec3(light.color.xyz), 1.0);

float Kd = max(dot(toLight, worldNormal), 0.0);
vec4 diffuse = Kd * light.color;

float Ks = pow(max(dot(worldNormal, Halfway), 0.0), shininess);
vec4 specular = Ks * light.color;
if(dot(toLight, worldNormal) < 0.0)
    {
    specular = vec4(0.0, 0.0, 0.0, 0.0);
    }

outColor = ambient + (attenuation * (diffuse + specular));
outColor.a = 1.0;
return outColor;
}

void main(void)
{
vec4 colorSum;

colorSum = vec4(0, 0, 0, 0);

for(int i = 0; i < MAX_LIGHTS; i++)
    {
    if(i >= numLights)
        {
        break;
        }
    colorSum += applyLight(sceneLights[i]);  
    }

colorSum.xyzw = normalize(colorSum.xyzw);

vec3 gammaCorrection = vec3(1.0/2.2);
color = vec4(pow(vec3(colorSum.xyz), gammaCorrection), 1.0);

texCoord = v_texture;

gl_Position = Projection * modelView * vec4(v_position.xyz, 1.0);
}
我对代码从头到尾都很熟悉,但我就是看不出我的问题在哪里。我将v_纹理指定给texCoord,并将其传递给frag着色器,在那里我将其与顶点着色器的最终照明结果一起使用,以生成最终颜色。我在编译时检查着色器错误,但没有得到任何结果。我目前唯一的猜测是,可能gl_FragColor=(color*texture2D(texSampler,texCoord.xy))不是一个有效的语句,但这不应该捕获它吗

glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &shader_status);
if (!shader_status) 
    {
    GLchar InfoLog[1024];
    glGetShaderInfoLog(fragment_shader, sizeof(InfoLog), NULL, InfoLog);
    fprintf(stderr, "Fragment Shader %d: '%s'\n", fragment_shader, InfoLog);
    }
<>编辑:我可能应该把它放在这里,但是这个片段是我的C++程序的初始化函数()的着色器部分。GLGetAttriblLocation调用中唯一一个失败的是v_纹理

// Begin shader loading.
    //compile the shaders
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
GLint shader_status;
pass=new char [2048];
unsigned int len;

//Give a maximum number of attempts to load the vertex shader 
int attempts=10;
//Load the vertex shader
do
    {

    loader.load("lighting.vsh");

    shaderCode = loader.hold.c_str();
    len=loader.length;
    pass=shaderCode;


    attempts-=1;
    }
while(len!=pass.length()&& attempts>0);

//Pass the temperary variable to a pointer
tmp = pass.c_str();


// Vertex shader first
glShaderSource(vertex_shader, 1,&tmp, NULL);
glCompileShader(vertex_shader);
//check the compile status
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &shader_status);
if (!shader_status) 
    {
    GLchar InfoLog[1024];
    glGetShaderInfoLog(vertex_shader, sizeof(InfoLog), NULL, InfoLog);
    fprintf(stderr, "Vertex Shader %d: '%s'\n", vertex_shader, InfoLog);
    }

const char *fs=loader.load("lighting.fsh");


// Now the Fragment shader
glShaderSource(fragment_shader, 1, &fs, NULL);
glCompileShader(fragment_shader);
//check the compile status
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &shader_status);
if (!shader_status) 
    {
    GLchar InfoLog[1024];
    glGetShaderInfoLog(fragment_shader, sizeof(InfoLog), NULL, InfoLog);
    fprintf(stderr, "Fragment Shader %d: '%s'\n", fragment_shader, InfoLog);
    }

//Now we link the 2 shader objects into a program
//This program is what is run on the GPU
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
//check if everything linked ok
glGetProgramiv(program, GL_LINK_STATUS, &shader_status);
  if(!shader_status)
    {
    std::cerr << "[F] THE SHADER PROGRAM FAILED TO LINK" << std::endl;
    return false;
    }

//Now we set the locations of the attributes and uniforms
//this allows us to access them easily while rendering
loc_position = glGetAttribLocation(program,
                const_cast<const char*>("v_position"));

if(loc_position == -1)
    {
    std::cerr << "Error: POSITION NOT FOUND IN SHADER" << std::endl;
    return false;
    }

loc_normals = glGetAttribLocation(program, const_cast<const char*>("v_normal"));

if(loc_normals == -1)
    {
    std::cerr << "Error: NORMALS NOT FOUND IN SHADER" << std:: endl;
    return false;
    }


loc_texture = glGetAttribLocation(program, const_cast<const char*>("v_texture"));

if(loc_texture == -1)
    {
    std::cerr << "[F] TEXTURE NOT FOUND IN SHADER" << std::endl;
    return false;
    }


// Begin light initialization.
//开始加载着色器。
//编译着色器
GLuint vertex_着色器=glCreateShader(GL_vertex_着色器);
GLuint fragment_shader=glCreateShader(GL_fragment_shader);
闪烁状态;
通过=新字符[2048];
无符号整数len;
//指定加载顶点着色器的最大尝试次数
int=10;
//加载顶点着色器
做
{
loader.load(“lighting.vsh”);
shaderCode=loader.hold.c_str();
len=装载机长度;
通过=着色器代码;
尝试次数-=1;
}
while(len!=pass.length()&尝试次数>0);
//将临时变量传递给指针
tmp=pass.c_str();
//顶点着色器优先
glShaderSource(顶点着色器,1,&tmp,NULL);
glCompileShader(顶点着色器);
//检查编译状态
glGetShaderiv(顶点着色器、GL着色器编译状态和着色器状态);
如果(!着色器_状态)
{
GLchar信息日志[1024];
glGetShaderInfoLog(顶点着色器,sizeof(InfoLog),NULL,InfoLog);
fprintf(标准,“顶点着色器%d:“%s”\n”,顶点着色器,信息日志);
}
const char*fs=loader.load(“lighting.fsh”);
//现在是片段着色器
glShaderSource(片段着色器,1,&fs,NULL);
glCompileShader(片段着色器);
//检查编译状态
glGetShaderiv(片段着色器、GL编译状态和着色器状态);
如果(!着色器_状态)
{
GLchar信息日志[1024];
glGetShaderInfoLog(片段着色器,sizeof(InfoLog),NULL,InfoLog);
fprintf(stderr,“片段着色器%d:“%s”\n”,片段着色器,信息日志);
}
//现在我们将两个着色器对象链接到一个程序中
//这个程序是在GPU上运行的
program=glCreateProgram();
glAttachShader(程序,顶点着色器);
glAttachShader(程序,片段着色器);
glLinkProgram(program);
//检查所有链接是否正常
glGetProgramiv(程序、GL链接状态和着色器状态);
如果(!着色器_状态)
{

您是否尝试过对着色器进行颜色调试?尝试:gl_FragColor=vec4(texCoord,0.0,1.0);如果使用此选项获得不同的颜色,则错误在于纹理设置。如果仅获得一种颜色,则传递的texCoords错误。我刚刚尝试了此选项,但GlGetAttriblLocation仍然返回-1。这说明了什么吗?很有趣;我在这里看到了很多代码,但没有看到您实际调用GlGetAttriblLocation。啊,抱歉,我经常这样做我只需要提交我的着色器代码,因为我认为编译器剔除的属性非常常见,相关部分就是着色器中发生的任何事情。我将在中编辑一些内容。这就是为什么你需要学习使用调试器:p它会告诉你执行的代码不是你正在编辑的代码!你尝试过使用颜色调试吗你的着色器?试试:gl_FragColor=vec4(texCoord,0.0,1.0);如果使用此选项获得不同的颜色,则错误在于纹理设置。如果仅获得一种颜色,则传递的texCoords错误。我刚刚尝试了此选项,但GlGetAttriblLocation仍然返回-1。这说明了什么吗?很有趣;我在这里看到了很多代码,但没有看到您实际调用GlGetAttriblLocation。啊,抱歉,我经常这样做我只需要拿出我的着色器代码,因为我认为编译器剔除的属性足够常见,相关部分就是着色器中发生的任何事情。我将在中编辑一些内容。这就是为什么你需要学习使用调试器:p它会告诉你执行的代码不是你正在编辑的代码!
// Begin shader loading.
    //compile the shaders
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
GLint shader_status;
pass=new char [2048];
unsigned int len;

//Give a maximum number of attempts to load the vertex shader 
int attempts=10;
//Load the vertex shader
do
    {

    loader.load("lighting.vsh");

    shaderCode = loader.hold.c_str();
    len=loader.length;
    pass=shaderCode;


    attempts-=1;
    }
while(len!=pass.length()&& attempts>0);

//Pass the temperary variable to a pointer
tmp = pass.c_str();


// Vertex shader first
glShaderSource(vertex_shader, 1,&tmp, NULL);
glCompileShader(vertex_shader);
//check the compile status
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &shader_status);
if (!shader_status) 
    {
    GLchar InfoLog[1024];
    glGetShaderInfoLog(vertex_shader, sizeof(InfoLog), NULL, InfoLog);
    fprintf(stderr, "Vertex Shader %d: '%s'\n", vertex_shader, InfoLog);
    }

const char *fs=loader.load("lighting.fsh");


// Now the Fragment shader
glShaderSource(fragment_shader, 1, &fs, NULL);
glCompileShader(fragment_shader);
//check the compile status
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &shader_status);
if (!shader_status) 
    {
    GLchar InfoLog[1024];
    glGetShaderInfoLog(fragment_shader, sizeof(InfoLog), NULL, InfoLog);
    fprintf(stderr, "Fragment Shader %d: '%s'\n", fragment_shader, InfoLog);
    }

//Now we link the 2 shader objects into a program
//This program is what is run on the GPU
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
//check if everything linked ok
glGetProgramiv(program, GL_LINK_STATUS, &shader_status);
  if(!shader_status)
    {
    std::cerr << "[F] THE SHADER PROGRAM FAILED TO LINK" << std::endl;
    return false;
    }

//Now we set the locations of the attributes and uniforms
//this allows us to access them easily while rendering
loc_position = glGetAttribLocation(program,
                const_cast<const char*>("v_position"));

if(loc_position == -1)
    {
    std::cerr << "Error: POSITION NOT FOUND IN SHADER" << std::endl;
    return false;
    }

loc_normals = glGetAttribLocation(program, const_cast<const char*>("v_normal"));

if(loc_normals == -1)
    {
    std::cerr << "Error: NORMALS NOT FOUND IN SHADER" << std:: endl;
    return false;
    }


loc_texture = glGetAttribLocation(program, const_cast<const char*>("v_texture"));

if(loc_texture == -1)
    {
    std::cerr << "[F] TEXTURE NOT FOUND IN SHADER" << std::endl;
    return false;
    }


// Begin light initialization.