Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/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
C++ Can';无法在OpenGL中获取分配给属性的ID_C++_C_Opengl_Glsl_Shader - Fatal编程技术网

C++ Can';无法在OpenGL中获取分配给属性的ID

C++ Can';无法在OpenGL中获取分配给属性的ID,c++,c,opengl,glsl,shader,C++,C,Opengl,Glsl,Shader,我试图让OpenGL自动为glsl属性分配一个ID,但失败了 我的主要节目: #include <iostream> #include <GL/glew.h> #include <GL/glfw3.h> #include "test.h" #include "shader_utils.h" static void error_callback(int error, const char* description) { std::cout <

我试图让OpenGL自动为glsl属性分配一个ID,但失败了

我的主要节目:

#include <iostream>

#include <GL/glew.h>
#include <GL/glfw3.h>

#include "test.h"
#include "shader_utils.h"

static void error_callback(int error, const char* description) {
    std::cout << description << std::endl;
}

static void key_callback(GLFWwindow* window, int a, int b) {
    if (a == GLFW_KEY_ESCAPE && b == GLFW_PRESS) {
        glfwSetWindowShouldClose(window, GL_TRUE);
    }
}

void test()
{
    std::cout << "Starting up" << std::endl;
    init();
    run();
}

GLFWwindow *window;
GLuint shaders;
GLuint vertexBuffer;

int init() {
    glfwSetErrorCallback(error_callback);

    if(!glfwInit()) {
        return -1;
    }

    window = glfwCreateWindow(640, 480, "GLFW test", NULL, NULL);
    if (!window)  {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetKeyCallback(window, key_callback);

    glewExperimental = true;
    glewInit();

    shaders = LoadShaders("vertex.glsl", "fragment.glsl");

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


    static const GLfloat vertex_data[] = {
        // Bottom
        -.5f, -.5f, -.5f,   1.f, 0.f, 0.f,
        -.5f, -.5f,  .5f,   1.f, 0.f, 0.f,
         .5f, -.5f,  .5f,   1.f, 0.f, 0.f,
    };

    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
}

void checkE() {
    std::cout << "Checking for errors: ";
    int err;
    int a = 0;
    while((err = glGetError()) != GL_NO_ERROR) {
        std::cout << "Error: " << err << std::endl;
        a = 1;
    }

    if(a == 0) {
        std::cout << "no errors" << std::endl;
    }
    std::cout.flush();
}

int run() {
    GLfloat angle = 0;

    while(!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(shaders);

        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

        GLuint attrLocation = glGetAttribLocation(shaders, "location");
        GLuint attrColor = glGetAttribLocation(shaders, "color");

        std::cout << "AttribLocation('location'): ";
        std::cout << glGetAttribLocation(shaders, "location") << std::endl;
        std::cout << "AttribLocation('color'): ";
        std::cout << glGetAttribLocation(shaders, "color") << std::endl;

        checkE();
        std::cout << std::endl;

        std::cout << "glEnableVertexAttribArray()" << std::endl;
        glEnableVertexAttribArray(attrLocation);
        glEnableVertexAttribArray(attrColor);

        checkE();
        std::cout << std::endl;

        std::cout << "glVertexAttribPointer();" << std::endl;

        glVertexAttribPointer(
                        glGetAttribLocation(shaders, "location"), // Attribute
                        3, // Size
                        GL_FLOAT, // Size
                        GL_FALSE, // Normalized
                        24, // Stride
                        (GLvoid*) 0 // Offset
                    );

        checkE();
        std::cout << std::endl;


        std::cout << "glVertexAttribPointer();" << std::endl;
        glVertexAttribPointer(
                        glGetAttribLocation(shaders, "color"),
                        3,
                        GL_FLOAT,
                        GL_FALSE,
                        24,
                        (GLvoid*) (3*sizeof(GLfloat))
                    );
        checkE();
        std::cout << std::endl;

        glDrawArrays(GL_TRIANGLES, 0, 3);

        checkE();
        std::cout << std::endl;

        glDisableVertexAttribArray(attrLocation);
        glDisableVertexAttribArray(attrColor);

        checkE();
        std::cout << std::endl;

        glfwSwapBuffers(window);
        glfwPollEvents();

        glfwSetWindowShouldClose(window, GL_TRUE);
    }

    glfwDestroyWindow(window);
    glfwTerminate();
}
着色器加载程序:

#include "shader_utils.h"

#include <string>
#include <iostream>
#include <fstream>
#include <vector>

#include "GL/glew.h"
#include "GL/glfw3.h"


GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path){

    // Create the shaders
    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    // Read the Vertex Shader code from the file
    std::string VertexShaderCode;
    std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
    if(VertexShaderStream.is_open())
    {
        std::string Line = "";
        while(getline(VertexShaderStream, Line))
            VertexShaderCode += "\n" + Line;
        VertexShaderStream.close();
    } else {
        std::cout << "could not open\n";
    }

    // Read the Fragment Shader code from the file
    std::string FragmentShaderCode;
    std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
    if(FragmentShaderStream.is_open()){
        std::string Line = "";
        while(getline(FragmentShaderStream, Line))
            FragmentShaderCode += "\n" + Line;
        FragmentShaderStream.close();
    }

    GLint Result = GL_FALSE;
    int InfoLogLength;

    // Compile Vertex Shader
    printf("Compiling shader : %s\n", vertex_file_path);
    char const * VertexSourcePointer = VertexShaderCode.c_str();
    glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
    glCompileShader(VertexShaderID);

    // Check Vertex Shader
    glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> VertexShaderErrorMessage(InfoLogLength);
    glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
    fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);

    // Compile Fragment Shader
    printf("Compiling shader : %s\n", fragment_file_path);
    char const * FragmentSourcePointer = FragmentShaderCode.c_str();
    glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
    glCompileShader(FragmentShaderID);

    // Check Fragment Shader
    glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
    glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
    fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);

    // Link the program
    fprintf(stdout, "Linking program\n");
    GLuint ProgramID = glCreateProgram();
    glAttachShader(ProgramID, VertexShaderID);
    glAttachShader(ProgramID, FragmentShaderID);
    glLinkProgram(ProgramID);

    // Check the program
    glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
    glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> ProgramErrorMessage( std::max(InfoLogLength, int(1)) );
    glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
    fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);

    glDeleteShader(VertexShaderID);
    glDeleteShader(FragmentShaderID);

    std::cout.flush();

    return ProgramID;
}
片段着色器:

#version 130

in vec3 color;

void main() {
    gl_FragColor = vec4(color, 1);
}
出于某种原因,我只得到
-1
作为这两个属性的位置。显然,其余的错误是由无效的位置索引引起的

来自OpenGL文档:
如果指定的属性变量不是指定程序对象中的活动属性,或者如果名称以保留前缀“gl_”开头,则返回值-1。


名称不是以
gl\uuu
开头,它们在着色器中使用,因此我不应该得到
-1
的值。我遗漏了什么?

您无法获取
颜色的属性位置,因为它不处于活动状态。虽然在本例中,
color
确实用于计算
f_color
,但片段着色器不使用
f_color
,因此链接器确定名为:
color
的顶点属性处于非活动状态

解决方案非常简单,真的:

片段着色器: 在顶点着色器(输入顶点属性)和片段着色器(输入变化)阶段中,为不同目的重复使用名称
颜色
,这样编译器/链接器就不会抱怨了,这不是错误。但是,如果尝试执行类似于inout color的操作,则会出现错误,因此,必须使用不同名称的变量将顶点属性传递给几何体/细分/碎片着色器。如果阶段之间的输入/输出名称不匹配,则很有可能原始顶点属性被视为处于非活动状态


此外,除非要转置ModelViewProjection矩阵,否则顶点着色器中的矩阵乘法将向后。列主矩阵乘法,就像OpenGL使用的那样,应该从右向左读取。也就是说,从对象空间位置(最右侧)开始,变换到剪辑空间(最左侧)

换句话说,这是变换顶点的正确方法

gl_Position = gl_ModelViewProjectionMatrix * position;

~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~
 clip space    object space to clip space    obj space

您无法获取
颜色的属性位置,因为它未处于活动状态。虽然在本例中,
color
确实用于计算
f_color
,但片段着色器不使用
f_color
,因此链接器确定名为:
color
的顶点属性处于非活动状态

解决方案非常简单,真的:

片段着色器: 在顶点着色器(输入顶点属性)和片段着色器(输入变化)阶段中,为不同目的重复使用名称
颜色
,这样编译器/链接器就不会抱怨了,这不是错误。但是,如果尝试执行类似于inout color的操作,则会出现错误,因此,必须使用不同名称的变量将顶点属性传递给几何体/细分/碎片着色器。如果阶段之间的输入/输出名称不匹配,则很有可能原始顶点属性被视为处于非活动状态


此外,除非要转置ModelViewProjection矩阵,否则顶点着色器中的矩阵乘法将向后。列主矩阵乘法,就像OpenGL使用的那样,应该从右向左读取。也就是说,从对象空间位置(最右侧)开始,变换到剪辑空间(最左侧)

换句话说,这是变换顶点的正确方法

gl_Position = gl_ModelViewProjectionMatrix * position;

~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~
 clip space    object space to clip space    obj space

您无法获取
颜色的属性位置,因为它未处于活动状态。虽然在本例中,
color
确实用于计算
f_color
,但片段着色器不使用
f_color
,因此链接器确定名为:
color
的顶点属性处于非活动状态

解决方案非常简单,真的:

片段着色器: 在顶点着色器(输入顶点属性)和片段着色器(输入变化)阶段中,为不同目的重复使用名称
颜色
,这样编译器/链接器就不会抱怨了,这不是错误。但是,如果尝试执行类似于inout color的操作,则会出现错误,因此,必须使用不同名称的变量将顶点属性传递给几何体/细分/碎片着色器。如果阶段之间的输入/输出名称不匹配,则很有可能原始顶点属性被视为处于非活动状态


此外,除非要转置ModelViewProjection矩阵,否则顶点着色器中的矩阵乘法将向后。列主矩阵乘法,就像OpenGL使用的那样,应该从右向左读取。也就是说,从对象空间位置(最右侧)开始,变换到剪辑空间(最左侧)

换句话说,这是变换顶点的正确方法

gl_Position = gl_ModelViewProjectionMatrix * position;

~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~
 clip space    object space to clip space    obj space

您无法获取
颜色的属性位置,因为它未处于活动状态。虽然在本例中,
color
确实用于计算
f_color
,但片段着色器不使用
f_color
,因此链接器确定名为:
color
的顶点属性处于非活动状态

解决方案非常简单,真的:

片段着色器: 在顶点着色器(输入顶点属性)和片段着色器(输入变化)阶段中,为不同目的重复使用名称
颜色
,这样编译器/链接器就不会抱怨了,这不是错误。但是,如果您尝试执行类似于inout color的操作,则会出现错误,因此,这就是为什么必须使用不同的na将顶点属性传递给几何体/细分/片段着色器的原因
gl_Position = gl_ModelViewProjectionMatrix * position;

~~~~~~~~~~~   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~
 clip space    object space to clip space    obj space