glGetUniformLocation() 在使用过的制服上返回 -1?
Posted
技术标签:
【中文标题】glGetUniformLocation() 在使用过的制服上返回 -1?【英文标题】:glGetUniformLocation() returns -1 on used uniform? 【发布时间】:2018-04-05 14:25:23 【问题描述】:我正在尝试使形状上的颜色变暗,然后定期变亮。我想到的方法是使用一个从 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 个立方体变暗然后变亮,但我想通过在所有立方体上使用它来确保它首先起作用。
【问题讨论】:
为什么在if (shadeIndex = -1)
中使用=
而不是==
?
【参考方案1】:
我相信:
if (shadeIndex = -1)
应该是:
if (shadeIndex == -1)
然后,您当然需要在代码中添加对glUniform1f
的调用,以便实际设置统一值。
【讨论】:
谢谢,就是这样。我总是觉得自己被困在简单的事情上寻找不同的问题很愚蠢,但老实说我没有考虑过。以上是关于glGetUniformLocation() 在使用过的制服上返回 -1?的主要内容,如果未能解决你的问题,请参考以下文章
glGetUniformLocation() 在使用过的制服上返回 -1?
即使我在着色器中使用了变量,glGetUniformLocation 仍返回 -1
glGetUniformLocation为第一个以外的采样器返回-1?