Adding Light

Hello, I’m new to this forum and I’d like to receive some help, but I’m quite stupid, so try and bear with me here, ok?

I’m trying to use some tutorial to learn OpenGL, it’s on some arcsynthesis site and YES a lot of people told me that it’s got a difficult learning curve, but I got so far in that I don’t want to start over now!

So I’d want to create some scene, for fun and all, and the closest I got to it so far was tutorial 7 from their site. There I mostly play with “World with UBO”

ColorMultiUniform.frag:

#version 330

smooth in vec4 interpColor;
uniform vec4 baseColor;

out vec4 outputColor;

void main()
{
outputColor = interpColor * baseColor;
}

ColorPassthrough.frag:

#version 330

smooth in vec4 interpColor;

out vec4 outputColor;

void main()
{
outputColor = interpColor;
}

ColorUniform.frag:

#version 330

uniform vec4 baseColor;

out vec4 outputColor;

void main()
{
outputColor = baseColor;
}

PosColorWorldTransformUbo.vert:

#version 330

layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;

smooth out vec4 interpColor;

layout(std140) uniform GlobalMatrices
{
mat4 cameraToClipMatrix;
mat4 worldToCameraMatrix;
};

uniform mat4 modelToWorldMatrix;

void main()
{
vec4 temp = modelToWorldMatrix * position;
temp = worldToCameraMatrix * temp;
gl_Position = cameraToClipMatrix * temp;
interpColor = color;
}

PosOnlyWorldTransformUbo.vert:

#version 330

layout(location = 0) in vec4 position;

layout(std140) uniform GlobalMatrices
{
mat4 cameraToClipMatrix;
mat4 worldToCameraMatrix;
};

uniform mat4 modelToWorldMatrix;

void main()
{
vec4 temp = modelToWorldMatrix * position;
temp = worldToCameraMatrix * temp;
gl_Position = cameraToClipMatrix * temp;
}

And finally, World With Ubo.cpp:

//Copyright (C) 2010-2012 by Jason L. McKesson
//This file is licensed under the MIT License.

#include <string>
#include <vector>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <glload/gl_3_3.h>
#include <glutil/glutil.h>
#include <GL/freeglut.h>
#include “…/framework/framework.h”
#include “…/framework/Mesh.h”
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>

#define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))

struct ProgramData
{
GLuint theProgram;
GLuint globalUniformBlockIndex;
GLuint modelToWorldMatrixUnif;
GLuint baseColorUnif;
GLuint thing;
};

float g_fzNear = 1.0f;
float g_fzFar = 1000.0f;

ProgramData UniformColor;
ProgramData ObjectColor;
ProgramData UniformColorTint;

GLuint g_GlobalMatricesUBO;

static const int g_iGlobalMatricesBindingIndex = 0;

ProgramData LoadProgram(const std::string &strVertexShader, const std::string &strFragmentShader)
{
std::vector<GLuint> shaderList;

shaderList.push_back(Framework::LoadShader(GL_VERTEX_SHADER, strVertexShader));
shaderList.push_back(Framework::LoadShader(GL_FRAGMENT_SHADER, strFragmentShader));

ProgramData data;
data.theProgram = Framework::CreateProgram(shaderList);
data.modelToWorldMatrixUnif = glGetUniformLocation(data.theProgram, “modelToWorldMatrix”);
data.globalUniformBlockIndex = glGetUniformBlockIndex(data.theProgram, “GlobalMatrices”);
data.baseColorUnif = glGetUniformLocation(data.theProgram, “baseColor”);

glUniformBlockBinding(data.theProgram, data.globalUniformBlockIndex, g_iGlobalMatricesBindingIndex);

return data;
}

void InitializeProgram()
{
UniformColor = LoadProgram(“PosOnlyWorldTransformUBO.vert”, “ColorUniform.frag”);
ObjectColor = LoadProgram(“PosColorWorldTransformUBO.vert”, “ColorPassthrough.frag”);
UniformColorTint = LoadProgram(“PosColorWorldTransformUBO.vert”, “ColorMultUniform.frag”);

glGenBuffers(1, &g_GlobalMatricesUBO);
glBindBuffer(GL_UNIFORM_BUFFER, g_GlobalMatricesUBO);
glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::mat4) * 2, NULL, GL_STREAM_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);

glBindBufferRange(GL_UNIFORM_BUFFER, g_iGlobalMatricesBindingIndex, g_GlobalMatricesUBO,
0, sizeof(glm::mat4) * 2);
}

glm::mat4 CalcLookAtMatrix(const glm::vec3 &cameraPt, const glm::vec3 &lookPt, const glm::vec3 &upPt)
{
glm::vec3 lookDir = glm::normalize(lookPt - cameraPt);
glm::vec3 upDir = glm::normalize(upPt);

glm::vec3 rightDir = glm::normalize(glm::cross(lookDir, upDir));
glm::vec3 perpUpDir = glm::cross(rightDir, lookDir);

glm::mat4 rotMat(1.0f);
rotMat[0] = glm::vec4(rightDir, 0.0f);
rotMat[1] = glm::vec4(perpUpDir, 0.0f);
rotMat[2] = glm::vec4(-lookDir, 0.0f);

rotMat = glm::transpose(rotMat);

glm::mat4 transMat(1.0f);
transMat[3] = glm::vec4(-cameraPt, 1.0f);

return rotMat * transMat;
}

Framework::Mesh *g_pConeMesh = NULL;
Framework::Mesh *g_pCylinderMesh = NULL;
Framework::Mesh *g_pCubeTintMesh = NULL;
Framework::Mesh *g_pCubeColorMesh = NULL;
Framework::Mesh *g_pPlaneMesh = NULL;

//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
void init()
{
InitializeProgram();

try
{
g_pConeMesh = new Framework::Mesh(“UnitConeTint.xml”);
g_pCylinderMesh = new Framework::Mesh(“UnitCylinderTint.xml”);
g_pCubeTintMesh = new Framework::Mesh(“UnitCubeTint.xml”);
g_pCubeColorMesh = new Framework::Mesh(“UnitCubeColor.xml”);
g_pPlaneMesh = new Framework::Mesh(“UnitPlane.xml”);
}
catch(std::exception &except)
{
printf("%s
", except.what());
throw;
}

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);

glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glDepthRange(0.0f, 1.0f);
glEnable(GL_DEPTH_CLAMP);
}

static float g_fYAngle = 0.0f;
static float g_fXAngle = 0.0f;

//Trees are 3x3 in X/Z, and fTrunkHeight+fConeHeight in the Y.
void DrawTree(glutil::MatrixStack &modelMatrix, float fTrunkHeight = 2.0f, float fConeHeight = 3.0f)
{
//Draw trunk.
{
glutil::PushStack push(modelMatrix);

  modelMatrix.Scale(glm::vec3(1.0f, fTrunkHeight, 1.0f));
  modelMatrix.Translate(glm::vec3(0.0f, 0.5f, 0.0f));

  glUseProgram(UniformColorTint.theProgram);
  glUniformMatrix4fv(UniformColorTint.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  glUniform4f(UniformColorTint.baseColorUnif, 0.694f, 0.4f, 0.106f, 1.0f);
  g_pCylinderMesh-&gt;Render();
  glUseProgram(0);

}

//Draw the treetop
{
glutil::PushStack push(modelMatrix);

  modelMatrix.Translate(glm::vec3(0.0f, fTrunkHeight, 0.0f));
  modelMatrix.Scale(glm::vec3(3.0f, fConeHeight, 3.0f));

  glUseProgram(UniformColorTint.theProgram);
  glUniformMatrix4fv(UniformColorTint.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  glUniform4f(UniformColorTint.baseColorUnif, 0.0f, 1.0f, 0.0f, 1.0f);
  g_pConeMesh-&gt;Render();
  glUseProgram(0);

}
}

const float g_fColumnBaseHeight = 0.25f;

//Columns are 1x1 in the X/Z, and fHieght units in the Y.
void DrawColumn(glutil::MatrixStack &modelMatrix, float fHeight = 5.0f)
{
//Draw the bottom of the column.
{
glutil::PushStack push(modelMatrix);

  modelMatrix.Scale(glm::vec3(1.0f, g_fColumnBaseHeight, 1.0f));
  modelMatrix.Translate(glm::vec3(0.0f, 0.5f, 0.0f));

  glUseProgram(UniformColorTint.theProgram);
  glUniformMatrix4fv(UniformColorTint.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  glUniform4f(UniformColorTint.baseColorUnif, 1.0f, 1.0f, 1.0f, 1.0f);
  g_pCubeTintMesh-&gt;Render();
  glUseProgram(0);

}

//Draw the top of the column.
{
glutil::PushStack push(modelMatrix);

  modelMatrix.Translate(glm::vec3(0.0f, fHeight - g_fColumnBaseHeight, 0.0f));
  modelMatrix.Scale(glm::vec3(1.0f, g_fColumnBaseHeight, 1.0f));
  modelMatrix.Translate(glm::vec3(0.0f, 0.5f, 0.0f));

  glUseProgram(UniformColorTint.theProgram);
  glUniformMatrix4fv(UniformColorTint.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  glUniform4f(UniformColorTint.baseColorUnif, 0.9f, 0.9f, 0.9f, 0.9f);
  g_pCubeTintMesh-&gt;Render();
  glUseProgram(0);

}

//Draw the main column.
{
glutil::PushStack push(modelMatrix);

  modelMatrix.Translate(glm::vec3(0.0f, g_fColumnBaseHeight, 0.0f));
  modelMatrix.Scale(glm::vec3(0.8f, fHeight - (g_fColumnBaseHeight * 2.0f), 0.8f));
  modelMatrix.Translate(glm::vec3(0.0f, 0.5f, 0.0f));

  glUseProgram(UniformColorTint.theProgram);
  glUniformMatrix4fv(UniformColorTint.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  glUniform4f(UniformColorTint.baseColorUnif, 0.9f, 0.9f, 0.9f, 0.9f);
  g_pCylinderMesh-&gt;Render();
  glUseProgram(0);

}
}

const float g_fParthenonWidth = 14.0f;
const float g_fParthenonLength = 20.0f;
const float g_fParthenonColumnHeight = 5.0f;
const float g_fParthenonBaseHeight = 1.0f;
const float g_fParthenonTopHeight = 2.0f;

void DrawParthenon(glutil::MatrixStack &modelMatrix)
{
//Draw base.
{
glutil::PushStack push(modelMatrix);

  modelMatrix.Scale(glm::vec3(g_fParthenonWidth, g_fParthenonBaseHeight, g_fParthenonLength));
  modelMatrix.Translate(glm::vec3(0.0f, 0.5f, 0.0f));

  glUseProgram(UniformColorTint.theProgram);
  glUniformMatrix4fv(UniformColorTint.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  glUniform4f(UniformColorTint.baseColorUnif, 0.9f, 0.9f, 0.9f, 0.9f);
  g_pCubeTintMesh-&gt;Render();
  glUseProgram(0);

}

//Draw top.
{
glutil::PushStack push(modelMatrix);

  modelMatrix.Translate(glm::vec3(0.0f, g_fParthenonColumnHeight + g_fParthenonBaseHeight, 0.0f));
  modelMatrix.Scale(glm::vec3(g_fParthenonWidth, g_fParthenonTopHeight, g_fParthenonLength));
  modelMatrix.Translate(glm::vec3(0.0f, 0.5f, 0.0f));

  glUseProgram(UniformColorTint.theProgram);
  glUniformMatrix4fv(UniformColorTint.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  glUniform4f(UniformColorTint.baseColorUnif, 0.9f, 0.9f, 0.9f, 0.9f);
  g_pCubeTintMesh-&gt;Render();
  glUseProgram(0);

}

//Draw columns.
const float fFrontZVal = (g_fParthenonLength / 2.0f) - 1.0f;
const float fRightXVal = (g_fParthenonWidth / 2.0f) - 1.0f;

for(int iColumnNum = 0; iColumnNum < int(g_fParthenonWidth / 2.0f); iColumnNum++)
{
{
glutil::PushStack push(modelMatrix);
modelMatrix.Translate(glm::vec3((2.0f * iColumnNum) - (g_fParthenonWidth / 2.0f) + 1.0f,
g_fParthenonBaseHeight, fFrontZVal));

  	DrawColumn(modelMatrix, g_fParthenonColumnHeight);
  }
  {
  	glutil::PushStack push(modelMatrix);
  	modelMatrix.Translate(glm::vec3((2.0f * iColumnNum) - (g_fParthenonWidth / 2.0f) + 1.0f,
  		g_fParthenonBaseHeight, -fFrontZVal));

  	DrawColumn(modelMatrix, g_fParthenonColumnHeight);
  }

}

//Don’t draw the first or last columns, since they’ve been drawn already.
for(int iColumnNum = 1; iColumnNum < int((g_fParthenonLength - 2.0f) / 2.0f); iColumnNum++)
{
{
glutil::PushStack push(modelMatrix);
modelMatrix.Translate(glm::vec3(fRightXVal,
g_fParthenonBaseHeight, (2.0f * iColumnNum) - (g_fParthenonLength / 2.0f) + 1.0f));

  	DrawColumn(modelMatrix, g_fParthenonColumnHeight);
  }
  {
  	glutil::PushStack push(modelMatrix);
  	modelMatrix.Translate(glm::vec3(-fRightXVal,
  		g_fParthenonBaseHeight, (2.0f * iColumnNum) - (g_fParthenonLength / 2.0f) + 1.0f));

  	DrawColumn(modelMatrix, g_fParthenonColumnHeight);
  }

}

//Draw interior.
{
glutil::PushStack push(modelMatrix);

  modelMatrix.Translate(glm::vec3(0.0f, 1.0f, 0.0f));
  modelMatrix.Scale(glm::vec3(g_fParthenonWidth - 6.0f, g_fParthenonColumnHeight,
  	g_fParthenonLength - 6.0f));
  modelMatrix.Translate(glm::vec3(0.0f, 0.5f, 0.0f));

  glUseProgram(ObjectColor.theProgram);
  glUniformMatrix4fv(ObjectColor.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  g_pCubeColorMesh-&gt;Render();
  glUseProgram(0);

}

//Draw headpiece.
{
glutil::PushStack push(modelMatrix);

  modelMatrix.Translate(glm::vec3(
  	0.0f,
  	g_fParthenonColumnHeight + g_fParthenonBaseHeight + (g_fParthenonTopHeight / 2.0f),
  	g_fParthenonLength / 2.0f));
  modelMatrix.RotateX(-135.0f);
  modelMatrix.RotateY(45.0f);

  glUseProgram(ObjectColor.theProgram);
  glUniformMatrix4fv(ObjectColor.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  g_pCubeColorMesh-&gt;Render();
  glUseProgram(0);

}
}

struct TreeData
{
float fXPos;
float fZPos;
float fTrunkHeight;
float fConeHeight;
};

static const TreeData g_forest =
{
{25.0f, 5.0f, 2.0f, 3.0f},
{25.0f, 10.0f, 2.0f, 3.0f},
{25.0f, 15.0f, 2.0f, 3.0f},
{25.0f, 20.0f, 2.0f, 3.0f},
{25.0f, 25.0f, 2.0f, 3.0f},
{25.0f, 30.0f, 2.0f, 3.0f},
{25.0f, 35.0f, 2.0f, 3.0f},
{25.0f, 40.0f, 2.0f, 3.0f},
{25.0f, 45.0f, 2.0f, 3.0f},
};

void DrawForest(glutil::MatrixStack &modelMatrix)
{
for(int iTree = 0; iTree < ARRAY_COUNT(g_forest); iTree++)
{
const TreeData &currTree = g_forest[iTree];

  glutil::PushStack push(modelMatrix);
  modelMatrix.Translate(glm::vec3(currTree.fXPos, 0.0f, currTree.fZPos));
  DrawTree(modelMatrix, currTree.fTrunkHeight, currTree.fConeHeight);

}
}

static bool g_bDrawLookatPoint = false;
static glm::vec3 g_camTarget(0.0f, 0.4f, 0.0f);

//In spherical coordinates.
static glm::vec3 g_sphereCamRelPos(67.5f, -46.0f, 150.0f);

glm::vec3 ResolveCamPosition()
{
glutil::MatrixStack tempMat;

float phi = Framework::DegToRad(g_sphereCamRelPos.x);
float theta = Framework::DegToRad(g_sphereCamRelPos.y + 90.0f);

float fSinTheta = sinf(theta);
float fCosTheta = cosf(theta);
float fCosPhi = cosf(phi);
float fSinPhi = sinf(phi);

glm::vec3 dirToCamera(fSinTheta * fCosPhi, fCosTheta, fSinTheta * fSinPhi);
return (dirToCamera * g_sphereCamRelPos.z) + g_camTarget;
}

//Called to update the display.
//You should call glutSwapBuffers after all of your rendering to display what you rendered.
//If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

if(g_pConeMesh && g_pCylinderMesh && g_pCubeTintMesh && g_pCubeColorMesh && g_pPlaneMesh)
{
const glm::vec3 &camPos = ResolveCamPosition();

  glutil::MatrixStack camMatrix;
  camMatrix.SetMatrix(CalcLookAtMatrix(camPos, g_camTarget, glm::vec3(0.0f, 1.0f, 0.0f)));

  glBindBuffer(GL_UNIFORM_BUFFER, g_GlobalMatricesUBO);
  glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(camMatrix.Top()));
  glBindBuffer(GL_UNIFORM_BUFFER, 0);

  glutil::MatrixStack modelMatrix;

  //Render the ground plane.
  {
  	glutil::PushStack push(modelMatrix);

  	modelMatrix.Scale(glm::vec3(100.0f, 1.0f, 100.0f));

  	glUseProgram(UniformColor.theProgram);
  	glUniformMatrix4fv(UniformColor.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  	glUniform4f(UniformColor.baseColorUnif, 0.302f, 0.416f, 0.0589f, 1.0f);
  	g_pPlaneMesh-&gt;Render();
  	glUseProgram(0);
  }

  //Draw the trees
  DrawForest(modelMatrix);

  //Draw the building.
  {
  	glutil::PushStack push(modelMatrix);
  	modelMatrix.Translate(glm::vec3(20.0f, 0.0f, -10.0f));

  	DrawParthenon(modelMatrix);
  }

  if(g_bDrawLookatPoint)
  {
  	glDisable(GL_DEPTH_TEST);

  	glutil::PushStack push(modelMatrix);

  	modelMatrix.Translate(g_camTarget);
  	modelMatrix.Scale(1.0f, 1.0f, 1.0f);

  	glUseProgram(ObjectColor.theProgram);
  	glUniformMatrix4fv(ObjectColor.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  	g_pCubeColorMesh-&gt;Render();
  	glUseProgram(0);
  	glEnable(GL_DEPTH_TEST);
  }

}

glutSwapBuffers();
}

//Called whenever the window is resized. The new window size is given, in pixels.
//This is an opportunity to call glViewport or glScissor to keep up with the change in size.
void reshape (int w, int h)
{
glutil::MatrixStack persMatrix;
persMatrix.Perspective(45.0f, (w / (float)h), g_fzNear, g_fzFar);

glBindBuffer(GL_UNIFORM_BUFFER, g_GlobalMatricesUBO);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(persMatrix.Top()));
glBindBuffer(GL_UNIFORM_BUFFER, 0);

glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glutPostRedisplay();
}

//Called whenever a key on the keyboard was pressed.
//The key is given by the ‘‘key’’ parameter, which is in ASCII.
//It’s often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to
//exit the program.
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
delete g_pConeMesh;
g_pConeMesh = NULL;
delete g_pCylinderMesh;
g_pCylinderMesh = NULL;
delete g_pCubeTintMesh;
g_pCubeTintMesh = NULL;
delete g_pCubeColorMesh;
g_pCubeColorMesh = NULL;
delete g_pPlaneMesh;
g_pPlaneMesh = NULL;
glutLeaveMainLoop();
return;
case ‘w’: g_camTarget.z -= 4.0f; break;
case ‘s’: g_camTarget.z += 4.0f; break;
case ‘d’: g_camTarget.x += 4.0f; break;
case ‘a’: g_camTarget.x -= 4.0f; break;
case ‘e’: g_camTarget.y -= 4.0f; break;
case ‘q’: g_camTarget.y += 4.0f; break;
case ‘W’: g_camTarget.z -= 0.4f; break;
case ‘S’: g_camTarget.z += 0.4f; break;
case ‘D’: g_camTarget.x += 0.4f; break;
case ‘A’: g_camTarget.x -= 0.4f; break;
case ‘E’: g_camTarget.y -= 0.4f; break;
case ‘Q’: g_camTarget.y += 0.4f; break;
case ‘i’: g_sphereCamRelPos.y -= 11.25f; break;
case ‘k’: g_sphereCamRelPos.y += 11.25f; break;
case ‘j’: g_sphereCamRelPos.x -= 11.25f; break;
case ‘l’: g_sphereCamRelPos.x += 11.25f; break;
case ‘o’: g_sphereCamRelPos.z -= 5.0f; break;
case ‘u’: g_sphereCamRelPos.z += 5.0f; break;
case ‘I’: g_sphereCamRelPos.y -= 1.125f; break;
case ‘K’: g_sphereCamRelPos.y += 1.125f; break;
case ‘J’: g_sphereCamRelPos.x -= 1.125f; break;
case ‘L’: g_sphereCamRelPos.x += 1.125f; break;
case ‘O’: g_sphereCamRelPos.z -= 0.5f; break;
case ‘U’: g_sphereCamRelPos.z += 0.5f; break;

case 32:
g_bDrawLookatPoint = !g_bDrawLookatPoint;
printf("Target: %f, %f, %f
", g_camTarget.x, g_camTarget.y, g_camTarget.z);
printf("Position: %f, %f, %f
", g_sphereCamRelPos.x, g_sphereCamRelPos.y, g_sphereCamRelPos.z);
break;
}

g_sphereCamRelPos.y = glm::clamp(g_sphereCamRelPos.y, -78.75f, -1.0f);
g_camTarget.y = g_camTarget.y > 0.0f ? g_camTarget.y : 0.0f;
g_sphereCamRelPos.z = g_sphereCamRelPos.z > 5.0f ? g_sphereCamRelPos.z : 5.0f;

glutPostRedisplay();
}

unsigned int defaults(unsigned int displayMode, int &width, int &height) {return displayMode;}

It’s so much text, but it’s just plain colors… Tutorial 9 on that site explains how to do lightning effects, but … that one goes like this:

ColorPassthrough.frag: <same as before>

DirVertexLighting_PN.vert:

#version 330

layout(location = 0) in vec3 position;
layout(location = 2) in vec3 normal;

smooth out vec4 interpColor;

uniform vec3 dirToLight;
uniform vec4 lightIntensity;

uniform mat4 modelToCameraMatrix;
uniform mat3 normalModelToCameraMatrix;

layout(std140) uniform Projection
{
mat4 cameraToClipMatrix;
};

void main()
{
gl_Position = cameraToClipMatrix * (modelToCameraMatrix * vec4(position, 1.0));

vec3 normCamSpace = normalize(normalModelToCameraMatrix * normal);

float cosAngIncidence = dot(normCamSpace, dirToLight);
cosAngIncidence = clamp(cosAngIncidence, 0, 1);

interpColor = lightIntensity * cosAngIncidence;
}

DirVertexLighting_PCN.vert:

#version 330

layout(location = 0) in vec3 position;
layout(location = 1) in vec4 diffuseColor;
layout(location = 2) in vec3 normal;

smooth out vec4 interpColor;

uniform vec3 dirToLight;
uniform vec4 lightIntensity;

uniform mat4 modelToCameraMatrix;
uniform mat3 normalModelToCameraMatrix;

layout(std140) uniform Projection
{
mat4 cameraToClipMatrix;
};

void main()
{
gl_Position = cameraToClipMatrix * (modelToCameraMatrix * vec4(position, 1.0));

vec3 normCamSpace = normalize(normalModelToCameraMatrix * normal);

float cosAngIncidence = dot(normCamSpace, dirToLight);
cosAngIncidence = clamp(cosAngIncidence, 0, 1);

interpColor = lightIntensity * diffuseColor * cosAngIncidence;
}

Basic Lightning.cpp:

//Copyright (C) 2010-2012 by Jason L. McKesson
//This file is licensed under the MIT License.

#include <string>
#include <vector>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <glload/gl_3_3.h>
#include <glutil/glutil.h>
#include <GL/freeglut.h>
#include “…/framework/framework.h”
#include “…/framework/Mesh.h”
#include “…/framework/MousePole.h”
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>

#define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*))))

struct ProgramData
{
GLuint theProgram;

GLuint dirToLightUnif;
GLuint lightIntensityUnif;

GLuint modelToCameraMatrixUnif;
GLuint normalModelToCameraMatrixUnif;
};

float g_fzNear = 1.0f;
float g_fzFar = 1000.0f;

ProgramData g_WhiteDiffuseColor;
ProgramData g_VertexDiffuseColor;

const int g_projectionBlockIndex = 2;

ProgramData LoadProgram(const std::string &strVertexShader, const std::string &strFragmentShader)
{
std::vector<GLuint> shaderList;

shaderList.push_back(Framework::LoadShader(GL_VERTEX_SHADER, strVertexShader));
shaderList.push_back(Framework::LoadShader(GL_FRAGMENT_SHADER, strFragmentShader));

ProgramData data;
data.theProgram = Framework::CreateProgram(shaderList);
data.modelToCameraMatrixUnif = glGetUniformLocation(data.theProgram, “modelToCameraMatrix”);
data.normalModelToCameraMatrixUnif = glGetUniformLocation(data.theProgram, “normalModelToCameraMatrix”);
data.dirToLightUnif = glGetUniformLocation(data.theProgram, “dirToLight”);
data.lightIntensityUnif = glGetUniformLocation(data.theProgram, “lightIntensity”);

GLuint projectionBlock = glGetUniformBlockIndex(data.theProgram, “Projection”);
glUniformBlockBinding(data.theProgram, projectionBlock, g_projectionBlockIndex);

return data;
}

void InitializeProgram()
{
g_WhiteDiffuseColor = LoadProgram(“DirVertexLighting_PN.vert”, “ColorPassthrough.frag”);
g_VertexDiffuseColor = LoadProgram(“DirVertexLighting_PCN.vert”, “ColorPassthrough.frag”);
}

Framework::Mesh *g_pCylinderMesh = NULL;
Framework::Mesh *g_pPlaneMesh = NULL;

///////////////////////////////////////////////
// View/Object Setup
glutil::ViewData g_initialViewData =
{
glm::vec3(0.0f, 0.5f, 0.0f),
glm::fquat(0.92387953f, 0.3826834f, 0.0f, 0.0f),
5.0f,
0.0f
};

glutil::ViewScale g_viewScale =
{
3.0f, 20.0f,
1.5f, 0.5f,
0.0f, 0.0f, //No camera movement.
90.0f/250.0f
};

glutil::ObjectData g_initialObjectData =
{
glm::vec3(0.0f, 0.5f, 0.0f),
glm::fquat(1.0f, 0.0f, 0.0f, 0.0f),
};

glutil::ViewPole g_viewPole = glutil::ViewPole(g_initialViewData,
g_viewScale, glutil::MB_LEFT_BTN);
glutil::ObjectPole g_objtPole = glutil::ObjectPole(g_initialObjectData,
90.0f/250.0f, glutil::MB_RIGHT_BTN, &g_viewPole);

namespace
{
void MouseMotion(int x, int y)
{
Framework::ForwardMouseMotion(g_viewPole, x, y);
Framework::ForwardMouseMotion(g_objtPole, x, y);
glutPostRedisplay();
}

void MouseButton(int button, int state, int x, int y)
{
Framework::ForwardMouseButton(g_viewPole, button, state, x, y);
Framework::ForwardMouseButton(g_objtPole, button, state, x, y);
glutPostRedisplay();
}

void MouseWheel(int wheel, int direction, int x, int y)
{
Framework::ForwardMouseWheel(g_viewPole, wheel, direction, x, y);
Framework::ForwardMouseWheel(g_objtPole, wheel, direction, x, y);
glutPostRedisplay();
}
}

GLuint g_projectionUniformBuffer = 0;

struct ProjectionBlock
{
glm::mat4 cameraToClipMatrix;
};

//Called after the window and OpenGL are initialized. Called exactly once, before the main loop.
void init()
{
InitializeProgram();

try
{
g_pCylinderMesh = new Framework::Mesh(“UnitCylinder.xml”);
g_pPlaneMesh = new Framework::Mesh(“LargePlane.xml”);
}
catch(std::exception &except)
{
printf("%s
", except.what());
throw;
}

glutMouseFunc(MouseButton);
glutMotionFunc(MouseMotion);
glutMouseWheelFunc(MouseWheel);

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);

glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glDepthRange(0.0f, 1.0f);
glEnable(GL_DEPTH_CLAMP);

glGenBuffers(1, &g_projectionUniformBuffer);
glBindBuffer(GL_UNIFORM_BUFFER, g_projectionUniformBuffer);
glBufferData(GL_UNIFORM_BUFFER, sizeof(ProjectionBlock), NULL, GL_DYNAMIC_DRAW);

//Bind the static buffers.
glBindBufferRange(GL_UNIFORM_BUFFER, g_projectionBlockIndex, g_projectionUniformBuffer,
0, sizeof(ProjectionBlock));

glBindBuffer(GL_UNIFORM_BUFFER, 0);
}

glm::vec4 g_lightDirection(0.866f, 0.5f, 0.0f, 0.0f);

static bool g_bDrawColoredCyl = true;

//Called to update the display.
//You should call glutSwapBuffers after all of your rendering to display what you rendered.
//If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function.
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

if(g_pPlaneMesh && g_pCylinderMesh)
{
glutil::MatrixStack modelMatrix;
modelMatrix.SetMatrix(g_viewPole.CalcMatrix());

  glm::vec4 lightDirCameraSpace = modelMatrix.Top() * g_lightDirection;

  glUseProgram(g_WhiteDiffuseColor.theProgram);
  glUniform3fv(g_WhiteDiffuseColor.dirToLightUnif, 1, glm::value_ptr(lightDirCameraSpace));
  glUseProgram(g_VertexDiffuseColor.theProgram);
  glUniform3fv(g_VertexDiffuseColor.dirToLightUnif, 1, glm::value_ptr(lightDirCameraSpace));
  glUseProgram(0);

  {
  	glutil::PushStack push(modelMatrix);

  	//Render the ground plane.
  	{
  		glutil::PushStack push(modelMatrix);

  		glUseProgram(g_WhiteDiffuseColor.theProgram);
  		glUniformMatrix4fv(g_WhiteDiffuseColor.modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  		glm::mat3 normMatrix(modelMatrix.Top());
  		glUniformMatrix3fv(g_WhiteDiffuseColor.normalModelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(normMatrix));
  		glUniform4f(g_WhiteDiffuseColor.lightIntensityUnif, 1.0f, 1.0f, 1.0f, 1.0f);
  		g_pPlaneMesh-&gt;Render();
  		glUseProgram(0);
  	}

  	//Render the Cylinder
  	{
  		glutil::PushStack push(modelMatrix);

  		modelMatrix.ApplyMatrix(g_objtPole.CalcMatrix());

  		if(g_bDrawColoredCyl)
  		{
  			glUseProgram(g_VertexDiffuseColor.theProgram);
  			glUniformMatrix4fv(g_VertexDiffuseColor.modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  			glm::mat3 normMatrix(modelMatrix.Top());
  			glUniformMatrix3fv(g_VertexDiffuseColor.normalModelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(normMatrix));
  			glUniform4f(g_VertexDiffuseColor.lightIntensityUnif, 1.0f, 1.0f, 1.0f, 1.0f);
  			g_pCylinderMesh-&gt;Render("lit-color");
  		}
  		else
  		{
  			glUseProgram(g_WhiteDiffuseColor.theProgram);
  			glUniformMatrix4fv(g_WhiteDiffuseColor.modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  			glm::mat3 normMatrix(modelMatrix.Top());
  			glUniformMatrix3fv(g_WhiteDiffuseColor.normalModelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(normMatrix));
  			glUniform4f(g_WhiteDiffuseColor.lightIntensityUnif, 1.0f, 1.0f, 1.0f, 1.0f);
  			g_pCylinderMesh-&gt;Render("lit");
  		}
  		glUseProgram(0);
  	}
  }

}

glutSwapBuffers();
}

//Called whenever the window is resized. The new window size is given, in pixels.
//This is an opportunity to call glViewport or glScissor to keep up with the change in size.
void reshape (int w, int h)
{
glutil::MatrixStack persMatrix;
persMatrix.Perspective(45.0f, (w / (float)h), g_fzNear, g_fzFar);

ProjectionBlock projData;
projData.cameraToClipMatrix = persMatrix.Top();

glBindBuffer(GL_UNIFORM_BUFFER, g_projectionUniformBuffer);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(ProjectionBlock), &projData);
glBindBuffer(GL_UNIFORM_BUFFER, 0);

glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glutPostRedisplay();
}

//Called whenever a key on the keyboard was pressed.
//The key is given by the ‘‘key’’ parameter, which is in ASCII.
//It’s often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to
//exit the program.
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
delete g_pPlaneMesh;
delete g_pCylinderMesh;
glutLeaveMainLoop();
return;

case 32:
g_bDrawColoredCyl = !g_bDrawColoredCyl;
break;
}

glutPostRedisplay();
}

unsigned int defaults(unsigned int displayMode, int &width, int &height) {return displayMode;}

True, this isn’t for a whole scenery, it’s just for one object that is always the center of the camera, but I figured that if the tutorial touches upon this, then it should be a type of knowledge that can be combined with things learned before… it’s really not.
I tried adding adding GLuint dirToLightUnif and GLuint lightIntensityUnif to the ProgramData of the Tut7 and then work around that… didn’t work. Then I fiddled with the vertex shaders… still nothing… then I did so much different stuff… seriously the best result I ever got was creating ProgramData (from the tutorial about the scene) and ProgramData_2 (from the tutorial about lightning). With this I made this sort of thing:

(…)
//Render the ground plane.
{
glutil::PushStack push(modelMatrix);

  	modelMatrix.Scale(glm::vec3(100.0f, 1.0f, 100.0f));

  	glUseProgram(UniformColor.theProgram);
  	glUniformMatrix4fv(UniformColor.modelToWorldMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  	glUniform4f(UniformColor.baseColorUnif, 0.302f, 0.416f, 0.0589f, 1.0f);
  	
  	if(g_bDoInvTranspose)
  		{
  	glUseProgram(g_WhiteDiffuseColor.theProgram);
  	glUniformMatrix4fv(g_WhiteDiffuseColor.modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
  	glm::mat3 normMatrix(modelMatrix.Top());
  	glUniformMatrix3fv(g_WhiteDiffuseColor.normalModelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(normMatrix));
  	glUniform4f(g_WhiteDiffuseColor.lightIntensityUnif, 1.0f, 1.0f, 1.0f, 1.0f);
  	}

g_pPlaneMesh->Render();
glUseProgram(0);
}
(…)

The “g_bDoInvTranspose” thing is a bool variable which switches values when the ‘t’ key is pressed. Surprisingly when it’s off, things render nicely as before, but if it’s on, the specific object is invisible! Even when I removed everything but the ‘glUseProgram(g_WhiteDiffuseColor.theProgram);’ line, it still was invisible.

I have spend more than 2 weeks on this already, no jokes at all, I’m frustrated with this, so here, I ask kindly, could anyone at all help me with this? How should I apply simple lightning to this big scene?

Are you serious? The whole program? O_O Please, reduce the code to the sections that you think matter for your problem.

it’s on some arcsynthesis site and YES a lot of people told me that it’s got a difficult learning curve

Fellow board member Alfonse is the author - if you have specific questions about the tutorial, just ask - and the curve is actually not that steep, it’s just not as simple as the glBegin()/glEnd() crap so many of us were accustomed to.

I am not sure what you have been reading but this is the first section on lighting
http://www.arcsynthesis.org/gltut/Illumination/Tutorial%2009.html
but please don’t skip the section prior to it; they are important

[QUOTE=tonyo_au;1251661]I am not sure what you have been reading but this is the first section on lighting
http://www.arcsynthesis.org/gltut/Illumination/Tutorial%2009.html
but please don’t skip the section prior to it; they are important[/QUOTE]

This.

Every chapter builds on the chapters before it. They aren’t independent. If you start a novel or movie in the middle, you’re going to find the “learning curve” to be steep. Just like this.

The key thing to do is not come into it with any expectations. Try not to be constantly thinking, “when does it get to the part I want to know.” In fact, try not thinking about wanting to know anything at all. Instead, focus on what the material is teaching you, in the order it tries to teach it to you.

Ok I admit, I see the error of my ways and reading up on the theory does clear up a lot of stuff that I was confused about and didn’t know why they were changed from tutorial 7… HOWEVER, I can admit that there still is a certain element that I am absolutely not clear on:

If I wished to make the cylinder in tutorial 9 green or blue… how should I do that? I don’t see any definition/declaration in the program that would clearly give it a red color. I’m completely clueless where that came from.

I don’t see any definition/declaration in the program that would clearly give it a red color.

You also don’t see any “definition/declaration in the program” that makes a cylinder.

The vertex shader for the cylinder has these definitions for its inputs:

layout(location = 0) in vec3 position;
layout(location = 1) in vec4 diffuseColor;
layout(location = 2) in vec3 normal;

Vertex shader inputs store the per-vertex attributes passed from buffer objects. AKA: the mesh. The diffuseColor, just like the positions and the normals, comes from the mesh, which is loaded from a file. Since both Tutorials 8 and 7 rely on mesh files, I didn’t think it warranted mentioning where the mesh came from. And per-vertex colors have been around since #2.

If you want to change its color, you will have to either modify the diffuseColor or override/ignore it in the computations.

Well this took me a long time to get to, sorry, college and everything, but I passed all exams, so I can return to OpenGL and yes, I finally understand.
layout(location = x)
This means that in the .xml fine that defines this object, there will be an index of x referring to this. This explains things.

Naturally there won’t be a basecolor for me, it’s not defined in the .xml, that’s fine, I setup the colors in .cpp, but I don’t have a normal in it the xml!

I tried and checked the .xml file of the cylinder and the numbers for normal there… I can’t comprehend what they even mean or where they came from. I’m so confused.

I’ve been thinking and thinking and for once I “MIGHT” have a more concrete problem, as in, I MIGHT know how to approach it. I know, hard to believe, but hear me out.

this is the part in my .cpp responsible for the lightning

//Light

  glUseProgram(UniformColor.theProgram);
  glUniformMatrix4fv(UniformColor.worldToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(camMatrix.Top()));
  glUseProgram(ObjectColor.theProgram);
  glUniformMatrix4fv(ObjectColor.worldToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(camMatrix.Top()));
  glUseProgram(UniformColorTint.theProgram);
  glUniformMatrix4fv(UniformColorTint.worldToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(camMatrix.Top()));

//Part A
glUniform4f(UniformColorTint.lightIntensityUnif, 0.9f, 0.9f, 0.9f, 1.0f);
glUniform4f(UniformColorTint.ambientIntensityUnif, 0.5f, 0.5f, 0.5f, 1.0f);
glUniform3f(UniformColorTint.dirToLightUnif, 0.866f, 0.7f,3.0f);

//Part B
glUniform4f(UniformColorTint.lightIntensityUnif2, 0.9f, 0.9f, 0.9f, 1.0f);
glUniform4f(UniformColorTint.ambientIntensityUnif2, 0.3f, 0.3f, 0.3f, 1.0f);

  glUseProgram(0);

  // End lightning

I’ve divided this into PartA and PartB to demonstrate something:
http://neuropod.net/imagehost/uploads/a44646e9fb8556666544d407d56eccd6.jpg

Top Left: This is the scene when both parts are active
Top Right: This is the scene when only PartB is active
Bottom Left: This is the scene when only PartA is active
Bottom Right: This is the scene when both parts are inactive

I experiment because I try to get directional lightning, but no matter what it doesn’t work, I’m troubled…

Oh and emmm here is my vertex shader:

#version 330

layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;
layout(location = 2) in vec3 normal;

smooth out vec4 interpColor;

out vec3 vertexNormal;
out vec3 modelSpacePosition;

uniform mat4 worldToCameraMatrix;
uniform mat4 modelToWorldMatrix;
uniform mat3 normalModelToCameraMatrix;
uniform vec3 dirToLight;
uniform vec4 lightIntensity;
uniform vec4 ambientIntensity;
uniform vec4 baseColor;

uniform mat4 cameraToClipMatrix;

void main()
{

vertexNormal = normal;
vec3 normCamSpace = normalize(normalModelToCameraMatrix * vertexNormal);

vec3 dirToLight = normalize(dirToLight);

float cosAngIncidence = dot(normCamSpace, dirToLight);
cosAngIncidence = clamp(cosAngIncidence, 0, 1);

modelSpacePosition.x = position.x;
modelSpacePosition.y = position.y;
modelSpacePosition.z = position.z;

vec4 temp = modelToWorldMatrix * position;
temp = worldToCameraMatrix * temp;
gl_Position = cameraToClipMatrix * temp;

interpColor = ((lightIntensity * cosAngIncidence) + (ambientIntensity)) * baseColor;
}

I mostly just want to add a simple directional light as in tutorial 9
http://arcsynthesis.org/gltut/Illumination/Tutorial%2009.html
But it doesn’t work, I somehow miraculously made a Plane-Light, where there’s a pseudo lightbulb and that works, but I can’t get any imitation of a sunlight into this… also … worthy of note, the lightbulb only works should both those parts be active. Just saying

The vector “dirToLight” is being redefined in your shader after already having been passed in as a Uniform variable. This seems like trouble to me.

Wow that did fix it! And I suppose the fact that only walls get shaded now, is because they’re the only ones with normals for now. I’ll get to that, thanks, I’ll come back if more problems occur!