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

时间:2018-04-05 14:25:24

标签: c++ opengl shader glfw

我试图让形状上的颜色变暗,然后定期变亮。我想这样做的方法是使用一个统一变量,它从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个立方体变暗然后变亮但我想确保它首先在所有它们上使用它。

1 个答案:

答案 0 :(得分:3)

我相信:

if (shadeIndex = -1)

应该是:

if (shadeIndex == -1)

然后,您需要在代码中添加对glUniform1f的调用,以便实际设置统一值。