PDA

View Full Version : Fragment shader showing only black color



Schulz
02-17-2017, 12:20 AM
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

john_connor
02-17-2017, 09:36 AM
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.

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"

Schulz
02-21-2017, 12:58 AM
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.