Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: Adding Light

  1. #1
    Junior Member Newbie
    Join Date
    Jun 2013
    Posts
    6

    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_VERT EX_SHADER, strVertexShader));
    shaderList.push_back(Framework::LoadShader(GL_FRAG MENT_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\n", 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.modelToWorldMa trixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glUniform4f(UniformColorTint.baseColorUnif, 0.694f, 0.4f, 0.106f, 1.0f);
    g_pCylinderMesh->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.modelToWorldMa trixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glUniform4f(UniformColorTint.baseColorUnif, 0.0f, 1.0f, 0.0f, 1.0f);
    g_pConeMesh->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.modelToWorldMa trixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glUniform4f(UniformColorTint.baseColorUnif, 1.0f, 1.0f, 1.0f, 1.0f);
    g_pCubeTintMesh->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.modelToWorldMa trixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glUniform4f(UniformColorTint.baseColorUnif, 0.9f, 0.9f, 0.9f, 0.9f);
    g_pCubeTintMesh->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.modelToWorldMa trixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glUniform4f(UniformColorTint.baseColorUnif, 0.9f, 0.9f, 0.9f, 0.9f);
    g_pCylinderMesh->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.modelToWorldMa trixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glUniform4f(UniformColorTint.baseColorUnif, 0.9f, 0.9f, 0.9f, 0.9f);
    g_pCubeTintMesh->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.modelToWorldMa trixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glUniform4f(UniformColorTint.baseColorUnif, 0.9f, 0.9f, 0.9f, 0.9f);
    g_pCubeTintMesh->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.modelToWorldMatrixU nif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    g_pCubeColorMesh->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.modelToWorldMatrixU nif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    g_pCubeColorMesh->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:egToRad(g_sphereCamRelPos.x);
    float theta = Framework:egToRad(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.modelToWorldMatrix Unif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glUniform4f(UniformColor.baseColorUnif, 0.302f, 0.416f, 0.0589f, 1.0f);
    g_pPlaneMesh->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.modelToWorldMatrixU nif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    g_pCubeColorMesh->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\n", g_camTarget.x, g_camTarget.y, g_camTarget.z);
    printf("Position: %f, %f, %f\n", 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_VERT EX_SHADER, strVertexShader));
    shaderList.push_back(Framework::LoadShader(GL_FRAG MENT_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\n", 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.modelToCame raMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glm::mat3 normMatrix(modelMatrix.Top());
    glUniformMatrix3fv(g_WhiteDiffuseColor.normalModel ToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(normMatrix));
    glUniform4f(g_WhiteDiffuseColor.lightIntensityUnif , 1.0f, 1.0f, 1.0f, 1.0f);
    g_pPlaneMesh->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.modelToCam eraMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glm::mat3 normMatrix(modelMatrix.Top());
    glUniformMatrix3fv(g_VertexDiffuseColor.normalMode lToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(normMatrix));
    glUniform4f(g_VertexDiffuseColor.lightIntensityUni f, 1.0f, 1.0f, 1.0f, 1.0f);
    g_pCylinderMesh->Render("lit-color");
    }
    else
    {
    glUseProgram(g_WhiteDiffuseColor.theProgram);
    glUniformMatrix4fv(g_WhiteDiffuseColor.modelToCame raMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glm::mat3 normMatrix(modelMatrix.Top());
    glUniformMatrix3fv(g_WhiteDiffuseColor.normalModel ToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(normMatrix));
    glUniform4f(g_WhiteDiffuseColor.lightIntensityUnif , 1.0f, 1.0f, 1.0f, 1.0f);
    g_pCylinderMesh->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.modelToWorldMatrix Unif, 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.modelToCame raMatrixUnif, 1, GL_FALSE, glm::value_ptr(modelMatrix.Top()));
    glm::mat3 normMatrix(modelMatrix.Top());
    glUniformMatrix3fv(g_WhiteDiffuseColor.normalModel ToCameraMatrixUnif, 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?

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Apr 2010
    Location
    Germany
    Posts
    1,099
    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.

  3. #3
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,097
    I am not sure what you have been reading but this is the first section on lighting
    http://www.arcsynthesis.org/gltut/Il...rial%2009.html
    but please don't skip the section prior to it; they are important

  4. #4
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    Quote Originally Posted by tonyo_au View Post
    I am not sure what you have been reading but this is the first section on lighting
    http://www.arcsynthesis.org/gltut/Il...rial%2009.html
    but please don't skip the section prior to it; they are important
    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.

  5. #5
    Junior Member Newbie
    Join Date
    Jun 2013
    Posts
    6
    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.

  6. #6
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    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:

    Code :
    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.

  7. #7
    Junior Member Newbie
    Join Date
    Jun 2013
    Posts
    6
    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.

  8. #8
    Junior Member Newbie
    Join Date
    Jun 2013
    Posts
    6
    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.worldToCameraMatri xUnif, 1, GL_FALSE, glm::value_ptr(camMatrix.Top()));
    glUseProgram(ObjectColor.theProgram);
    glUniformMatrix4fv(ObjectColor.worldToCameraMatrix Unif, 1, GL_FALSE, glm::value_ptr(camMatrix.Top()));
    glUseProgram(UniformColorTint.theProgram);
    glUniformMatrix4fv(UniformColorTint.worldToCameraM atrixUnif, 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/upload...07d56eccd6.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/Illumi...rial%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

  9. #9
    Junior Member Newbie
    Join Date
    Jun 2013
    Posts
    25
    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.

  10. #10
    Junior Member Newbie
    Join Date
    Jun 2013
    Posts
    6
    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!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •