I'm trying to learn how to use OpenGL but I'm having problems trying to pass an array of matrices to my VertexShader. I think the problem is in the VertexShader because it seems the values in modelvalue are passed correctly to the components of model, but for some reason at the end only one of the three cubes I've created is drawn.
Here's the Main code.
glm::mat4 model[3];
GLint ModelLocation = glGetUniformLocation(MyShader.program, "model");
vector<GLfloat> modelvalue;
const int n = int(sizeof(model[0]) / sizeof(GLfloat));
for (int i = 0; i < 3; i++) {
model[i] = glm::translate(model[i], cubePositions[i]);
for (int j = 0; j < n; j++) {
modelvalue.push_back(glm::value_ptr(model[i])[j]);
}
}
glUniformMatrix4fv(ModelLocation, 3, GL_FALSE, &modelvalue[0]);
The VertexShader:
#version 400 core
layout (location = 0) in vec3 Position;
layout (location = 1) in vec2 texCoord;
out vec2 TexCoord;
out vec4 position0;
out vec4 position1;
out vec4 position2;
uniform mat4 model[3];
uniform mat4 view;
uniform mat4 projection;
void main()
{
position0 = projection * view * model[0] * vec4(Position,1.0f);
position1 = projection * view * model[1] * vec4(Position,1.0f);
position2 = projection * view * model[2] * vec4(Position,1.0f);
TexCoord = vec2(texCoord.x,1-texCoord.y);
}
And the FragmentShader:
#version 400 core
layout (location = 0) in vec3 Position;
layout (location = 1) in vec2 texCoord;
out vec2 TexCoord;
out vec4 position0;
out vec4 position1;
out vec4 position2;
uniform mat4 model[3];
uniform mat4 view;
uniform mat4 projection;
void main()
{
position0 = projection * view * model[0] * vec4(Position,1.0f);
position1 = projection * view * model[1] * vec4(Position,1.0f);
position2 = projection * view * model[2] * vec4(Position,1.0f);
TexCoord = vec2(texCoord.x,1-texCoord.y);
}
Uniform Blocks might be of interest to you. They are essentially buffer objects containing an array of uniform values.
Related
I want to use geometry shader to draw triangles of mesh, but encounter a really odd issue.
Result As follow: The wrong output.
The Right output.
The only diff between wrong and right in code, is when converting 3d position vector to 4d position vector. The right one did in vertex shader. The wrong one did in geometry shader.
Code as follow. Why this happend?
#version 330 core
layout (location = 0) in vec3 pos;
layout (location = 1) in vec3 normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 project;
out vec3 normal_;
out vec4 pos_;
out vec3 pos_bug_;
out mat4 mvp_;
void main()
{
mvp_ = project * view * model;
normal_ = normal;
pos_ = vec4(pos, 1.0);
pos_bug_ = pos;
}
#version 330 core
layout (triangles) in;
layout (line_strip, max_vertices = 12) out;
uniform float length = 0.4f;
out vec4 color;
in mat4 mvp_[];
in vec3 normal_[];
in vec4 pos_[];
in vec3 pos_bug_[];
void GenNormal(int index) {
color = vec4(1, 1, 0, 1);
gl_Position = mvp_[0] * pos_[index];
EmitVertex();
gl_Position = mvp_[0] * pos_[index] + vec4(normal_[index], 0.0) * length;
EmitVertex();
EndPrimitive();
}
void GenTriangle(int index0, int index1) {
color = vec4(1, 1, 1, 1);
gl_Position = mvp_[0] * pos_[index0]; // Right
// gl_Position = mvp_[0] * vec4(pos_bug_[index0], 1.0); // Wrong
EmitVertex();
gl_Position = mvp_[0] * pos_[index1]; // Right
// gl_Position = mvp_[0] * vec4(pos_bug_[index1], 1.0); // Wrong
EmitVertex();
EndPrimitive();
}
void main()
{
GenNormal(0);
GenNormal(1);
GenNormal(2);
GenTriangle(0, 1);
GenTriangle(1, 2);
GenTriangle(0, 2);
}
The problem is that artifacts appear in the shadows at a great distance. I want to try to make a logarithmic depth buffer, but I don’t understand where it should be done and how ... I use point light method for omnidirectional shadow maps
Vertex shader:
#version 460 core
layout (location = 0) in vec3 aPos;
uniform mat4 model;
uniform float zCoef;
//out vec4 pos;
void main() {
gl_Position = model * vec4(aPos, 1.0f);
// gl_Position.z = log2(max(1e-6, gl_Position.w + 1.0)) * zCoef - 1.0;
// gl_Position.z *= gl_Position.w;
}
Geometry shader:
#version 460 core
layout (triangles) in;
layout (triangle_strip, max_vertices = 18) out;
uniform mat4 shadowMatrices[6];
uniform float zCoef;
out vec4 FragPos; // FragPos from GS (output per emitvertex)
void main()
{
for(int face = 0; face < 6; ++face)
{
gl_Layer = face; // встроенная переменная, указывающая на то, какую грань мы рендерим
for(int i = 0; i < 3; ++i) // для каждой вершины треугольника
{
FragPos = gl_in[i].gl_Position;
gl_Position = shadowMatrices[face] * FragPos;
// gl_Position.z = log2(max(1e-6, gl_Position.w + 1.0)) * zCoef - 1.0;
// gl_Position.z *= gl_Position.w;
EmitVertex();
}
EndPrimitive();
}
}
Fragment shader:
#version 460 core
in vec4 FragPos;
uniform vec3 lightPos;
uniform float farPlane;
uniform float zCoef;
void main() {
float lightDistance = length(FragPos.xyz - lightPos);
lightDistance = lightDistance / farPlane;
gl_FragDepth = lightDistance;
}
Guys, pls help me,i tried to use the linearization depth, it didn't work too..
I'm trying to call glGetUniformLocation() on an array of struct. I read that I should use this name format: "uniformName[index].element", but the method always returns -1. I tried to delete the array and only use the structure and it worked so I guess that the problem might there. Here is the struct and the array in my fragment shader:
const int MAX_BLOCKS = 16;
struct sblock{
vec4 color;
float shineDamper;
float reflectivity;
};
uniform sblock blocks[MAX_BLOCKS];
And here is my call:
for(int i = 0; i < 16; i++) {
location_block_color[i] = super.getUniformLocation("blocks["+i+"].color");
location_block_reflectivity[i] = super.getUniformLocation("blocks["+i+"].reflectivity");
location_block_shineDamper[i] = super.getUniformLocation("blocks["+i+"].shineDamper");
System.out.println(location_block_color[i] + " " + location_block_reflectivity[i] + " " + location_block_shineDamper[i]); // prints -1 -1 -1 ...
}
getUniformLocation method:
protected int getUniformLocation(String uniformName) {
return GL20.glGetUniformLocation(programID, uniformName);
}
and this how I create programID (before anything else):
vertexShaderID = loadShader(vertexFile, GL20.GL_VERTEX_SHADER);
fragmentShaderID = loadShader(fragmentFile, GL20.GL_FRAGMENT_SHADER);
programID = GL20.glCreateProgram();
My question is what is happening here and what am I doing wrong?
Thanks for your help.
EDIT 1:
Here is my full fragment shader:
#version 400 core
const int MAX_LIGHTS = 16;
const int MAX_BLOCKS = 16;
struct sblock{
vec4 color;
float shineDamper;
float reflectivity;
};
uniform sblock blocks[MAX_BLOCKS];
in int block_id_out;
in vec3 unitNormal;
in vec3 lightVector[MAX_LIGHTS];
in vec3 directionalLightFinalColour;
in vec3 directionalLightReflected;
in vec3 toCameraVector;
in float visibility;
out vec4 outColor;
uniform float ambientLight;
uniform vec3 skyColor;
uniform vec3 lightColour[MAX_LIGHTS];
uniform vec3 attenuation[MAX_LIGHTS];
uniform int lightCount;
uniform vec3 directionalLightColour;
uniform vec3 directionalLightDirection;
vec3 calculateDiffuse(vec3 unitNormal, vec3 unitLightVector, vec3 lightColour, float attFactor){
float nDotl = dot(unitNormal,unitLightVector);
float brightness = max(nDotl,0);
return (brightness * lightColour) / attFactor;
}
vec3 calculateSpecular(vec3 unitNormal, vec3 unitLightVector, vec3 unitToCameraVector, float shineDamper, float reflectivity, vec3 lightColour, float attFactor){
vec3 reflectedLightDirection = reflect(-unitLightVector,unitNormal);
float specularFactor = max(dot(reflectedLightDirection, unitToCameraVector),0.0);
float dampedFactor = pow(specularFactor,shineDamper);
return (dampedFactor * reflectivity * lightColour) / attFactor;
}
void main(void){
vec3 totalDiffuse = vec3(0.0);
vec3 totalSpecular = vec3(0.0);
vec3 unitToCameraVector = normalize(toCameraVector);
for(int i = 0; i < lightCount;i++){
vec3 unitLightVector = normalize(lightVector[i]);
float lightDistance = length(lightVector[i]);
float attFactor = attenuation[i].x + attenuation[i].y*lightDistance + attenuation[i].z*lightDistance*lightDistance;
totalSpecular += calculateSpecular(unitNormal, unitLightVector, unitToCameraVector, blocks[block_id_out].shineDamper, blocks[block_id_out].reflectivity, lightColour[i], attFactor);
totalDiffuse += calculateDiffuse(unitNormal, unitLightVector, lightColour[i], attFactor);
}
totalDiffuse += directionalLightFinalColour;
totalSpecular += pow(max(dot(directionalLightReflected,unitToCameraVector),0.0),blocks[block_id_out].shineDamper)*blocks[block_id_out].reflectivity*directionalLightColour;
totalDiffuse = max(totalDiffuse,ambientLight);
outColor = vec4(totalDiffuse,1.0) * blocks[block_id_out].color + vec4(totalSpecular,1.0);
outColor = mix(vec4(skyColor,1.0),outColor,visibility);
}
EDIT 2:
Here is my VertexShader:
#version 400 core
const vec4 normals[] = vec4[6](vec4(1,0,0,0),vec4(0,1,0,0),vec4(0,0,1,0),vec4(-1,0,0,0),vec4(0,-1,0,0),vec4(0,0,-1,0));
const int MAX_LIGHTS = 16;
in vec3 position;
in int block_id;
in int normal;
out int block_id_out;
out vec3 unitNormal;
out vec3 lightVector[MAX_LIGHTS];
out vec3 directionalLightFinalColour;
out vec3 directionalLightReflected;
out vec3 toCameraVector;
out float visibility;
uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition[MAX_LIGHTS];
uniform vec3 directionalLight;
uniform vec3 directionalLightColor;
uniform int lightCount;
uniform float fogDensity;
uniform float fogGradient;
void main(void){
vec4 worldPosition = transformationMatrix * vec4(position,1.0);
vec4 positionRelativeToCam = viewMatrix * worldPosition;
gl_Position = projectionMatrix * positionRelativeToCam;
block_id_out = block_id;
unitNormal = normalize((transformationMatrix * normals[normal]).xyz);
for(int i = 0; i < lightCount;i++){
lightVector[i] = lightPosition[i] - worldPosition.xyz;
}
directionalLightFinalColour = max(dot(unitNormal, directionalLight),0)*directionalLightColor;
directionalLightReflected = reflect(-directionalLight,unitNormal);
toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;
visibility = clamp(exp(-pow(length(positionRelativeToCam.xyz)*fogDensity,fogGradient)),0.0,1.0);
}
From (most recent) OpenGL Shading Language 4.60 Specification (HTML) - 4.3.9. Interface Blocks
A uniform or shader storage block array can only be indexed with a dynamically uniform integral expression, otherwise results are undefined.
block_id_out is fragment shader input (set by a vertex shader input) and not a Dynamically uniform expression. Hence blocks[block_id_out] is undefined and is not guaranteed, that blocks[i] becomes an active program resource.
I recommend to change the declaration. Do not create an array of uniforms. Create a single Uniform block:
const int MAX_BLOCKS = 16;
struct Block
{
vec4 color;
float shineDamper;
float reflectivity;
};
layout(std140) uniform Blocks
{
Block blocks[MAX_BLOCKS];
};
You have to create a Uniform Buffer Object to bind data to the uniform block.
I think that #Rabbid76 answer is correct, but I found a more satisfying workaround. I defined the struct and the uniform in the vertex shader, and then pass the correct values for color, shinedamper and reflectivity to the fragment shader. This makes more sense since I only want to access the values for each vertex and they are going to be same in the fragment shader, so doing it 3 times for each triangle is better than doing it hundreds of times for each pixel.
tl;dr:
What is the best method for accessing data from each individual vertex whilst in the fragment shader?
e.g.
The triangle in this fragment is made up from vertices v0,v1 and v2 and I want to give each vertex a specific integer which I can use to pick a texture and then fade between the 3 in the fragment shader; I don't want these ids to be interpolated and it is important that I can access each vertex's id.
Current Situation:
I am currently writing a shader for rendering terrain; I have a function in my fragment shader which will return the appropriate texture colour from uvs for a given ID (By means of a texture atlas). I can then fade between the 3 textures to give the give smoothly textured terrain
Current Code
Vertex Shader:
#version 330 core
layout(location = 0) in vec3 in_position;
layout(location = 1) in vec2 in_uv_coords;
layout(location = 2) in vec3 in_normal;
layout(location = 3) in float in_texture_id;
uniform mat4 view_matrix;
uniform mat4 projection_matrix;
out vec2 pass_uv_coords;
out vec3 pass_normal;
out vec3 texture_ratio;
out float pass_fake_brightness;
out float pass_id0;
out float pass_id1;
out float pass_id2;
void CalculateFakeLighting()
{
const vec3 light_direction = normalize(vec3(1,-1,1));
vec3 unit_normal = normalize(in_normal);
float normal_dot_light = dot(unit_normal, -light_direction);
pass_fake_brightness = max(0.2, normal_dot_light);
}
void main()
{
pass_uv_coords = in_uv_coords;
pass_normal = in_normal;
gl_Position = projection_matrix * view_matrix * vec4(in_position, 1.0);
int tile_track = int(mod(gl_VertexID, 3));
switch(tile_track)
{
case 0:
texture_ratio = vec3(1,0,0);
pass_id0 = in_texture_id;
break;
case 1:
texture_ratio = vec3(0,1,0);
pass_id1 = in_texture_id;
break;
case 2:
texture_ratio = vec3(0,0,1);
pass_id0 = in_texture_id;
break;
};
CalculateFakeLighting();
}
Fragment Shader:
#version 330 core
in vec2 pass_uv_coords;
in vec3 pass_normal;
in vec3 texture_ratio;
in float pass_fake_brightness;
in float pass_id0;
in float pass_id1;
in float pass_id2;
const int HORIZONTAL_IDS = 8;
const int VERTICAL_IDS = 8;
uniform sampler2D texture0_sampler;
out vec4 colour;
void UseFakeLighting()
{
colour *= pass_fake_brightness;
}
vec2 CorrectUVs(vec2 uvs)
{
vec2 corrected_uvs = uvs;
const float cushion = 0.001;
//Correct UV scale
while(corrected_uvs.x >= 1)
corrected_uvs.x--;
while(corrected_uvs.y >= 1)
corrected_uvs.y--;
if(corrected_uvs.x < cushion)
corrected_uvs.x = cushion;
if(corrected_uvs.x > 1 - cushion)
corrected_uvs.x = 1 - cushion;
if(corrected_uvs.y < cushion)
corrected_uvs.y = cushion;
if(corrected_uvs.y > 1 - cushion)
corrected_uvs.y = 1 - cushion;
return corrected_uvs;
}
vec4 GetTexture(float id, vec2 uv_coords)
{
vec2 step = vec2(
1.0/HORIZONTAL_IDS,
1.0/VERTICAL_IDS
);
uv_coords.x/=HORIZONTAL_IDS;
uv_coords.y/=VERTICAL_IDS;
uv_coords.x += step.x * mod(id, HORIZONTAL_IDS);
uv_coords.y += step.y * floor(id/VERTICAL_IDS);
//Texture is upsidedown
uv_coords.y = 1.0 - uv_coords.y;
return texture(texture0_sampler, uv_coords);
}
void main()
{
vec2 corrected_uvs = CorrectUVs(pass_uv_coords);
vec3 correct_ratio = normalize(texture_ratio);
colour = GetTexture(pass_id0, corrected_uvs) * correct_ratio.x +
GetTexture(pass_id1, corrected_uvs) * correct_ratio.y +
GetTexture(pass_id2, corrected_uvs) * correct_ratio.z;
if(colour.a == 0)
discard;
UseFakeLighting();
}
By default the output variables from the vertex shader to the fragment shader use perspective-correct interpolation. If you want no interpolation done then qualify your variables with flat:
flat out vec3 pass_id0;
For more info see GLSL Type Qualifiers. Also see this question “flat” qualifier in glsl?
As recommended by #aslg and #AndonM.Coleman, geometry is a good solution to this issue. A flat vec3 is passed out of the geometry stage, which stores the id of each vertex which is then accessible in the fragment shader.
The key lines are in the geometry shader; one part of the output is
flat vec3 texture_ids;
Which is then set as such:
vertex_out.texture_ids.x = vertex_in[0].texture_id;
vertex_out.texture_ids.y = vertex_in[1].texture_id;
vertex_out.texture_ids.z = vertex_in[2].texture_id;
Full Shader Sources:
Vertex
#version 330 core
layout(location = 0) in vec3 in_position;
layout(location = 1) in vec2 in_uv_coords;
layout(location = 2) in vec3 in_normal;
layout(location = 3) in float in_texture_id;
out VertexData
{
vec2 uv_coord;
vec3 normal;
uint texture_id;
} vertex_out;
void main()
{
vertex_out.uv_coord = in_uv_coords;
vertex_out.normal = in_normal;
vertex_out.texture_id = uint(round(in_texture_id));
gl_Position = vec4(in_position, 1.0);
}
Geometry
#version 330 core
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
uniform mat4 view_matrix;
uniform mat4 projection_matrix;
mat4 vp_matrix = projection_matrix * view_matrix;
in VertexData
{
vec2 uv_coord;
vec3 normal;
uint texture_id;
} vertex_in[];
out VertexDataPass
{
vec2 uv_coord;
vec3 normal;
vec3 texture_ratio;
float brightness;
flat vec3 texture_ids;
} vertex_out;
void CalculateFakeBrightness(int index)
{
const vec3 light_direction = normalize(vec3(1,-1,1));
vec3 unit_normal = normalize(vertex_in[index].normal);
float normal_dot_light = dot(unit_normal, -light_direction);
vertex_out.brightness = max(0.2, normal_dot_light);
}
void main()
{
for(int i = 0; i < gl_in.length(); i++)
{
gl_Position = vp_matrix * gl_in[i].gl_Position;
vertex_out.uv_coord = vertex_in[i].uv_coord;
vertex_out.normal = vertex_in[i].normal;
vertex_out.texture_ids.x = vertex_in[0].texture_id;
vertex_out.texture_ids.y = vertex_in[1].texture_id;
vertex_out.texture_ids.z = vertex_in[2].texture_id;
CalculateFakeBrightness(i);
switch(int(mod(i,3)))
{
case 0:
vertex_out.texture_ratio = vec3(1,0,0);
break;
case 1:
vertex_out.texture_ratio = vec3(0,1,0);
break;
case 2:
vertex_out.texture_ratio = vec3(0,0,1);
break;
};
EmitVertex();
}
EndPrimitive();
}
Fragment
#version 330 core
in VertexDataPass
{
vec2 uv_coord;
vec3 normal;
vec3 texture_ratio;
float brightness;
flat vec3 texture_ids;
} vertex_data;
const int HORIZONTAL_IDS = 8;
const int VERTICAL_IDS = 8;
uniform sampler2D texture0_sampler;
out vec4 colour;
vec2 CorrectUVs(vec2 uvs)
{
vec2 corrected_uvs = uvs;
const float cushion = 0.001;
//Correct UV scale
while(corrected_uvs.x >= 1)
corrected_uvs.x--;
while(corrected_uvs.y >= 1)
corrected_uvs.y--;
if(corrected_uvs.x < cushion)
corrected_uvs.x = cushion;
if(corrected_uvs.x > 1 - cushion)
corrected_uvs.x = 1 - cushion;
if(corrected_uvs.y < cushion)
corrected_uvs.y = cushion;
if(corrected_uvs.y > 1 - cushion)
corrected_uvs.y = 1 - cushion;
return corrected_uvs;
}
vec4 GetTexture(uint id, vec2 uv_coords)
{
vec2 step = vec2(
1.0/HORIZONTAL_IDS,
1.0/VERTICAL_IDS
);
uv_coords.x/=HORIZONTAL_IDS;
uv_coords.y/=VERTICAL_IDS;
uv_coords.x += step.x * mod(id, HORIZONTAL_IDS);
uv_coords.y += step.y * floor(float(id)/VERTICAL_IDS);
//Texture is upsidedown
uv_coords.y = 1.0 - uv_coords.y;
return texture(texture0_sampler, uv_coords);
}
void main()
{
vec2 uvs = CorrectUVs(vertex_data.uv_coord);
colour =
GetTexture(uint(vertex_data.texture_ids.x), uvs) * vertex_data.texture_ratio.x +
GetTexture(uint(vertex_data.texture_ids.y), uvs) * vertex_data.texture_ratio.y +
GetTexture(uint(vertex_data.texture_ids.z), uvs) * vertex_data.texture_ratio.z;
if(colour.a == 0)
discard;
colour.xyz *= vertex_data.brightness;
}
I have a vertex shader that for some reason I can't get the location of one of the uniforms.
I use glGetActiveUniformto get all the uniforms available, and my uniform is there (bones[0]).
However, when I call glGetUniformLocation(shaderProgram_, "bones[0]");, it returns -1.
I also tried glGetUniformLocation(shaderProgram_, "bones");, but it also returns -1.
Here's the shader:
#version 330 core
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 pvmMatrix;
uniform mat3 normalMatrix;
layout (std140) uniform Bones
{
mat4 bones[100];
};
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
layout (location = 2) in vec3 normal;
layout (location = 3) in vec2 textureCoordinate;
layout (location = 4) in ivec4 boneIds;
layout (location = 5) in vec4 boneWeights;
out vec4 ourColor;
out vec2 texCoord;
out vec3 normalDirection;
void main()
{
mat4 bones2[100];
for(int i=0;i<100;++i)
{
bones2[i] = mat4(1.0);
}
// Calculate the transformation on the vertex position based on the bone weightings
mat4 boneTransform = bones2[ boneIds[0] ] * boneWeights[0];
boneTransform += bones2[ boneIds[1] ] * boneWeights[1];
boneTransform += bones2[ boneIds[2] ] * boneWeights[2];
boneTransform += bones2[ boneIds[3] ] * boneWeights[3];
//mat4 tempM = mat4(1.0);
//boneTransform = tempM;
// This is for animating the model
vec4 tempPosition = boneTransform * vec4(position, 1.0);
gl_Position = pvmMatrix * tempPosition;
float sum = boneWeights[0] + boneWeights[1] + boneWeights[2] + boneWeights[3];
if (sum > 1.01f)
gl_Position = pvmMatrix * vec4(position, 1.0);
else if (sum < 0.99f)
gl_Position = pvmMatrix * vec4(position, 1.0);
/*
if (boneIds[0] > 99 || boneIds[0] < 0)
gl_Position = pvmMatrix * vec4(position, 1.0);
else if (boneIds[1] > 99 || boneIds[1] < 0)
gl_Position = pvmMatrix * vec4(position, 1.0);
else if (boneIds[2] > 99 || boneIds[2] < 0)
gl_Position = pvmMatrix * vec4(position, 1.0);
else if (boneIds[3] > 99 || boneIds[3] < 0)
gl_Position = pvmMatrix * vec4(position, 1.0);
*/
// Calculate normal
vec4 normalDirTemp = boneTransform * vec4(normal, 0.0);
normalDirection = normalize(normalMatrix * normalDirTemp.xyz);
//gl_Position = vec4(position, 1.0);
//gl_Position = pvmMatrix * vec4(position, 1.0);
ourColor = color;
texCoord = textureCoordinate;
for(int i=0;i<100;++i)
{
if (bones[1] == mat4(0.0))
ourColor = vec4(0.0, 0.0, 1.0, 1.0);
}
}
I also tried using uniform mat4 bones[100]; in my shader, which did give me the uniform location (0), however, all of the data was mat4(0.0), even though I'm pushing data to the uniform.
Anyone have any ideas?
Uniforms in a uniform block do not have locations. You set their values by binding a buffer object to the appropriate binding index for that block. This is the entire point of putting uniforms in interface blocks.
In OpenGL you can't get the position of a particular array index directly. Instead, you should do glGetUniformLocation(shaderProgram_, "bones");. This will give you the location of the first element of the array. If you want to access another elements, like bones[1] or bones[20], you have to add the desired index number to the value returned by glGetUniformLocation.
So, the location of bones[0] is retrieved using glGetUniformLocation(shaderProgram_, "bones"); , the location of bones[1] is retrieved using glGetUniformLocation(shaderProgram_, "bones") + 1; , and so on.