• Skip to main content
  • Skip to primary sidebar

Anastasios Chondrogiannis

Software developer with a focus on iOS

Android OpenGL ES – Part 9: Diffuse lighting

March 24, 2020 by Anastasios Chondrogiannis Leave a Comment

1. Modify the directional light

1.1. Modify the fragment shader

  • Open the main.cpp file.
  • Modify the fragment shader source code as follows:
static const GLchar fragmentShaderSource[] =
   "#version 310 es\n"
   "precision mediump float;\n"
   "in vec4 vColor;\n"
   "in vec2 vTexCoords;\n"
   "out vec4 color;\n"
   "struct DirectionalLight\n"
   "{\n"
   "vec3 color;\n"
   "float intensity;\n"
   "vec3 direction;\n"
   "float diffuseIntensity;\n"
   "};\n"
   "uniform sampler2D textureSampler;\n"
   "uniform DirectionalLight directionalLight;\n"
   "void main()\n"
   "{\n"
   "vec4 ambientColor = vec4(directionalLight.color, 1.0f) * directionalLight.intensity;\n"
   "color = texture(textureSampler, vTexCoords) * ambientColor;\n"
   "}\n";

1.2. Set the uniform variables

  • Declare the following global variables:
/* code */

GLint uniformModel, uniformProjection, uniformView;
GLint uniformLightColor, uniformLightIntensity, uniformLightDirection, uniformDiffuseLightIntensity;
glm::mat4 projectionMatrix;

/* code */
  • Modify the createProgram function as follows:
/* code */

uniformLightIntensity = glGetUniformLocation(program, "directionalLight.intensity");
uniformLightDirection = glGetUniformLocation(program, "directionalLight.direction");
uniformDiffuseLightIntensity = glGetUniformLocation(program, "directionalLight.diffuseIntensity");

return;

/* code */
  • Modify the Java_dev_anastasioscho_glestriangle_NativeLibrary_nOnDrawFrame function as follows:
/* code */

glUniform3f(uniformLightColor, 1.0f, 1.0f, 1.0f);
glUniform1f(uniformLightIntensity, 1.0f);
glUniform3f(uniformLightDirection, 2.0f, 0.3f, -2.0f);
glUniform1f(uniformDiffuseLightIntensity, 1.0f);

currentAngle += angleStep;
if (currentAngle >= 360.0f) currentAngle -= 360.0f;

/* code */

2. Add the normals

2.1. Modify the vertices data

  • Modify the createTriangle function as follows:
void createTriangle() {
   /* code */

   GLfloat vertices[] = {
      0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
      -1.0f, -1.0f, 1.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f,
      1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
      1.0f, -1.0f, -1.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f,
      -1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f
   };

   glGenVertexArrays(1, &triangleVAO);
   glBindVertexArray(triangleVAO);

   glGenBuffers(1, &triangleIBO);
   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangleIBO);
   glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

   glGenBuffers(1, &triangleVBO);
   glBindBuffer(GL_ARRAY_BUFFER, triangleVBO);
   glBufferData(GL_ARRAY_BUFFER, 40 * sizeof(GL_FLOAT), vertices, GL_STATIC_DRAW);

   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT) * 8, 0);
   glEnableVertexAttribArray(0);

   glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT) * 8, (void*)(sizeof(GL_FLOAT) * 3));
   glEnableVertexAttribArray(1);

   /* code */

   return;
}

Info

The last three floats are the x, y and z coordinates of the normal vector. Initially the are all zero. You will calculate them next.

  • Add the following function to calculate the average normals:
void calculateAverageNormals(unsigned int *indices, unsigned int totalIndices, GLfloat *vertices, unsigned int totalVertices, unsigned int vertexLength, unsigned int normalOffset) {
   for (size_t i = 0; i < totalIndices; i += 3) {
      unsigned int in0 = indices[i] * vertexLength;
      unsigned int in1 = indices[i + 1] * vertexLength;
      unsigned int in2 = indices[i + 2] * vertexLength;

      glm::vec3 v1(vertices[in1] - vertices[in0], vertices[in1 + 1] - vertices[in0 + 1], vertices[in1 + 2] - vertices[in0 + 2]);
      glm::vec3 v2(vertices[in2] - vertices[in0], vertices[in2 + 1] - vertices[in0 + 1], vertices[in2 + 2] - vertices[in0 + 2]);
      glm::vec3 normal = glm::cross(v1, v2);
      normal = glm::normalize(normal);

      in0 += normalOffset; in1 += normalOffset; in2 += normalOffset;

      vertices[in0] += normal.x; vertices[in0 + 1] += normal.y; vertices[in0 + 2] += normal.z;
      vertices[in1] += normal.x; vertices[in1 + 1] += normal.y; vertices[in1 + 2] += normal.z;
      vertices[in2] += normal.x; vertices[in2 + 1] += normal.y; vertices[in2 + 2] += normal.z;
   }

   for (size_t i = 0; i < (totalVertices / vertexLength); i++) {
      unsigned int nOffset = (i * vertexLength) + normalOffset;
      glm::vec3 vec(vertices[nOffset], vertices[nOffset + 1], vertices[nOffset + 2]);
      vec = glm::normalize(vec);
      vertices[nOffset] = vec.x; vertices[nOffset + 1] = vec.y; vertices[nOffset + 2] = vec.z;
   }
}
  • Modify the createTriangle function to call the function:
/* code */

GLfloat vertices[] = {
   0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
   -1.0f, -1.0f, 1.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f,
   1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
   1.0f, -1.0f, -1.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f,
   -1.0f, -1.0f, -1.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f
};

calculateAverageNormals(indices, 12, vertices, 40, 8, 5);

glGenVertexArrays(1, &triangleVAO);
glBindVertexArray(triangleVAO);

/* code */

2.2. Modify the vertex shader

  • Modify the vertex shader source code as follows:
static const GLchar vertexShaderSource[] =
   "#version 310 es\n"
   "layout (location = 0) in vec3 pos;\n"
   "layout (location = 1) in vec2 texCoords;\n"
   "layout (location = 2) in vec3 norm;\n"
   "out vec4 vColor;\n"
   "out vec2 vTexCoords;\n"
   "out vec3 vNorm;\n"
   "uniform mat4 model;\n"
   "uniform mat4 projection;\n"
   "uniform mat4 view;\n"
   "void main()\n"
   "{\n"
   "gl_Position = projection * view * model * vec4(pos, 1.0);\n"
   "vColor = vec4(clamp(pos, 0.0, 1.0), 1.0);\n"
   "vTexCoords = texCoords;\n"
   "vNorm = mat3(transpose(inverse(model))) * norm;\n"
   "}\n";
  • Modify the fragment shader source code as follows:
static const GLchar fragmentShaderSource[] =
   "#version 310 es\n"
   "precision mediump float;\n"
   "in vec4 vColor;\n"
   "in vec2 vTexCoords;\n"
   "in vec3 vNorm;\n"
   "out vec4 color;\n"
   "struct DirectionalLight\n"
   "{\n"
   "vec3 color;\n"
   "float intensity;\n"
   "vec3 direction;\n"
   "float diffuseIntensity;\n"
   "};\n"
   "uniform sampler2D textureSampler;\n"
   "uniform DirectionalLight directionalLight;\n"
   "void main()\n"
   "{\n"
   "vec4 ambientColor = vec4(directionalLight.color, 1.0f) * directionalLight.intensity;\n"
   "color = texture(textureSampler, vTexCoords) * ambientColor;\n"
   "}\n";
  • Modify the createTriangle function as follows:
/* code */

glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT) * 8, (void*)(sizeof(GL_FLOAT) * 3));
glEnableVertexAttribArray(1);

glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT) * 8, (void*)(sizeof(GL_FLOAT) * 5));
glEnableVertexAttribArray(2);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);

/* code */

3. Apply diffuse lighting

  • Modify the fragment shader source code as follows:
static const GLchar fragmentShaderSource[] =
   "#version 310 es\n"
   "precision mediump float;\n"
   "in vec4 vColor;\n"
   "in vec2 vTexCoords;\n"
   "in vec3 vNorm;\n"
   "out vec4 color;\n"
   "struct DirectionalLight\n"
   "{\n"
   "vec3 color;\n"
   "float intensity;\n"
   "vec3 direction;\n"
   "float diffuseIntensity;\n"
   "};\n"
   "uniform sampler2D textureSampler;\n"
   "uniform DirectionalLight directionalLight;\n"
   "void main()\n"
   "{\n"
   "vec4 ambientColor = vec4(directionalLight.color, 1.0f) * directionalLight.intensity;\n"
   "float diffuseFactor = max(dot(normalize(vNorm), normalize(directionalLight.direction)), 0.0f);\n"
   "vec4 diffuseColor = vec4(directionalLight.color, 1.0f) * directionalLight.diffuseIntensity * diffuseFactor;\n"
   "color = texture(textureSampler, vTexCoords) * (ambientColor + diffuseColor);\n"
   "}\n";

Filed Under: Android Development

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

Let’s connect!

  • Facebook
  • Instagram
  • LinkedIn
  • Twitter

Recent Posts

  • Android OpenGL ES – Part 10: Specular lighting
  • Android OpenGL ES – Part 9: Diffuse lighting
  • Android OpenGL ES – Part 8: Ambient Lighting
  • Android OpenGL ES – Part 7: Textures
  • Android OpenGL ES – Part 6: Camera View

Archives

  • March 2020
  • February 2020
  • November 2019
  • October 2019
  • July 2019

Categories

  • Android Development
  • Machine Learning

Copyright © 2025 · Genesis Sample on Genesis Framework · WordPress · Log in