Can't find uniforms in the fragmentShader lwgl 3 - opengl

the problem is in the title.
Console error
LWJGL Version: 3.0.0 build 90
GLFW Version: 3.2.0 Win32 WGL EGL VisualC DLL
OpenGL Version: 4.0.0 NVIDIA 372.70
java.lang.Exception: Can't find uniform: lightColor
at com.ms.shaders.ShaderProgram.getUniformLocation(ShaderProgram.java:50)
at com.ms.shaders.Shaders.createUniforms(Shaders.java:32)
ShaderProgram
public class ShaderProgram {
private int programID;
private int vertexShaderID;
private int fragmentShaderID;
private Map<String, Integer> uniforms;
public ShaderProgram() {
uniforms = new HashMap<>();
}
public void createProgram() throws Exception {
programID = glCreateProgram();
if(programID == 0) {
throw new Exception("Failed to create program");
}
}
public void createShaders(String vertexFile, String fragmentFile) throws Exception {
vertexShaderID = shadersLoader(vertexFile, GL_VERTEX_SHADER);
}
protected void bindAttribute(int attribute, String name) {
glBindAttribLocation(programID, attribute, name);
}
public void getUniformLocation(String uniform) throws Exception {
int uniformLocation = glGetUniformLocation(programID, uniform);
if(uniformLocation < 0) {
throw new Exception("Can't find uniform: " + uniform);
}
uniforms.put(uniform, uniformLocation);
}
public void floatUniforms(String uniform, float value) {
glUniform1f(uniforms.get(uniform), value);
}
public void intUniforms(String uniform, int value) {
glUniform1i(uniforms.get(uniform), value);
}
public void booleanUniforms(String uniform, boolean value) {
float load = 0;
if(value) {
load = 1;
}
glUniform1f(uniforms.get(uniform), load);
}
public void vectorUniforms(String uniform, Vector3f value) {
glUniform3f(uniforms.get(uniform), value.x, value.y, value.z);
}
public void matrixUniforms(String uniform, Matrix4f value) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
value.get(buffer);
glUniformMatrix4fv(uniforms.get(uniform), false, buffer);
}
public int shadersLoader(String shader, int type) throws Exception {
int shaderID = glCreateShader(type);
glShaderSource(shaderID, shader);
glCompileShader(shaderID);
if(glGetShaderi(shaderID, GL_COMPILE_STATUS) == 0) {
throw new Exception("Failed to compile Shader: " + glGetShaderInfoLog(shaderID, 1024));
}
glAttachShader(programID, shaderID);
return shaderID;
}
public void linkProgram() throws Exception {
glLinkProgram(programID);
if(glGetProgrami(programID, GL_LINK_STATUS) == 0) {
throw new Exception("Failed to link program: " + glGetProgramInfoLog(programID, 1024));
}
glValidateProgram(programID);
if(glGetProgrami(programID, GL_VALIDATE_STATUS) == 0) {
throw new Exception("Failed to validate program: " + glGetProgramInfoLog(programID, 1024));
}
}
public void bind() {
glUseProgram(programID);
}
public void unbind() {
glUseProgram(0);
}
public void cleanUp() {
unbind();
if(programID != 0) {
if(vertexShaderID != 0) {
glDetachShader(programID, vertexShaderID);
glDeleteShader(vertexShaderID);
}
if(fragmentShaderID != 0) {
glDetachShader(programID, fragmentShaderID);
glDeleteShader(fragmentShaderID);
}
glDeleteProgram(programID);
}
}
}
Shaders
public class Shaders extends ShaderProgram {
private static final String VERTEX_SHADER = "vertexShader.txt";
private static final String FRAGMENT_SHADER = "fragmentShader.txt";
public void init() throws Exception {
createProgram();
createShaders(FileLoader.loadResources(VERTEX_SHADER), FileLoader.loadResources(FRAGMENT_SHADER));
linkProgram();
createUniforms();
}
public void bindAttributes() {
bindAttribute(0, "position");
bindAttribute(1, "textureCoords");
bindAttribute(2, "normal");
}
public void createUniforms() throws Exception {
getUniformLocation("transformationMatrix");
getUniformLocation("projectionMatrix");
getUniformLocation("viewMatrix");
getUniformLocation("lightPosition");
getUniformLocation("lightColor");
getUniformLocation("shineDamper");
getUniformLocation("reflectivity");
}
}
fragmentShader.txt
#version 400 core
in vec2 outTextureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCameraVector;
out vec4 outColor;
uniform sampler2D textureSampler;
uniform vec3 lightColor;
uniform float shineDamper;
uniform float reflectivity;
void main()
{
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
float nDotl = dot(unitNormal, unitLightVector);
float brightness = max(nDotl, 0.2);
vec3 diffuse = brightness * lightColor;
vec3 unitVectorToCamera = normalize(toCameraVector);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);
float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
specularFactor = max(specularFactor, 0.0);
float dampFactor = pow(specularFactor, shineDamper);
vec3 finalSpecular = dampFactor * reflectivity * lightColor;
outColor = vec4(diffuse, 1.0) * texture(textureSampler, outTextureCoords) + vec4(finalSpecular, 1.0);
}
If i try to remove lightColor uniform the error switch in the shineDamper uniform.
EDITED
If i put all in the Renderer class the problem don't exist... Why?
This is the class where I set uniforms:
UniformCreation
public class UniformsCreation {
private Transformation transformation;
private ShaderProgram shaders;
private float FOV = (float) Math.toRadians(60.0f);
private float zNEAR = 0.01f;
private float zFAR = 1000.0f;
public UniformsCreation() {
transformation = new Transformation();
shaders = new ShaderProgram();
}
public void renderer(Entity[] entity, Camera camera, Light light) {
createProjectionMatrix();
createTransformationMatrix(entity);
createViewMatrix(camera);
createLight(light, Texture.getShineDamper(), Texture.getReflection());
}
public Matrix4f createProjectionMatrix() {
Matrix4f projectionMatrix = new Matrix4f();
projectionMatrix = transformation.createProjectionMatrix(
FOV,
Main.getWIDTH(),
Main.getHEIGHT(),
zNEAR,
zFAR);
shaders.matrixUniforms("projectionMatrix", projectionMatrix);
return projectionMatrix;
}
public Matrix4f createTransformationMatrix(Entity[] entity) {
Matrix4f transformationMatrix = new Matrix4f();
for(Entity entities : entity) {
transformationMatrix = transformation.createTransformationMatrix(
entities.getPosition(),
entities.getRotation(),
entities.getScale());
shaders.matrixUniforms("transformationMatrix", transformationMatrix);
entities.getMesh().render();
}
return transformationMatrix;
}
public Matrix4f createViewMatrix(Camera camera) {
Matrix4f viewMatrix = new Matrix4f();
viewMatrix = transformation.createViewMatrix(camera);
shaders.matrixUniforms("viewMatrix", viewMatrix);
return viewMatrix;
}
public void createLight(Light light, float damper, float reflectivity) {
shaders.vectorUniforms("lightPosition", light.getPosition());
shaders.vectorUniforms("lightColor", light.getColor());
shaders.floatUniforms("shineDamper", damper);
shaders.floatUniforms("reflectivity", reflectivity);
}
}
If I remove the lightColor, shineDamper and reflectivity uniforms the error is:
java.lang.NullPointerException
at com.ms.shaders.ShaderProgram.matrixUniforms(ShaderProgram.java:83)
at com.ms.utils.UniformsCreation.createProjectionMatrix(UniformsCreation.java:46)
at com.ms.utils.UniformsCreation.renderer(UniformsCreation.java:29)
at com.ms.renderer.Renderer.render(Renderer.java:42)
at com.ms.MineSmooth.gameLoop(MineSmooth.java:93)
at com.ms.MineSmooth.run(MineSmooth.java:56)
at java.lang.Thread.run(Unknown Source)

Negative uniform locations are perfectly cromulent:
Although not strictly a mistake, some wonder why glGetUniformLocation​
returns -1. If there is a uniform that you are not using, the driver
will optimize your uniform out. Drivers are really good at optimizing
code. If you are using your uniform, but none of the values computed
from that uniform contribute to any output from the shader (directly
or indirectly), the uniform will usually be optimized out.
Typically this is not a problem, since if you pass -1 instead of a
valid uniform location to the glUniform​ calls, they will quietly do
nothing anyway. But you will also get -1 if you misspell the variable
name to glGetUniformLocation​, so keep this in mind.
Enumerate uniform names via the shader introspection API to check for spelling mistakes.

Related

libgdx: mesh color not making it to vertex shader

I've implemented my own shader (see below), which I use to render meshes in a ModelBatch. The shader program seems to be bound correctly as I can see geometry on the screen in the correct locations so the camera transform is also setup correctly.
public class ModelShader implements Shader {
ShaderProgram program;
Camera camera;
RenderContext context;
int u_projTrans;
int u_worldTrans;
public void init() {
String vert = Gdx.files.internal("first_vertex.glsl").readString();
String frag = Gdx.files.internal("first_fragment.glsl").readString();
program = new ShaderProgram(vert, frag);
if (!program.isCompiled()) {
throw new GdxRuntimeException(program.getLog());
}
u_projTrans = program.getUniformLocation("u_projTrans");
u_worldTrans = program.getUniformLocation("u_worldTrans");
}
public void dispose() { ... }
public void begin(Camera camera, RenderContext context) {
this.camera = camera;
this.context = context;
program.begin();
program.setUniformMatrix(u_projTrans, camera.combined);
context.setDepthTest(GL20.GL_LEQUAL);
context.setCullFace(GL20.GL_BACK);
}
public void render(Renderable renderable) {
program.setUniformMatrix(u_worldTrans, renderable.worldTransform);
renderable.meshPart.render(program);
}
public void end() {
program.end();
}
public int compareTo(Shader other) { ... }
public boolean canRender(Renderable instance) {
return true;
}
}
The only problem I'm having now is the color isn't coming down. I have some meshes I setup as below with a diffuse color.
model = modelBuilder.createBox(1f, SIZE, SIZE, new Material(ColorAttribute.createDiffuse(Color.MAGENTA)), Usage.Position | Usage.Normal);
box = new ModelInstance(model);
I've verified the color from the vertex shader is making it to the fragment shader, but when I set the vertex shader varying property to the a_color, the scene is all red making me think the color isn't coming down at all. I had valid colors with these meshes when I was using the builtin shader so I'm doing something wrong.
attribute vec3 a_position;
attribute vec4 a_color;
uniform mat4 u_projTrans;
uniform mat4 u_worldTrans;
varying vec4 vColor;
void main() {
vColor = a_color; // hard-coding a color will show up on screen
gl_Position = u_projTrans * u_worldTrans * vec4(a_position, 1.0);
}
Is the a_color the wrong attribute to use here? Am I supposed to bind something manually or is that all done by the meshPart.render() call?

Attribute being removed by compiler, but I can't see why

I'm trying to write a set of shaders to do per-vertex lighting with multiple lights, and textures. I think I'm running into the shader compiler optimizing out 'v_texture', one of my attribute variables, because glVertexAttribLocation is failing to find it.
Here's my vertex shader code:
attribute vec3 v_position;
attribute vec3 v_normal;
attribute vec2 v_texture;
varying vec4 color;
varying vec2 texCoord;
const int MAX_LIGHTS = 8;
uniform struct lightSource
{
vec4 position;
vec4 color;
vec3 coneDirection;
float coneAngle;
float ambientFactor;
} sceneLights[MAX_LIGHTS];
uniform mat4 modelView;
uniform mat4 Projection;
uniform float shininess;
uniform int numLights;
vec4 applyLight(lightSource light)
{
vec4 outColor;
float attenuation;
vec3 surfacePos = (modelView * vec4(v_position.xyz, 1.0)).xyz;
vec3 toLight;
if(light.position.w == 0.0)
{
toLight = normalize(light.position.xyz);
attenuation = 1.0;
}
else
{
toLight = normalize(light.position.xyz - surfacePos);
float distanceToLight = length(light.position.xyz - surfacePos);
float lightAngle = degrees(acos(dot(-surfacePos, normalize(light.coneDirection))));
if(lightAngle > light.coneAngle)
{
attenuation = 0.0;
}
else
{
attenuation = 1.0/(1.0 + (0.1 * pow(distanceToLight, 2.0)));
}
}
vec3 Eye = normalize(-surfacePos);
vec3 Halfway = normalize(toLight + Eye);
vec3 worldNormal = normalize(modelView * vec4(v_normal, 0.0)).xyz;
vec4 ambient = vec4(light.ambientFactor * vec3(light.color.xyz), 1.0);
float Kd = max(dot(toLight, worldNormal), 0.0);
vec4 diffuse = Kd * light.color;
float Ks = pow(max(dot(worldNormal, Halfway), 0.0), shininess);
vec4 specular = Ks * light.color;
if(dot(toLight, worldNormal) < 0.0)
{
specular = vec4(0.0, 0.0, 0.0, 0.0);
}
outColor = ambient + (attenuation * (diffuse + specular));
outColor.a = 1.0;
return outColor;
}
void main(void)
{
vec4 colorSum;
colorSum = vec4(0, 0, 0, 0);
for(int i = 0; i < MAX_LIGHTS; i++)
{
if(i >= numLights)
{
break;
}
colorSum += applyLight(sceneLights[i]);
}
colorSum.xyzw = normalize(colorSum.xyzw);
vec3 gammaCorrection = vec3(1.0/2.2);
color = vec4(pow(vec3(colorSum.xyz), gammaCorrection), 1.0);
texCoord = v_texture;
gl_Position = Projection * modelView * vec4(v_position.xyz, 1.0);
}
And the fragment shader:
varying vec4 color;
varying vec2 texCoord;
uniform sampler2D texSampler;
void main(void)
{
gl_FragColor = (color * texture2D(texSampler, texCoord.xy));
}
I've been over the code top to bottom but I just can't see where my problem is. I'm assigning v_texture to the texCoord, and passing it to the frag shader, where I'm using it together with the final lighting result from the vertex shader to yield the final color. I'm checking for shader errors when I compile them, and I'm not getting anything. My only guess at the moment is that maybe gl_FragColor = (color * texture2D(texSampler, texCoord.xy)) isn't a valid statement, but then shouldn't this have caught it?
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &shader_status);
if (!shader_status)
{
GLchar InfoLog[1024];
glGetShaderInfoLog(fragment_shader, sizeof(InfoLog), NULL, InfoLog);
fprintf(stderr, "Fragment Shader %d: '%s'\n", fragment_shader, InfoLog);
}
Edit: I probably should have put this in here in the first place, but this snippet is the shader section from my C++ program's initialize() function. The only one of the glGetAttribLocation calls to fail is for v_texture.
// Begin shader loading.
//compile the shaders
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
GLint shader_status;
pass=new char [2048];
unsigned int len;
//Give a maximum number of attempts to load the vertex shader
int attempts=10;
//Load the vertex shader
do
{
loader.load("lighting.vsh");
shaderCode = loader.hold.c_str();
len=loader.length;
pass=shaderCode;
attempts-=1;
}
while(len!=pass.length()&& attempts>0);
//Pass the temperary variable to a pointer
tmp = pass.c_str();
// Vertex shader first
glShaderSource(vertex_shader, 1,&tmp, NULL);
glCompileShader(vertex_shader);
//check the compile status
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &shader_status);
if (!shader_status)
{
GLchar InfoLog[1024];
glGetShaderInfoLog(vertex_shader, sizeof(InfoLog), NULL, InfoLog);
fprintf(stderr, "Vertex Shader %d: '%s'\n", vertex_shader, InfoLog);
}
const char *fs=loader.load("lighting.fsh");
// Now the Fragment shader
glShaderSource(fragment_shader, 1, &fs, NULL);
glCompileShader(fragment_shader);
//check the compile status
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &shader_status);
if (!shader_status)
{
GLchar InfoLog[1024];
glGetShaderInfoLog(fragment_shader, sizeof(InfoLog), NULL, InfoLog);
fprintf(stderr, "Fragment Shader %d: '%s'\n", fragment_shader, InfoLog);
}
//Now we link the 2 shader objects into a program
//This program is what is run on the GPU
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
//check if everything linked ok
glGetProgramiv(program, GL_LINK_STATUS, &shader_status);
if(!shader_status)
{
std::cerr << "[F] THE SHADER PROGRAM FAILED TO LINK" << std::endl;
return false;
}
//Now we set the locations of the attributes and uniforms
//this allows us to access them easily while rendering
loc_position = glGetAttribLocation(program,
const_cast<const char*>("v_position"));
if(loc_position == -1)
{
std::cerr << "Error: POSITION NOT FOUND IN SHADER" << std::endl;
return false;
}
loc_normals = glGetAttribLocation(program, const_cast<const char*>("v_normal"));
if(loc_normals == -1)
{
std::cerr << "Error: NORMALS NOT FOUND IN SHADER" << std:: endl;
return false;
}
loc_texture = glGetAttribLocation(program, const_cast<const char*>("v_texture"));
if(loc_texture == -1)
{
std::cerr << "[F] TEXTURE NOT FOUND IN SHADER" << std::endl;
return false;
}
// Begin light initialization.

Attribute Position_VS_in is bound to generic attribute 0, but gl_Vertex is also used

I am attempting to use four shaders: A vertex Shader (VS), a Tessellation Control Shader (TCS), a Tessellation Evaluation Shader (TES), and a Fragment Shader (FS).
However, when I attempt to load these shaders, I get:
This has been most baffling, and I have already spent a couple of hours trying to sort it out. However, I cannot see "gl_Vertex" anywhere in my code, so I am stuck really. I don't even know which shader is the problem.
Here is my current code for loading shaders (It looks like a lot, but it's really all just repeated code with slight changes):
public static int loadShaderPair(String vertexShaderLocation, String fragmentShaderLocation, String tesShaderLocation, String tesscontrolShaderLocation) {
int shaderProgram = glCreateProgram();
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
int tesscontrolShader = glCreateShader(GL40.GL_TESS_CONTROL_SHADER);
int tesShader = glCreateShader(GL40.GL_TESS_EVALUATION_SHADER);
StringBuilder vertexShaderSource = new StringBuilder();
StringBuilder fragmentShaderSource = new StringBuilder();
StringBuilder tesShaderSource = new StringBuilder();
StringBuilder tesscontrolShaderSource = new StringBuilder();
BufferedReader tesShaderFileReader = null;
try {
tesShaderFileReader = new BufferedReader(new FileReader(tesShaderLocation));
String line;
while ((line = tesShaderFileReader.readLine()) != null) {
tesShaderSource.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
return -1;
} finally {
if (tesShaderFileReader != null) {
try {
tesShaderFileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedReader tesscontrolShaderFileReader = null;
try {
tesscontrolShaderFileReader = new BufferedReader(new FileReader(tesscontrolShaderLocation));
String line;
while ((line = tesscontrolShaderFileReader.readLine()) != null) {
tesscontrolShaderSource.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
return -1;
} finally {
if (tesscontrolShaderFileReader != null) {
try {
tesscontrolShaderFileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedReader vertexShaderFileReader = null;
try {
vertexShaderFileReader = new BufferedReader(new FileReader(vertexShaderLocation));
String line;
while ((line = vertexShaderFileReader.readLine()) != null) {
vertexShaderSource.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
return -1;
} finally {
if (vertexShaderFileReader != null) {
try {
vertexShaderFileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedReader fragmentShaderFileReader = null;
try {
fragmentShaderFileReader = new BufferedReader(new FileReader(fragmentShaderLocation));
String line;
while ((line = fragmentShaderFileReader.readLine()) != null) {
fragmentShaderSource.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
return -1;
} finally {
if (fragmentShaderFileReader != null) {
try {
fragmentShaderFileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
glShaderSource(vertexShader, vertexShaderSource);
glCompileShader(vertexShader);
if (glGetShaderi(vertexShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("Vertex shader wasn't able to be compiled correctly. Error log:");
System.err.println(glGetShaderInfoLog(vertexShader, 1024));
return -1;
}
glShaderSource(tesscontrolShader, tesscontrolShaderSource);
glCompileShader(tesscontrolShader);
if (glGetShaderi(tesscontrolShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("tesscontrol shader wasn't able to be compiled correctly. Error log:");
System.err.println(GL11.glGetString(GL11.glGetError()));
System.err.println(glGetShaderInfoLog(tesscontrolShader, 1024));
}
glShaderSource(fragmentShader, fragmentShaderSource);
glCompileShader(fragmentShader);
if (glGetShaderi(fragmentShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("Fragment shader wasn't able to be compiled correctly. Error log:");
System.err.println(GL11.glGetString(GL11.glGetError()));
System.err.println(glGetShaderInfoLog(fragmentShader, 1024));
}
glShaderSource(tesShader, tesShaderSource);
glCompileShader(tesShader);
if (glGetShaderi(vertexShader, GL_COMPILE_STATUS) == GL_FALSE) {
System.err.println("Tessellation shader wasn't able to be compiled correctly. Error log:");
System.err.println(glGetShaderInfoLog(tesShader, 1024));
return -1;
}
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, tesShader);
glAttachShader(shaderProgram, tesscontrolShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
if (glGetProgrami(shaderProgram, GL_LINK_STATUS) == GL_FALSE) {
System.err.println("Shader program wasn't linked correctly.");
System.err.println(GL11.glGetString(GL11.glGetError()));
System.err.println(glGetProgramInfoLog(shaderProgram, 1024));
System.exit(1);
return -1;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteShader(tesShader);
glDeleteShader(tesscontrolShader);
return shaderProgram;
}
And here are my shaders:
VS:
layout (location = 0) in vec3 Position_VS_in;
layout (location = 1) in vec2 TexCoord_VS_in;
layout (location = 2) in vec3 Normal_VS_in;
uniform mat4 gWorld;
out vec3 WorldPos_CS_in;
out vec2 TexCoord_CS_in;
out vec3 Normal_CS_in;
void main()
{
WorldPos_CS_in = (gWorld * vec4(Position_VS_in, 1.0)).xyz;
TexCoord_CS_in = TexCoord_VS_in;
Normal_CS_in = (gWorld * vec4(Normal_VS_in, 0.0)).xyz;
gl_Position = ftransform();
}
TCS:
// define the number of CPs in the output patch
layout (vertices = 3) out;
uniform vec3 gEyeWorldPos;
// attributes of the input CPs
in vec3 WorldPos_CS_in[];
in vec2 TexCoord_CS_in[];
in vec3 Normal_CS_in[];
// attributes of the output CPs
out vec3 WorldPos_ES_in[];
out vec2 TexCoord_ES_in[];
out vec3 Normal_ES_in[];
float GetTessLevel(float Distance0, float Distance1)
{
float AvgDistance = (Distance0 + Distance1) / 2.0;
if (AvgDistance <= 2.0) {
return 10.0;
}
else if (AvgDistance <= 5.0) {
return 7.0;
}
else {
return 3.0;
}
}
void main()
{
// Set the control points of the output patch
TexCoord_ES_in[gl_InvocationID] = TexCoord_CS_in[gl_InvocationID];
Normal_ES_in[gl_InvocationID] = Normal_CS_in[gl_InvocationID];
WorldPos_ES_in[gl_InvocationID] = WorldPos_CS_in[gl_InvocationID];
// Calculate the distance from the camera to the three control points
float EyeToVertexDistance0 = distance(gEyeWorldPos, WorldPos_ES_in[0]);
float EyeToVertexDistance1 = distance(gEyeWorldPos, WorldPos_ES_in[1]);
float EyeToVertexDistance2 = distance(gEyeWorldPos, WorldPos_ES_in[2]);
// Calculate the tessellation levels
gl_TessLevelOuter[0] = GetTessLevel(EyeToVertexDistance1, EyeToVertexDistance2);
gl_TessLevelOuter[1] = GetTessLevel(EyeToVertexDistance2, EyeToVertexDistance0);
gl_TessLevelOuter[2] = GetTessLevel(EyeToVertexDistance0, EyeToVertexDistance1);
gl_TessLevelInner[0] = gl_TessLevelOuter[2];
}
TES:
layout(triangles, equal_spacing, ccw) in;
uniform mat4 gVP;
uniform sampler2D gDisplacementMap;
uniform float gDispFactor;
in vec3 WorldPos_ES_in[];
in vec2 TexCoord_ES_in[];
in vec3 Normal_ES_in[];
out vec3 WorldPos_FS_in;
out vec2 TexCoord_FS_in;
out vec3 Normal_FS_in;
vec2 interpolate2D(vec2 v0, vec2 v1, vec2 v2)
{
return vec2(gl_TessCoord.x) * v0 + vec2(gl_TessCoord.y) * v1 + vec2(gl_TessCoord.z) * v2;
}
vec3 interpolate3D(vec3 v0, vec3 v1, vec3 v2)
{
return vec3(gl_TessCoord.x) * v0 + vec3(gl_TessCoord.y) * v1 + vec3(gl_TessCoord.z) * v2;
}
void main()
{
// Interpolate the attributes of the output vertex using the barycentric coordinates
TexCoord_FS_in = interpolate2D(TexCoord_ES_in[0], TexCoord_ES_in[1], TexCoord_ES_in[2]);
Normal_FS_in = interpolate3D(Normal_ES_in[0], Normal_ES_in[1], Normal_ES_in[2]);
Normal_FS_in = normalize(Normal_FS_in);
WorldPos_FS_in = interpolate3D(WorldPos_ES_in[0], WorldPos_ES_in[1], WorldPos_ES_in[2]);
// Displace the vertex along the normal
float Displacement = texture(gDisplacementMap, TexCoord_FS_in.xy).x;
WorldPos_FS_in += Normal_FS_in * Displacement * gDispFactor;
gl_Position = gVP * vec4(WorldPos_FS_in, 1.0);
}
FS:
varying vec4 position_in_view_space;
uniform sampler2D color_texture;
void main()
{
float dist = distance(position_in_view_space,
vec4(0.0, 0.0, 0.0, 1.0));
if (dist < 1000.0)
{
gl_FragColor = gl_Color;
// color near origin
}
else
{
gl_FragColor = gl_Color;
//kill;
//discard;
//gl_FragColor = vec4(0.3, 0.3, 0.3, 1.0);
// color far from origin
}
}
If for any reason it helps, my PC supports up to (and including) OpenGL 4.0.
Since I have been unable to work out how I am supposedly using a line of code I am not using, I am hoping one of you will be able to diagnose the issue.
Well, the error message is very clear, and the reason is this:
layout (location = 0) in vec3 Position_VS_in;
[...]
gl_Position = ftransform();
ftransform is a legacy function which uses the legacy bultin vertex position attribute gl_Vertex to transform a vertex according to the also legacy bultin matrix uniforms.
The GL spec also requires the generic vertex attribute 0 to alias the old builtin gl_Vertex, so your attribute index 0 is blocked by this and you must not assign some other attribute to this.
Now it is totally unclear why you use ftransform here. It seems like you don't want that at all. But I can't be sure about that. But it will definitively not work that way. You shouldn't use that deprecated stuff at all, in my opinion.
UPDATE 1
Note that ftransform is in princicple equivalent to gl_ModelViewProjectionMatrix * gl_Vertex, with gl_ModelViewProjectionMatrix being a builtin uniform representing the product P * MV of the matrices you set for GL_PROJECTION and GL_MODELVIEW using the also-deprecated GL matrix stack, and gl_Vertex being the builtin vertex position attribute set with glVertex.../glVertexPointer/glVertexAttribPointer(0,...). Both can be replaced by user-defined attributes/uniforms.
The only twist with ftransform is that it is also guaranteed to get the exact same result as rendering with the fixed function pipeline does, for the same inputs. That was useful for multi-pass algorithms where some passed needed to render with shaders, while others used the fixed function pipelinew. Such a function was needed because there might be slight numerical differences if the shader does not use the exact same formula as the GL implementation when rendering without shaders.

My code renders a black screen

I'm trying to render a simple wire frame cube using JOGL.
However I am presented with a black screen, can anyone with more experience than me tell if I'm doing something wrong?
The shaders compile and throw no errors.
private Mat4 projectionMatrix;
//reference to the uniform MPV matrix in the vertex shader
private int mpvUnif;
//Holds the references to GL objects
private final int[] glPointers = new int[3];
private static final int VBO = 0;
private static final int INDEXBUFFER = 1;
private static final int VAO = 2;
private int shaderProgram;
private FloatBuffer vertexDataBuffer;
private ShortBuffer indexDataBuffer;
private float[] testCube = new float[] {
//Top
-1, 1, 1, //0
1, 1, 1, //1
-1, -1, 1, //2
1, -1, 1, //3
//Bottom
-1, 1, -1, //4
1, 1, -1, //5
-1, -1, -1, //6
1, -1, -1, //7
};
private short[] testCubeIndexes = new short[] {
0,1,2,3,
4,5,6,7,
0,1,4,5,
2,3,6,7,
0,2,4,6,
1,3,5,7
};
public GLController() {
this.vertexDataBuffer = FloatBuffer.wrap(testCube);
this.indexDataBuffer = ShortBuffer.wrap(testCubeIndexes);
}
#Override
public void init(GLAutoDrawable drawable) {
GL3 gl = drawable.getGL().getGL3();
shaderProgram = gl.glCreateProgram();
try {
InitializeVertexBuffer(gl);
InitializeVertexArrayObjects(gl);
initShaders(gl);
} catch (IOException e) {
e.printStackTrace();
}
gl.glPolygonMode(GL3.GL_FRONT_AND_BACK, GL3.GL_LINE);
gl.glFrontFace(GL3.GL_CW);
}
#Override
public void display(GLAutoDrawable drawable) {
GL3 gl = drawable.getGL().getGL3();
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClear(GL3.GL_COLOR_BUFFER_BIT);
gl.glUseProgram(shaderProgram);
gl.glBindVertexArray(glPointers[VAO]);
gl.glDrawElements(GL3.GL_QUADS, indexDataBuffer.capacity(), GL3.GL_UNSIGNED_SHORT, 0);
gl.glBindVertexArray(0);
gl.glUseProgram(0);
}
#Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
GL3 gl = drawable.getGL().getGL3();
mpvUnif = gl.glGetUniformLocation(shaderProgram, "MPV");
projectionMatrix = Matrices.perspective(60f, width/height, .1f, 100f);
gl.glUseProgram(shaderProgram);
gl.glUniformMatrix4fv(mpvUnif, 1, GLHelper.glBool(GL3.GL_FALSE), projectionMatrix.getBuffer());
gl.glUseProgram(0);
}
/**
* Called in GLEventListener.init()
* #param gl
*/
private void InitializeVertexBuffer(GL3 gl) {
gl.glGenBuffers(1, glPointers, VBO);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, glPointers[VBO]);
gl.glBufferData(GL3.GL_ARRAY_BUFFER, GLHelper.sizeof(vertexDataBuffer), vertexDataBuffer, GL3.GL_STATIC_DRAW);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);
gl.glGenBuffers(1, glPointers, INDEXBUFFER);
gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, glPointers[INDEXBUFFER]);
gl.glBufferData(GL3.GL_ELEMENT_ARRAY_BUFFER, GLHelper.sizeof(indexDataBuffer), indexDataBuffer, GL3.GL_STATIC_DRAW);
gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, 0);
}
/**
* Called in GLEventListener.init()
* #param gl
*/
private void InitializeVertexArrayObjects(GL3 gl) {
gl.glGenVertexArrays(1, glPointers, VAO);
gl.glBindVertexArray(glPointers[VAO]);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, glPointers[VBO]);
gl.glEnableVertexAttribArray(0);
gl.glVertexAttribPointer(0, 3, GL3.GL_FLOAT, GLHelper.glBool(GL3.GL_FALSE), 0, 0);
gl.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, glPointers[INDEXBUFFER]);
gl.glBindVertexArray(0);
}
My vertex shader:
#version 330
layout(location = 0) in vec3 vertexPosition_modelspace;
uniform mat4 MVP;
void main()
{
vec4 v = vec4(vertexPosition_modelspace, 1);
gl_Position = MVP * v;
}
This shader does draw something on the screen:
#version 330
layout(location = 0) in vec3 vertexPosition_modelspace;
uniform mat4 MVP;//not used
void main()
{
gl_Position = vec4(vertexPosition_modelspace, 1);
}
My fragment shader:
#version 330
out vec4 outputColor;
void main()
{
outputColor = vec4(1.0, 1.0, 1.0, 1.0);
}
I'm feeling so silly, the main problem was that MVP in the shader was referenced as MPV! Thanks to gouessej for trying to help.

Why is this glsl shader causing an "Invalid Operation" when trying to use the program?

I'm checking the logs, and everything compiles fine. The shader looks like this:
Vertex:
#version 330 core
layout(location = 0) in struct InData {
vec3 position;
vec4 color;
} inData;
out struct OutData {
vec3 position;
vec4 color;
} outData;
void main()
{
outData.position = inData.position;
outData.color = inData.color;
}
Fragment:
#version 330 core
in struct InData {
vec2 position;
vec4 color;
} inData;
out vec4 color;
void main(){
color = inData.color;
}
I'm preparing the shader like this:
public Shader(string src, ShaderType type)
{
shaderId = GL.CreateShader(type);
GL.ShaderSource(shaderId, GetShader(src));
GL.CompileShader(shaderId);
EventSystem.Log.Message(GL.GetShaderInfoLog(shaderId));
EventSystem.Log.Message("GLERROR: " + GL.GetError());
packs = new List<ShaderPack>();
}
public void Attach(ShaderPack pack)
{
packs.Add(pack);
GL.AttachShader(pack.ProgramID, shaderId);
EventSystem.Log.Message(GL.GetProgramInfoLog(pack.ProgramID));
EventSystem.Log.Message("GLERROR: " + GL.GetError());
}
Then I compile the shader:
public void Compile()
{
if(program >= 0)
GL.DeleteProgram(program);
program = GL.CreateProgram();
foreach (var s in shaders.Values)
s.Attach(this);
EventSystem.Log.Message(GL.GetProgramInfoLog(program));
EventSystem.Log.Message("GLERROR: " + GL.GetError());
}
And then I'm trying to use it:
mesh = new Mesh();
mesh.AddTriangle(
new Vector3(0, 0, 0), new Vector4(1, 0, 0, 1),
new Vector3(0, sizeY, 0), new Vector4(0, 1, 0, 1),
new Vector3(sizeX, sizeY, 0), new Vector4(0, 0, 1, 1));
mesh.RefreshBuffer();
shaderPack.Apply();
shaderPack.SetVertexAttribute<Mesh.MeshData1>("vertex", 0, mesh.meshData);
EventSystem.Log.Message("GLERROR: " + GL.GetError());
In Apply GL.UseProgram is called and GetError returns "Invalid Operation"
UPDATE:
Okay I changed the code:
public void Compile()
{
if(program >= 0)
GL.DeleteProgram(program);
program = GL.CreateProgram();
foreach (var s in shaders.Values)
s.Attach(this);
// GL.LinkProgram(program);
//GL.ValidateProgram(program);
GL.ValidateProgram(program);
EventSystem.Log.Message("Validate: " + GL.GetProgramInfoLog(program) + " - " + GL.GetError());
}
public void Apply()
{
GL.UseProgram(program);
EventSystem.Log.Message("GLERROR (Apply): " + GL.GetError());
}
And the output is
[23:25:55][Log]: Validate: - NoError
[23:25:55][Log]: GLERROR (Apply): InvalidOperation
edit: Okay I changed the vertex shaders:
#version 330 core
layout(location = 0) in struct InData {
vec3 position;
vec4 color;
} inData;
void main()
{
gl_Position = vec4(inData.position, 1);
}
...
#version 330 core
//in struct InData {
// vec2 position;
// vec4 color;
//} inData;
out vec4 color;
void main(){
color = vec4(1,0,0,1);
}
It compiles without errors, but I have a blank screen...
Pre-Rollback:
EDIT: Okay, I suspect the problem lies here:
public void VertexAttribute<T>(int loc, ShaderPack p, T[] dataArray) where T : struct
{
int buf;
GL.GenBuffers(1, out buf);
GL.BindBuffer(BufferTarget.ArrayBuffer, buf);
GL.BufferData<T>(BufferTarget.ArrayBuffer, (IntPtr)(dataArray.Length * Marshal.SizeOf(typeof(T))), dataArray, BufferUsageHint.StaticDraw);
GL.EnableVertexAttribArray(0);
GL.VertexAttribPointer<T>(loc, 2, VertexAttribPointerType.Float, false, 0, ref dataArray[0]);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
}
I'm passing this with an Array of the following type:
public struct MeshData1
{
public Vector3 vertex;
public Vector4 color;
public MeshData1(Vector3 vertex, Vector4 color)
{
this.vertex = vertex;
this.color = color;
}
}
And the input looks like this:
#version 330 core
layout(location = 0) in struct InData {
vec3 position;
vec4 color;
} inData;
void main()
{
gl_Position = vec4(inData.position, 1.0);
}
What am I doing wrong?
Two problems immediately come to mind:
You never linked the attached shader stages in your program object (most important)
The string output by glGetProgramInfoLog (...) is only generated/updated after linking or validating a GLSL program.
To fix this, you should make a call to glLinkProgram (...) after attaching your shaders, and also understand that up until you do this the program info log will be undefined.
glValidateProgram (...) is another way of updating the contents of the program info log. In addition to generating the info log, this function will also return whether your program is in a state suitable for execution or not. The result of this operation is stored in a per-program state called GL_VALIDATE_STATUS.