While learning OpenGL I encountered a problem with light rendering. It looks like the first thing my program is doing is rendering one box, calculating light and then copying it. As a result, it looks like the light is coming from many directions (I’m using a directional light).
Screen:
[ATTACH=CONFIG]1841[/ATTACH]
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <assert.h>
#include "ShaderLoader.h"
#include "Camera.h"
#include "Callbacks.h"
#define STB_IMAGE_IMPLEMENTATION
#include "ImageLoader.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#define WIND_X 800
#define WIND_Y 600
//Window
GLfloat Wind_width = WIND_X;
GLfloat Wind_height = WIND_Y;
//Camera----------------------
Camera camera( glm::vec3( 1.0f, 1.0f, 5.0f ) );
float lastX = WIND_X / 2;
float lastY = WIND_Y / 2;
bool firstMause = true;
//Timing---------------------------------------------
float deltaTime = 0.0f;
float lastFrame = 0.0f;
int main()
{
//GLFW----------------------------------------------------------------------------------------------
if( glfwInit() )
assert( "Cant init GLFW" );
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
GLFWwindow * window = glfwCreateWindow( WIND_X, WIND_Y, "Level Editor 0.23", nullptr, nullptr );
if( window == nullptr )
{
assert( "cant create a GLFW window" );
glfwTerminate();
return - 1;
}
glfwMakeContextCurrent( window );
glfwSetFramebufferSizeCallback( window, framebuffer_size_callback );
glfwSetCursorPosCallback( window, mouse_callback );
glfwSetScrollCallback( window, scroll_callback );
glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_DISABLED );
//---------------------------------------------------------------------------------------------------
//DEPTH TEXT-----------------------------------------------------------------------------------------
glEnable( GL_DEPTH_TEST );
//---------------------------------------------------------------------------------------------------
//GLEW-----------------------------------------------------------------------------------------------
glewExperimental = GL_TRUE;
if( glewInit() != GLEW_OK )
{
assert( "Cant init GLEW" );
glfwTerminate();
return - 1;
}
glViewport( 0, 0, WIND_X, WIND_Y );
//---------------------------------------------------------------------------------------------------
//Shader loaderd
Shader lightingShader( "Shaders/T3_VertexShader.glsl", "Shaders/T3_FragmentShader.glsl" );
//Cube---------------------------------------------------
GLfloat vertices[] = {
// positions // normals // texture coords
- 0.5f, - 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 0.0f, 0.0f,
0.5f, - 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 0.0f, 1.0f,
- 0.5f, - 0.5f, - 0.5f, 0.0f, 0.0f, - 1.0f, 0.0f, 0.0f,
- 0.5f, - 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, - 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
- 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
- 0.5f, - 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
- 0.5f, 0.5f, 0.5f, - 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
- 0.5f, 0.5f, - 0.5f, - 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
- 0.5f, - 0.5f, - 0.5f, - 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
- 0.5f, - 0.5f, - 0.5f, - 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
- 0.5f, - 0.5f, 0.5f, - 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
- 0.5f, 0.5f, 0.5f, - 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, - 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, - 0.5f, - 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, - 0.5f, - 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, - 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
- 0.5f, - 0.5f, - 0.5f, 0.0f, - 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, - 0.5f, - 0.5f, 0.0f, - 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, - 0.5f, 0.5f, 0.0f, - 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, - 0.5f, 0.5f, 0.0f, - 1.0f, 0.0f, 1.0f, 0.0f,
- 0.5f, - 0.5f, 0.5f, 0.0f, - 1.0f, 0.0f, 0.0f, 0.0f,
- 0.5f, - 0.5f, - 0.5f, 0.0f, - 1.0f, 0.0f, 0.0f, 1.0f,
- 0.5f, 0.5f, - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
- 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
- 0.5f, 0.5f, - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
glm::vec3 cubePositions[] = {
glm::vec3( 0.0f, 0.0f, 0.0f ),
glm::vec3( 2.0f, 5.0f, - 15.0f ),
glm::vec3( - 1.5f, - 2.2f, - 2.5f ),
glm::vec3( - 3.8f, - 2.0f, - 12.3f ),
glm::vec3( 2.4f, - 0.4f, - 3.5f ),
glm::vec3( - 1.7f, 3.0f, - 7.5f ),
glm::vec3( 1.3f, - 2.0f, - 2.5f ),
glm::vec3( 1.5f, 2.0f, - 2.5f ),
glm::vec3( 1.5f, 0.2f, - 1.5f ),
glm::vec3( - 1.3f, 1.0f, - 1.5f )
};
//-------------------------------------------------------
GLuint VBO, cubeVAO;
glGenVertexArrays( 1, & cubeVAO );
glGenBuffers( 1, & VBO );
glBindBuffer( GL_ARRAY_BUFFER, VBO );
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), & vertices, GL_STATIC_DRAW );
glBindVertexArray( cubeVAO );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof( GLfloat ),( GLvoid * ) 0 );
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof( GLfloat ),( GLvoid * )( 3 * sizeof( float ) ) );
glEnableVertexAttribArray( 1 );
glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof( GLfloat ),( GLvoid * )( 6 * sizeof( float ) ) );
glEnableVertexAttribArray( 2 );
glBindVertexArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
//Texture
GLuint diffuseMap = loadTexture( "Textures/container2.png" );
GLuint specularMap = loadTexture( "Textures/container2_specular.png" );
lightingShader.use();
lightingShader.setInt( "material.diffuse", 0 );
lightingShader.setInt( "material.specular", 1 );
while( !glfwWindowShouldClose( window ) )
{
//Delta time-----------------------------
float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
//Events---------------------------------
glfwPollEvents();
processInput( window );
//clear---------------------------------
glClearColor( 0.1f, 0.1f, 0.1f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//Run shader----------------------------
lightingShader.use();
lightingShader.setVec3( "light.direction", glm::vec3( - 0.2f, - 1.0f, - 0.3f ) );
lightingShader.setVec3( "viewPos", camera.Position );
lightingShader.setVec3( "light.ambient", glm::vec3( 0.2f, 0.2f, 0.2f ) );
lightingShader.setVec3( "light.diffuse", glm::vec3( 0.5f, 0.5f, 0.5f ) ); //darken the light a bit to fit the scene
lightingShader.setVec3( "light.specular", glm::vec3( 1.0f, 1.0f, 1.0f ) );
lightingShader.setVec3( "material.specular", glm::vec3( 0.5f, 0.5f, 0.5f ) );
lightingShader.setFloat( "material.shininess", 32.0f );
//Do math------------------------------
glm::mat4 projection = glm::perspective( glm::radians( camera.Zoom ), Wind_width / Wind_height, 0.1f, 100.0f );
glm::mat4 view = camera.GetViewMatrix();
lightingShader.setMat4( "projection", projection );
lightingShader.setMat4( "view", view );
glm::mat4 model( 1.0f );
lightingShader.setMat4( "model", model );
//Texture------------------------------
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, diffuseMap );
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, specularMap );
//Draw---------------------------------
glBindVertexArray( cubeVAO );
for( int i = 0; i < 10; i++ )
{
glm::mat4 model( 1.0f );
model = glm::translate( model, cubePositions[ i ] );
float angle = 20.0f * i;
model = glm::rotate( model, glm::radians( angle ), glm::vec3( 1.0f, 0.3f, 0.5f ) );
lightingShader.setMat4( "model", model );
glDrawArrays( GL_TRIANGLES, 0, 36 );
}
glBindVertexArray( 0 );
//Swap---------------------------------
glfwSwapBuffers( window );
}
glDeleteVertexArrays( 1, & cubeVAO );
glDeleteBuffers( 1, & VBO );
glfwTerminate();
return 0;
}
Vertex Shader:
#version 330 core
layout (location = 0) in vec3 aPosition;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoords;
void main()
{
gl_Position = projection * view * model * vec4(aPosition, 1.0f);
FragPos = vec3(model * vec4(aPosition, 1.0f));
Normal = aNormal;
TexCoords = aTexCoords;
}
Fragment Shader:
#version 330 core
struct Material{
sampler2D diffuse;
sampler2D specular;
sampler2D emmission;
float shininess;
};
uniform Material material;
struct Light{
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform Light light;
uniform vec3 viewPos;
out vec4 FragColor;
in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoords;
void main()
{
//Ambient
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
//diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(-light.direction);
float diff = max(dot(norm, lightDir), 0.0f);
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
//specular
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0f), material.shininess);
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
vec3 result = ambient + diffuse + specular;
FragColor = vec4(result, 1.0f);
}