Fragment shader showing only black color

Hi,
I’m new to OpenGL and I’m facing the problem that the fragment shader is not working and show just a black instead of colored cube.
So far context creation works fine. I’m checking here and there for errors with glGetError() and I don’t get any errors.
Shader compilation and program creation does not return any errors.
glClear() works also fine and sets the color to green as specified by glClearColor().

What I want to display is a colored cube (opengl-tutorial.org). The cube should further rotate around the y-axis, what actually works fine, telling me that the vertex shader is doing well.

I also tried to set a fix color but what shows up is still balck.

Following is the main code to setup the cube data and drawing it:

static const GLfloat g_vertex_buffer_data[] = {
  -0.5f,-0.5f,-0.5f, // triangle 1 : begin
  -0.5f,-0.5f, 0.5f,
  -0.5f, 0.5f, 0.5f, // triangle 1 : end
  0.5f, 0.5f,-0.5f, // triangle 2 : begin
  -0.5f,-0.5f,-0.5f,
  -0.5f, 0.5f,-0.5f, // triangle 2 : end
  0.5f,-0.5f, 0.5f,
  -0.5f,-0.5f,-0.5f,
  0.5f,-0.5f,-0.5f,
  0.5f, 0.5f,-0.5f,
  0.5f,-0.5f,-0.5f,
  -0.5f,-0.5f,-0.5f,
  -0.5f,-0.5f,-0.5f,
  -0.5f, 0.5f, 0.5f,
  -0.5f, 0.5f,-0.5f,
  0.5f,-0.5f, 0.5f,
  -0.5f,-0.5f, 0.5f,
  -0.5f,-0.5f,-0.5f,
  -0.5f, 0.5f, 0.5f,
  -0.5f,-0.5f, 0.5f,
  0.5f,-0.5f, 0.5f,
  0.5f, 0.5f, 0.5f,
  0.5f,-0.5f,-0.5f,
  0.5f, 0.5f,-0.5f,
  0.5f,-0.5f,-0.5f,
  0.5f, 0.5f, 0.5f,
  0.5f,-0.5f, 0.5f,
  0.5f, 0.5f, 0.5f,
  0.5f, 0.5f,-0.5f,
  -0.5f, 0.5f,-0.5f,
  0.5f, 0.5f, 0.5f,
  -0.5f, 0.5f,-0.5f,
  -0.5f, 0.5f, 0.5f,
  0.5f, 0.5f, 0.5f,
  -0.5f, 0.5f, 0.5f,
  0.5f,-0.5f, 0.5f
};

// One color for each vertex. They were generated randomly.
static const GLfloat g_color_buffer_data[] = {
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f,
  0.5f,  0.5f,  0.5f
};

SetupCubeData()
{
  glClearColor(0.0f, 1.0f, 0.0f, 0.0f);

  // Enable depth test
  glEnable(GL_DEPTH_TEST);
  // Accept fragment if it is closer to the camera than the former one
  glDepthFunc(GL_LESS);

  glGenVertexArrays(1, &mVertexArrayId);
  glBindVertexArray(mVertexArrayId);

  // Get a handle for our "MVP" uniform
  mMatrixId = glGetUniformLocation(mOpenGLContext.GetProgramId(), "MVP");

  // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
  mProjection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
  // Camera matrix
  mView = glm::lookAt(
    // glm::vec3(4, 3, -3), // Camera is at (4,3,-3), in World Space
    glm::vec3(2, 2, -2),
    glm::vec3(0, 0, 0), // and looks at the origin
    glm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down)
  );
  // Model matrix : an identity matrix (model will be at the origin)
  mModel = glm::mat4(1.0f);
  // Our ModelViewProjection : multiplication of our 3 matrices
  mMVP = mProjection * mView * mModel; // Remember, matrix multiplication is the other way around

  // vertex buffer
  glGenBuffers(1, &mVertexBufferId);
  glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferId);
  glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

  // color buffer
  glGenBuffers(1, &mColorBufferId);
  glBindBuffer(GL_ARRAY_BUFFER, mColorBufferId);
  glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
}

DrawCube()
{
  CHECK_OPENGL_ERROR();  // glGetError()

  // Clear the screen
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
  // Use our shader
  glUseProgram(mOpenGLContext.GetProgramId());

//  glDisable(GL_CULL_FACE);
//  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

  // Send our transformation to the currently bound shader, 
  // in the "MVP" uniform
  glUniformMatrix4fv(mMatrixId, 1, GL_FALSE, &mMVP[0][0]);

  // 1rst attribute buffer : vertices
  glEnableVertexAttribArray(0);
  glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferId);
  glVertexAttribPointer(
    0,                  // attribute. No particular reason for 0, but must match the layout in the shader.
    3,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    0,                  // stride
    (void*)0            // array buffer offset
  );

  // 2nd attribute buffer : colors
  glEnableVertexAttribArray(1);
  glBindBuffer(GL_ARRAY_BUFFER, mColorBufferId);
  glVertexAttribPointer(
    1,                                // attribute. No particular reason for 1, but must match the layout in the shader.
    3,                                // size
    GL_FLOAT,                         // type
    GL_FALSE,                         // normalized?
    0,                                // stride
    (void*)0                          // array buffer offset
  );

  // Draw the triangles!
  glDrawArrays(GL_TRIANGLES, 0, 12 * 3); // 12*3 indices starting at 0 -> 12 triangles

  glDisableVertexAttribArray(0);
  glDisableVertexAttribArray(1);

  glUseProgram(0);

  SwapBuffers(GetDC()->m_hDC);

  CHECK_OPENGL_ERROR();  // glGetError()
}

void OnTimer()
{
  static GLfloat angle = 0.0f;
  angle += 0.031415f;
  glm::mat4 model = glm::rotate(mModel, angle, glm::vec3(0, 1, 0)); // y is rotation axis -> (0, 1, 0)
  mMVP = mProjection * mView * model;
  
  DrawCube();
}

The vertex and fragment shader loook as follows:

// vertex shader
#version 330

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;

// Output data ; will be interpolated for each fragment.
varying vec3 fragmentColor;

// Values that stay constant for the whole mesh.
uniform mat4 MVP;

void main()
{	
  // Output position of the vertex, in clip space : MVP * position
  gl_Position =  MVP * vec4(vertexPosition_modelspace,1);

  //fragmentColor = vertexColor;
  fragmentColor = vec3(1.0, 0.0, 0.0);
}

// fragment shader
#version 330
// Interpolated values from the vertex shaders
//in vec3 fragmentColor;
varying vec3 fragmentColor;

// Ouput data (defaults to zero index)
//out vec4 color;  // instead of gl_FragColor, but does not work!

void main()
{
  // Output color = color specified in the vertex shader, 
  // interpolated between all 3 surrounding vertices
  // color = fragmentColor;
  gl_FragColor = vec4(fragmentColor, 1.0);
  // color = vec4(1.0, 0.0, 0.0, 1.0);  // ->doesn't work
  // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // ->doesn't work either
}

Any idea?

Any kind of help and hints are really appreciated.

Thanks in advance.

Schulz

[QUOTE=Schulz;1285963]I’m checking here and there for errors with glGetError() and I don’t get any errors.
Shader compilation and program creation does not return any errors.[/QUOTE]

check this out:
https://www.khronos.org/opengl/wiki/Shader_Compilation#Example


//Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked);
if(isLinked == GL_FALSE)
{
	GLint maxLength = 0;
	glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);

	//The maxLength includes the NULL character
	std::vector<GLchar> infoLog(maxLength);
	glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
	
	//We don't need the program anymore.
	glDeleteProgram(program);
	//Don't leak shaders either.
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);

	//Use the infoLog as you see fit.
	
	//In this simple program, we'll just leave
	return;
}

that tells you if your program object is linked correctly
my first guess is to replace “varying” keyword with “in” and “out”

I’m already checking the link status with glGetProgramiv() and there are no errors reported. Changing varying to in/out does not make any difference.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.