代码之家  ›  专栏  ›  技术社区  ›  geojade

glGetUniformLocation()在使用的统一上返回-1?

  •  1
  • geojade  · 技术社区  · 6 年前

    我试图使形状上的颜色变暗,然后定期变亮。我想到的方法是使用一个均匀变量,该变量周期性地从0变为1,再变回来,然后将其乘以输入的颜色,形成输出颜色。我有一个统一的变量ublackness,它可以做到这一点。

    检查是否可以定位它总是返回-1,但是前一个变量和下一个变量按预期工作。我知道这个名字是正确的,而且我知道它正在被使用,因为有了乘法,屏幕是黑色的(大概是因为颜色被乘以0或什么),但没有它,它显示得很好。以下是cpp文件中的相关代码

    GLuint positionIndex = glGetAttribLocation(g_shaderProgramID, "aPosition");
    GLuint colorIndex = glGetAttribLocation(g_shaderProgramID, "aColor");
    shadeIndex = glGetUniformLocation(g_shaderProgramID, "ublackness");
    if (shadeIndex = -1)
    {
        cout << "it didn't work" << endl;
    }
    g_MVP_Index = glGetUniformLocation(g_shaderProgramID, "uModelViewProjectionMatrix");
    

    这是相关的片段着色器文件。

    #version 330 core
    
    // interpolated values from the vertex shaders
    in vec3 vColor;
    
    //thing
    uniform float ublackness;
    
    // output data
    out vec3 fColor;
    
    void main()
    {
        // set output color
        fColor = vColor * ublackness;
    }
    

    如果有人告诉我改用顶点着色器,我已经尝试过了,结果也是一样的。我还尝试发送 vec3 ,并创建临时 vec3 并将其颜色设置为vcolor*blackness,然后输出。

    我还听说nvidia图形卡会影响glUniform1f等函数的工作方式,我使用了该函数,但这似乎并不相关,因为它甚至无法访问具有有效索引的代码部分。如果是相关的,但是,我有一个NVIDIA Geforce GTX 1080。我还听说你需要使用glUseProgram glGetUniformLocation 但是,其他函数在没有它的情况下也可以工作,而ublackness仍然不能使用它,所以我没有费心把它放在里面。但是,渲染时仍会使用它。


    我强调了我认为相关的代码,但如果需要更多,以下是所有主要的cpp代码:

    #include <cstdio>       // for C++ i/o
    #include <iostream>
    #include <string>
    #include <time.h>
    using namespace std;    // to avoid having to use std::
    
    #define GLEW_STATIC     // include GLEW as a static library
    #include <GLEW/glew.h>  // include GLEW
    #include <GLFW/glfw3.h> // include GLFW (which includes the OpenGL header)
    #include <glm/glm.hpp>  // include GLM (ideally should only use the GLM   headers that are actually used)
    #include <glm/gtx/transform.hpp>
    using namespace glm;    // to avoid having to use glm::
    
    #include "shader.h"
    
                                // struct for vertex attributes
    struct Vertex
    {
        GLfloat position[3];
        GLfloat color[3];
    };
    
    
    Vertex g_vertices[] = {
    // vertex 1
    -0.5f, 0.5f, 0.5f,  // position
    1.0f, 0.0f, 1.0f,   // colour
    // vertex 2
    -0.5f, -0.5f, 0.5f, // position
    1.0f, 0.0f, 0.0f,   // colour
    // vertex 3
    0.5f, 0.5f, 0.5f,   // position
    1.0f, 1.0f, 1.0f,   // colour
    // vertex 4
    0.5f, -0.5f, 0.5f,  // position
    1.0f, 1.0f, 0.0f,   // colour
    // vertex 5
    -0.5f, 0.5f, -0.5f, // position
    0.0f, 0.0f, 1.0f,   // colour
    // vertex 6
    -0.5f, -0.5f, -0.5f,// position
    0.0f, 0.0f, 0.0f,   // colour
    // vertex 7
    0.5f, 0.5f, -0.5f,  // position
    0.0f, 1.0f, 1.0f,   // colour
    // vertex 8
    0.5f, -0.5f, -0.5f, // position
    0.0f, 1.0f, 0.0f,   // colour
     };
    
    GLuint g_indices[] = {
    0, 1, 2,    // triangle 1
    2, 1, 3,    // triangle 2
    4, 5, 0,    // triangle 3
    0, 5, 1,    // ...
    2, 3, 6,
    6, 3, 7,
    4, 0, 6,
    6, 0, 2,
    1, 5, 3,
    3, 5, 7,
    5, 4, 7,
    7, 4, 6,    // triangle 12
    };
    
    
    GLuint g_IBO = 0;               // index buffer object identifier
    GLuint g_VBO = 0;               // vertex buffer object identifier
    GLuint g_VAO = 0;               // vertex array object identifier
    GLuint g_shaderProgramID = 0;   // shader program identifier
    GLuint g_MVP_Index = 0;         // location in shader
    GLuint shadeIndex = 0;
    glm::mat4 g_modelMatrix[6];     // object's model matrix
    glm::mat4 g_viewMatrix;         // view matrix
    glm::mat4 g_projectionMatrix;   // projection matrix
    float translation[6];
    float scaling[6];
    float rotation[6];
    float totalRotation[6];
    float orbit[6];
    float totalOrbit[6];
    float totalShade = 1;
    int shadeChange = 1;
    
    
    
    
                        // function used to render the scene
    static void render_scene()
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear colour buffer and depth buffer
    
    glUseProgram(g_shaderProgramID);    // use the shaders associated with the shader program
    
    glBindVertexArray(g_VAO);       // make VAO active
    
    for (int i = 0; i < 5; i++)
    {
        g_modelMatrix[i]  = glm::rotate(totalOrbit[i], glm::vec3(0.0f, 1.0f, 0.0f))
            * glm::translate(glm::vec3(translation[i], 0.0f, 0.0f))
            * glm::rotate(totalRotation[i], glm::vec3(0.0f, 1.0f, 0.0f))
            * glm::scale(glm::vec3(scaling[i], scaling[i], scaling[i]));
        glm::mat4 MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[i];
        // set uniform model transformation matrix
        glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type
    }
    
    g_modelMatrix[5] = glm::rotate(totalOrbit[5], glm::vec3(0.0f, 1.0f, 0.0f))
        * glm::translate(glm::vec3(translation[5], 0.0f, 0.0f))
        * glm::rotate(totalOrbit[5], glm::vec3(0.0f, 1.0f, 0.0f))
        * glm::translate(glm::vec3(0.4, 0.0f, 0.0f))
        * glm::rotate(totalRotation[5], glm::vec3(0.0f, 1.0f, 0.0f))
        * glm::scale(glm::vec3(scaling[5], scaling[5], scaling[5]));
    glm::mat4 MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[5];
    // set uniform model transformation matrix
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type
    
    //glm::mat4 MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[0];
    // set uniform model transformation matrix
    //glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    
    glFlush();  // flush the pipeline
    }
    
    // error callback function
    static void error_callback(int error, const char* description)
    {
    cerr << description << endl;    // output error description
    }
    
    
    // key press or release callback function
     static void key_callback(GLFWwindow* window, int key, int scancode, int     action, int mods)
    {
    // quit if the ESCAPE key was press
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
    {
        // set flag to close the window
        glfwSetWindowShouldClose(window, GL_TRUE);
        return;
    }
    }
    
    static void init(GLFWwindow* window)
    {
    glClearColor(0.0, 0.0, 0.0, 1.0);   // set clear background colour
    
    glEnable(GL_DEPTH_TEST);    // enable depth buffer test
                                // create and compile our GLSL program from the shader files
    g_shaderProgramID = loadShaders("VertexShader.vert", "FragShader.frag");
    
    // find the location of shader variables
    GLuint positionIndex = glGetAttribLocation(g_shaderProgramID, "aPosition");
    GLuint colorIndex = glGetAttribLocation(g_shaderProgramID, "aColor");
    shadeIndex = glGetUniformLocation(g_shaderProgramID, "ublackness");
    if (shadeIndex = -1)
    {
        cout << "it didn't work" << endl;
    }
    g_MVP_Index = glGetUniformLocation(g_shaderProgramID, "uModelViewProjectionMatrix");
    
    srand(time(NULL));
    
    // initialise model matrix to the identity matrix
    g_modelMatrix[0] = glm::mat4(1.0f); //sun
    scaling[0] = 0.5f * (100 + ((rand() % 100)))/100;
    translation[0] = 0.0f;
    rotation[0] = 1.0f * (100 + ((rand() % 100))) / 100;
    orbit[0] = 0.0f;
    
    g_modelMatrix[1] = glm::mat4(1.0f); //tilted planet
    scaling[1] = 0.1f * (100 + ((rand() % 100))) / 100;
    translation[1] = 0.7f * (100 + ((rand() % 15))) / 100;
    rotation[1] = 1.0f * (100 + ((rand() % 100))) / 100;
    orbit[1] = 0.3f * (100 + ((rand() % 100))) / 100;
    
    g_modelMatrix[2] = glm::mat4(1.0f); //ringed planet
    scaling[2] = 0.1f * (100 + ((rand() % 100))) / 100;
    translation[2] = 1.5f * (100 + ((rand() % 15))) / 100;
    rotation[2] = 1.0f * (100 + ((rand() % 100))) / 100;
    orbit[2] = 0.3f * (100 + ((rand() % 100))) / 100;
    
    g_modelMatrix[3] = glm::mat4(1.0f); //moon planet
    scaling[3] = 0.1f * (100 + ((rand() % 100))) / 100;
    translation[3] = 2.8f * (100 + ((rand() % 15))) / 100;
    rotation[3] = 1.0f * (100 + ((rand() % 100))) / 100;
    orbit[3] = 0.3f * (100 + ((rand() % 100))) / 100;
    
    g_modelMatrix[4] = glm::mat4(1.0f); //fading planet
    scaling[4] = 0.1f * (100 + ((rand() % 100))) / 100;
    translation[4] = 4.0f * (100 + ((rand() % 15))) / 100;
    rotation[4] = 1.0f * (100 + ((rand() % 100))) / 100;
    orbit[4] = 0.3f * (100 + ((rand() % 100))) / 100;
    
    g_modelMatrix[5] = glm::mat4(1.0f); //moon
    scaling[5] = 0.02f * (100 + ((rand() % 100))) / 100;
    translation[5] = translation[3];
    rotation[5] = 1.0f * (100 + ((rand() % 100))) / 100;
    orbit[5] = orbit[3];
    
    
    g_viewMatrix = glm::lookAt(glm::vec3(0, 6, 1), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
    
    int width, height;
    glfwGetFramebufferSize(window, &width, &height);
    float aspectRatio = static_cast<float>(width) / height;
    
    g_projectionMatrix = glm::perspective(45.0f, aspectRatio, 0.1f, 100.0f);
    
    // generate identifier for VBO and copy data to GPU
    glGenBuffers(1, &g_VBO);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices), g_vertices, GL_STATIC_DRAW);
    
    // generate identifier for IBO and copy data to GPU
    glGenBuffers(1, &g_IBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(g_indices), g_indices, GL_STATIC_DRAW);
    
    // generate identifiers for VAO
    glGenVertexArrays(1, &g_VAO);
    
    // create VAO and specify VBO data
    glBindVertexArray(g_VAO);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO);
    // interleaved attributes
    glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)));
    glVertexAttribPointer(colorIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, color)));
    
    glEnableVertexAttribArray(positionIndex);   // enable vertex attributes
    glEnableVertexAttribArray(colorIndex);
    }
    
    static void update_scene(GLFWwindow* window, float frameTime)
    {
    // declare variables to transform the object
    for (int i = 0; i < 6; i++)
    {
        totalOrbit[i] += orbit[i] * frameTime;
        totalRotation[i] += rotation[i] * frameTime;
    }
    if (totalShade = 1)
    {
        shadeChange = -0.05f;
    }
    else if (totalShade = 0)
    {
        shadeChange = 0.05f;
    }
    totalShade += shadeChange;
    glUniform1f(shadeIndex, totalShade);
    }
    
    int main(void)
    {
    GLFWwindow* window = NULL;  // pointer to a GLFW window handle
    
    glfwSetErrorCallback(error_callback);   // set error callback function
    
                                            // initialise GLFW
    if (!glfwInit())
    {
        // if failed to initialise GLFW
        exit(EXIT_FAILURE);
    }
    
    // minimum OpenGL version 3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    
    // create a window and its OpenGL context
    window = glfwCreateWindow(800, 600, "Creating a Window", NULL, NULL);
    
    // if failed to create window
    if (window == NULL)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }
    
    glfwMakeContextCurrent(window); // set window context as the current context
    glfwSwapInterval(1);            // swap buffer interval
    
                                    // initialise GLEW
    if (glewInit() != GLEW_OK)
    {
        // if failed to initialise GLEW
        cerr << "GLEW initialisation failed" << endl;
        exit(EXIT_FAILURE);
    }
    
    // set key callback function
    glfwSetKeyCallback(window, key_callback);
    
    /*
    // if not using key or mouse callback functions
    // use sticky mode to avoid missing state changes from polling
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
    glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, GL_TRUE);
    */
    
    // initialise rendering states
    init(window);
    
    double lastUpdateTime = glfwGetTime();  // last update time
    double elapsedTime = lastUpdateTime;    // time elapsed since last update
    float frameTime = 0.0f;             // frame time
    int frameCount = 0;
                                        // the rendering loop
    while (!glfwWindowShouldClose(window))
    {
        update_scene(window, frameTime);    // update the scene
        render_scene();             // render the scene
    
        glfwSwapBuffers(window);    // swap buffers
        glfwPollEvents();           // poll for events
    
        frameCount++;
        elapsedTime = glfwGetTime() - lastUpdateTime;   // current time - last update time
    
        if (elapsedTime >= 1.0f)    // if time since last update >= to 1 second
        {
            frameTime = static_cast<float>(1.0f / frameCount);  // calculate frame time
    
            string str = "FPS = " + to_string(frameCount) + "; FT = " + to_string(frameTime);
    
            glfwSetWindowTitle(window, str.c_str());    // update window title
    
            frameCount = 0;                 // reset frame count
            lastUpdateTime += elapsedTime;  // update last update time
        }
    }
    
    // clean up
    glDeleteProgram(g_shaderProgramID);
    glDeleteBuffers(1, &g_IBO);
    glDeleteBuffers(1, &g_VBO);
    glDeleteVertexArrays(1, &g_VAO);
    
    // close the window and terminate GLFW
    glfwDestroyWindow(window);
    glfwTerminate();
    
    exit(EXIT_SUCCESS);
    }
    

    以下是所有顶点着色器代码:

    #version 330 core
    
    // input data (different for all executions of this shader)
    in vec3 aPosition;
    in vec3 aColor;
    
    // ModelViewProjection matrix
    uniform mat4 uModelViewProjectionMatrix;
    
    // output data (will be interpolated for each fragment)
    out vec3 vColor;
    
    void main()
    {
    // set vertex position
    gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0);
    
    // the color of each vertex will be interpolated
    // to produce the color of each fragment
    vColor = aColor;
    }
    

    以下是所有着色器cpp代码:

    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    #define GLEW_STATIC     // include GLEW as a static library
    #include <GLEW/glew.h>  // include GLEW
    
    #include "shader.h"
    
    // function to load shaders
    GLuint loadShaders(const string vertexShaderFile, const string fragmentShaderFile)
    {
    GLint status;   // for checking compile and linking status
    
    // load vertex shader code from file
    string vertexShaderCode;    // to store shader code
    ifstream vertexShaderStream(vertexShaderFile, ios::in); // open file stream
    
    // check whether file stream was successfully opened
    if(vertexShaderStream.is_open())
    {
        // read from stream line by line and append it to shader code
        string line = "";
        while(getline(vertexShaderStream, line))
            vertexShaderCode += line + "\n";
    
        vertexShaderStream.close();     // no longer need file stream
    }
    else
    {
        // output error message and exit
        cout << "Failed to open vertex shader file - " << vertexShaderFile << endl;
        exit(EXIT_FAILURE);
    }
    
    // load fragment shader code from file
    string fragmentShaderCode;  // to store shader code
    ifstream fragmentShaderStream(fragmentShaderFile, ios::in); // open file stream
    
    // check whether file stream was successfully opened
    if(fragmentShaderStream.is_open())
    {
        // read from stream line by line and append it to shader code
        string line = "";
        while(getline(fragmentShaderStream, line))
            fragmentShaderCode += line + "\n";
    
        fragmentShaderStream.close();   // no longer need file stream
    }
    else
    {
        // output error message and exit
        cout << "Failed to open fragment shader file - " << fragmentShaderFile << endl;
        exit(EXIT_FAILURE);
    }
    
    // create shader objects
    GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
    
    // provide source code for shaders
    const GLchar* vShaderCode = vertexShaderCode.c_str();
    const GLchar* fShaderCode = fragmentShaderCode.c_str();
    glShaderSource(vertexShaderID, 1, &vShaderCode, NULL);
    glShaderSource(fragmentShaderID, 1, &fShaderCode, NULL);
    
    // compile vertex shader
    glCompileShader(vertexShaderID);
    
    // check compile status
    status = GL_FALSE;
    glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &status);
    
    if(status == GL_FALSE)
    {
        // output error message
        cout << "Failed to compile vertex shader - " << vertexShaderFile  << endl;
    
        // output error information
        int infoLogLength;
        glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
        char* errorMessage = new char[infoLogLength + 1];
        glGetShaderInfoLog(vertexShaderID, infoLogLength, NULL, errorMessage);
        cout << errorMessage << endl;
        delete[] errorMessage;
    
        exit(EXIT_FAILURE);
    }
    
    // compile fragment shader
    glCompileShader(fragmentShaderID);
    
    // check compile status
    status = GL_FALSE;
    glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &status);
    
    if(status == GL_FALSE)
    {
        // output error message
        cout << "Failed to compile fragment shader - " << fragmentShaderFile << endl;
    
        // output error information
        int infoLogLength;
        glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
        char* errorMessage = new char[infoLogLength + 1];
        glGetShaderInfoLog(fragmentShaderID, infoLogLength, NULL, errorMessage);
        cout << errorMessage << endl;
        delete[] errorMessage;
    
        exit(EXIT_FAILURE);
    }
    
    // create program
    GLuint programID = glCreateProgram();
    
    // attach shaders to the program object
    glAttachShader(programID, vertexShaderID);
    glAttachShader(programID, fragmentShaderID);
    
    // flag shaders for deletion (will not be deleted until detached from program)
    glDeleteShader(vertexShaderID);
    glDeleteShader(fragmentShaderID);
    
    // link program object
    glLinkProgram(programID);
    
    // check link status
    status = GL_FALSE;
    glGetProgramiv(programID, GL_LINK_STATUS, &status);
    
    if(status == GL_FALSE)
    {
        // output error message
        cout << "Failed to link program object." << endl;
    
        // output error information
        int infoLogLength;
        glGetShaderiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength);
        char* errorMessage = new char[infoLogLength + 1];
        glGetShaderInfoLog(programID, infoLogLength, NULL, errorMessage);
        cout << errorMessage << endl;
        delete[] errorMessage;
    
        exit(EXIT_FAILURE);
    }
    
    return programID;
    }
    

    如果您想知道代码的作用,它会创建一个立方体,然后将其转换为一个太阳系。我试图让一个立方体先变暗再变亮,但我想先用它来确保它在所有立方体上都起作用。

    1 回复  |  直到 6 年前
        1
  •  3
  •   Nicolas Tisserand    6 年前

    我相信:

    if (shadeIndex = -1)
    

    应为:

    if (shadeIndex == -1)
    

    然后您需要向添加呼叫 glUniform1f 当然,在您的代码中,为了实际设置统一的值。