0

I'm trying to draw a sphere with just a diffuse color, but nothing shows up. All the OpenGL code should be correct, because if I swap the "color" shader with "textured" shader, everything shows up nicely.

This is the shader selection code. The if-branch is for the textured objects, and the else-branch is for color-only objects.

GL.Disable(EnableCap.Blend);

if (phong.diffuseTexture != 0)
{
    texturedShader.Enable();
    GL.UniformMatrix4(texturedShader.GetUniformLocation("view"), false, ref camView);
    GL.UniformMatrix4(texturedShader.GetUniformLocation("projection"), false, ref Camera.main.projection);

    GL.ActiveTexture(TextureUnit.Texture0);
    GL.BindTexture(TextureTarget.Texture2D, phong.diffuseTexture);
    int colorMapLoc = Shader.currentShader.GetUniformLocation("colorMap");
    if (colorMapLoc > -1) GL.Uniform1(colorMapLoc, 0);
}
else
{
    coloredShader.Enable();
    GL.UniformMatrix4(texturedShader.GetUniformLocation("view"), false, ref camView);
    GL.UniformMatrix4(texturedShader.GetUniformLocation("projection"), false, ref Camera.main.projection);
}

// Continues with the VBO rendering code...

So the first branch works, but the second branch outputs nothing. Here's the color-only shaders (most of it is just copy-paste from the textured shader, that's why there's texcoords etc. still there):

// VERTEX SHADER
#version 330

uniform mat4 projection;
uniform mat4 view;
uniform mat4 world;

uniform vec3 diffuseColor;

layout(location = 0) in vec3 in_position;
layout(location = 1) in vec3 in_normal;
layout(location = 2) in vec2 in_texcoord;
layout(location = 3) in vec3 in_tangent;
layout(location = 4) in vec3 in_binormal;

out mat3 tangentToWorld;
out vec2 texcoord;
out vec3 normal;
out vec3 color;

void main(void)         
{   
    gl_Position = projection * view * world * vec4(in_position, 1.0);

    color = diffuseColor;

    normal = (world * vec4(normalize(in_normal), 0.0)).xyz;

    tangentToWorld[0] = (world * vec4(in_tangent, 0.0)).xyz;
    tangentToWorld[1] = (world * vec4(in_binormal, 0.0)).xyz;
    tangentToWorld[2] = (world * vec4(in_normal, 0.0)).xyz;

    texcoord = in_texcoord;
}


// FRAGMENT SHADER
#version 330

in vec2 texcoord;
in mat3 tangentToWorld;
in vec3 normal;
in vec3 color;

layout(location = 0) out vec4 out_diffuse;
layout(location = 1) out vec4 out_normal;

void main(void)                                 
{   
    out_diffuse = vec3(1, 0, 1, 1);

    vec3 normal = vec3(0.5, 0.5, 1.0);

    normal = 2.0 * normal - 1.0;

    normal = tangentToWorld * normal;
    normal = (normal + 1.0) / 2;
    normal = normalize(normal);

    out_normal = vec4(normal.x, normal.y, normal.z, 1.0);
}

... And here's the textured shader:

// VERTEX SHADER
#version 330

uniform mat4 projection;
uniform mat4 view;
uniform mat4 world;

layout(location = 0) in vec3 in_position;
layout(location = 1) in vec3 in_normal;
layout(location = 2) in vec2 in_texcoord;
layout(location = 3) in vec3 in_tangent;
layout(location = 4) in vec3 in_binormal;

out mat3 tangentToWorld;
out vec2 texcoord;
out vec3 normal;

void main(void)         
{   
    gl_Position = projection * view * world * vec4(in_position, 1.0);

    normal = (world * vec4(normalize(in_normal), 0.0)).xyz;

    tangentToWorld[0] = (world * vec4(in_tangent, 0.0)).xyz;
    tangentToWorld[1] = (world * vec4(in_binormal, 0.0)).xyz;
    tangentToWorld[2] = (world * vec4(in_normal, 0.0)).xyz;

    texcoord = in_texcoord;
}


// FRAGMENT SHADER
#version 330

in vec2 texcoord;
in mat3 tangentToWorld;
in vec3 normal;

layout(location = 0) out vec3 out_diffuse;
layout(location = 1) out vec4 out_normal;

uniform sampler2D colorMap;            
uniform sampler2D normalMap;

void main(void)                                 
{   
    out_diffuse = texture(colorMap, texcoord).xyz;

    vec3 normal = texture(normalMap, texcoord).xyz;

    normal = 2.0 * normal - 1.0;

    normal = tangentToWorld * normal;
    normal = (normal + 1.0) / 2;
    normal = normalize(normal);

   out_normal = vec4(normal.x, normal.y, normal.z, texture(normalMap, texcoord).a);
}

For the sake of it, if I render everything with the textured shader, I get this:

Textured shader

... And this is what I get when using both shaders:

Both shaders

Any ideas what could be causing this? Shaders do compile without errors, and everything works with the textured shader, it's just the colored shader that doesn't output anything.

manabreak
  • 5,415
  • 7
  • 39
  • 96
  • Some shader code snippet seems to be missing. I see only one shader source there, which one is your "textured" and which one is your "colour" shader? – datenwolf May 26 '13 at 10:31

2 Answers2

1

Without seeing the other shader's code, my best guess is, that you have

  • blending enabled with a glBlendFunc(GL_SRC_ALPHA, …)

and

  • since your color shader uses a vec3 for color output you get implicitly alpha=0, which makes invisible.

But that's just a guess. To test this hypothesis replace in your color fragment shader

// FRAGMENT SHADER
#version 330

layout(location = 0) out vec4 out_diffuse;

void main(void)                                 
{   
    out_diffuse = vec4(1, 0, 1, 1);
}
datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • I have blending disabled, and adding the four-component version doesn't help. I added the full shader sources I'm using for both the colored and textured shaders. – manabreak May 26 '13 at 11:05
  • I tried to implement SSAO in my hobby project but for normals and for positions I got black screen. This anwswer helped me out! I had to disable GL_BLEND before rendering and enable it again. – mudlee Jun 23 '17 at 17:28
1

I solved the problem. In the material selection code, I had a copy-paste error. I set the view and projection matrices to the wrong shader, "texturedShader", whereas I was supposed to set them to the "coloredShader". Copy-paste, not even once, kids!

manabreak
  • 5,415
  • 7
  • 39
  • 96