Reputation: 6789
I'm trying to apply some lighting to texture. I have created a textured cube and I placed a camera inside of it. Now, I'd like to light its internal faces. I've been told I should use shaders, so I read many tutorials and I've created:
vertex shader:
const GLchar* vertexSkySource =
#if defined(__APPLE_CC__)
"#version 150 core\n"
#else
"#version 130\n"
#endif
"uniform mat3 view_rot;"
"in vec3 position;"
"out vec3 Coord;"
"void main() {"
" Coord = view_rot * position;"
" gl_Position = vec4(position, 1.0);"
"}";
fragment shader
const GLchar* fragmentSkySource =
#if defined(__APPLE_CC__)
"#version 150 core\n"
#else
"#version 130\n"
#endif
"in vec3 Coord;"
"out vec4 outColor;"
"uniform samplerCube textureSampler;"
"void main() {"
" outColor = texture(textureSampler, Coord);"
"}";
After I initialize them
void initialize_shader()
{
// shader per la skybox
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSkySource, NULL);
glCompileShader(vertexShader);
{
GLchar log[512];
GLsizei slen = 0;
glGetShaderInfoLog(vertexShader, 512, &slen, log);
if (slen)
std::cerr << log << std::endl;
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSkySource, NULL);
glCompileShader(fragmentShader);
{
GLchar log[512];
GLsizei slen = 0;
glGetShaderInfoLog(fragmentShader, 512, &slen, log);
if (slen)
std::cerr << log << std::endl;
}
skyProgram = glCreateProgram();
glAttachShader(skyProgram, vertexShader);
glAttachShader(skyProgram, fragmentShader);
glBindFragDataLocation(skyProgram, 0, "outColor");
glLinkProgram(skyProgram);
GLint status = 0;
glGetProgramiv(skyProgram, GL_LINK_STATUS, &status);
if (!status)
{
std::cout << "failed to link" << std::endl;
GLchar log[256];
GLsizei slen = 0;
glGetProgramInfoLog(skyProgram, 256, &slen, log);
std::cout << log << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
Then in my draw method which will be called inside main
method I do this:
glm::vec3 light_direction = glm::normalize(glm::vec3(1.f, 1.f, 3.f));
glm::vec3 light_position = glm::vec3(1.0f, 1.0f, 0.0f);
glm::vec3 light_intensity = glm::vec3(1.f, 1.f, 1.f);
glDepthMask(GL_FALSE);
glUseProgram(skyProgram);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);
glUniform1i(glGetUniformLocation(skyProgram, "textureSampler"), 3);
glUniform3fv(glGetUniformLocation(skyProgram, "light_direction"), 1, &light_direction[0]);
glUniform3fv(glGetUniformLocation(skyProgram, "light_intensity"), 1, &light_intensity[0]);
glUniform3fv(glGetUniformLocation(skyProgram, "view_position"), 1, &camera_position[0]);
glUniform1f(glGetUniformLocation(skyProgram, "shininess"), 60); // shininess = 60, range is [0.0 - 128.0]
glUniformMatrix3fv(glGetUniformLocation(skyProgram, "view_rot"), 1, GL_FALSE, &(glm::mat3(glm::inverse(view)))[0][0]);
I can't see lights on the cube faces, what should I add to my shaders?
Upvotes: 0
Views: 1326
Reputation: 8356
You are sending light parameters (light_direction
, light_intensity
, view_position
and shininess
) into the shader, but you're not receiving them or doing anything with them. Your fragment shader only reads a texture but doesn't apply any lighting to it:
outColor = texture(textureSampler, Coord);
Complete source to shading would be big and without seeing more code is hard to give, so I'll give some pointers:
glGetError()
calls into various parts of your C++ code so you'll know if you use OpenGL API wrong.So, in the end your outColor
needs to be multiplied with the calculated shading:
outColor = texture(textureSampler, Coord) * shading;
but you'll need to modify your vertex and fragment shader to calculate it based on the light's direction and vertex normal.
Edit based on GitHub project:
I compiled and ran the project and had to fix some problems:
Include and Library paths were set for your computer and not relative to the project directory.
In the fragment shader you are declaring "shading" as "out". Remove that line and add vec4 shading = vec4(0.0, 0.0, 0.0, 1.0);
before shading += vec4...
vec4(light_intensity)
is wrong and doesn't compile on my NVIDIA Windows driver, replace with vec4(light_intensity,1.0)
I couldn't get anything on the screen even if I modified the shader to always output red.
Upvotes: 2