Code
Code
#include <iostream>
#include <cstdlib>
#include <GLEW/glew.h>
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <glm/glm/glm.hpp>
#include <glm/glm/gtx/transform.hpp>
#include <glm/glm/gtc/type_ptr.hpp>
// Camera Header
#include "camera.h"
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version " core \n" #Source
#endif
// Unnamed namespace
namespace
// Windows Name
struct GLMesh
{
// Vertex Array Object
GLuint cylinderVbos[2];
};
// GLFW window
GLMesh gMesh;
// Texture
// Shader programs
// Camera
Camera gCamera(glm::vec3(0.0f, 0.0f, 8.0f));
// Timing
glm::vec3 gLightScale(1.3f);
glm::vec3 gPlugScale(0.6f);
glm::vec3 gFillScale(1.3f);
// Rule (RECTANGLE)
glm::vec3 gRuleScale(0.85f);
glm::vec3 gPlaneScale(3.0f);
// Speaker (CYLINDER)
glm::vec3 gSpeakerScale(3.0f);
// Logo (CUBE)
glm::vec3 gLogoScale(0.3f);
// Lamp animation
// Initialize Program
// Mouse Functions
// Create Speaker
// Render Graphics
void URender();
// Shader Program
// Main
void main()
vertexTextureCoordinate = textureCoordinate;
);
in vec3 vertexNormal;
in vec3 vertexFragmentPos;
in vec2 vertexTextureCoordinate;
// Variables for Object Color, Light Color, Light Position, and Camera/View
Position
// Main
void main()
);
// Main
void main()
);
void main()
// Set Color
fragmentColor = vec4(1.0f);
);
// Main
void main()
);
// Main
void main()
// Set Color
fragmentColor = vec4(1.0f);
}
);
void flipImageVertically(unsigned char* image, int width, int height, int channels)
image[index1] = image[index2];
image[index2] = tmp;
++index1;
++index2;
// Main Function
return EXIT_FAILURE;
// Create Mesh
UCreateMesh(gMesh);
/* Rule */
if (!UCreateShaderProgram(cubeVertexShaderSource, cubeFragmentShaderSource,
gProgramId))
return EXIT_FAILURE;
/* Lamp */
if (!UCreateShaderProgram(lampVertexShaderSource, lampFragmentShaderSource,
gLampProgramId))
return EXIT_FAILURE;
/* Keyboard Mat */
if (!UCreateShaderProgram(cubeVertexShaderSource, cubeFragmentShaderSource,
gPlaneProgramId))
return EXIT_FAILURE;
/* Speaker */
if (!UCreateShaderProgram(cubeVertexShaderSource, cubeFragmentShaderSource,
gSpeakerProgramId))
return EXIT_FAILURE;
/* Wall Plug */
if (!UCreateShaderProgram(cubeVertexShaderSource, cubeFragmentShaderSource,
gPlugProgramId))
return EXIT_FAILURE;
/* Logo */
if (!UCreateShaderProgram(cubeVertexShaderSource, cubeFragmentShaderSource,
gLogoProgramId))
return EXIT_FAILURE;
/* Fill */
if (!UCreateShaderProgram(fillVertexShaderSource, fillFragmentShaderSource,
gFillProgramId))
return EXIT_FAILURE;
// RULE
if (!UCreateTexture(texFilename, gTextureId))
cout << "Failed to load texture " << texFilename << endl;
return EXIT_FAILURE;
// KEYBOARD(PLANE)
texFilename = "razenmat.png";
if (!UCreateTexture(texFilename, gPlanePattern))
cout << "Failed to load texture " << texFilename << endl;
return EXIT_FAILURE;
// SPEAKER
texFilename = "speaker.png";
if (!UCreateTexture(texFilename, gSpeakerPattern))
cout << "Failed to load texture " << texFilename << endl;
return EXIT_FAILURE;
// WALL PLUG
texFilename = "wplug.jpg";
if (!UCreateTexture(texFilename, gPlugPattern))
cout << "Failed to load texture " << texFilename << endl;
return EXIT_FAILURE;
// LOGO
texFilename = "logo.png";
if (!UCreateTexture(texFilename, gLogoPattern))
cout << "Failed to load texture " << texFilename << endl;
return EXIT_FAILURE;
glUseProgram(gProgramId);
// Render Loop
while (!glfwWindowShouldClose(gWindow))
// Pre-Frame Timing
gLastFrame = currentFrame;
// Input
UProcessInput(gWindow);
// Render
URender();
glfwPollEvents();
UDestroyMesh(gMesh);
// Release Texture
UDestroyTexture(gTextureId);
UDestroyShaderProgram(gProgramId);
UDestroyShaderProgram(gLampProgramId);
UDestroyShaderProgram(gPlaneProgramId);
UDestroyShaderProgram(gSpeakerProgramId);
UDestroyShaderProgram(gPlugProgramId);
UDestroyShaderProgram(gFillProgramId);
UDestroyShaderProgram(gLogoProgramId);
exit(EXIT_SUCCESS);
// GLFW
// Initialize
glfwInit();
// Configuration
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// GLFW
// Window Creation
if (*window == NULL)
glfwTerminate();
return false;
glfwMakeContextCurrent(*window);
glfwSetFramebufferSizeCallback(*window, UResizeWindow);
glfwSetCursorPosCallback(*window, UMousePositionCallback);
glfwSetScrollCallback(*window, UMouseScrollCallback);
// GLEW
glewExperimental = GL_TRUE;
return false;
cout << "INFO: OpenGL Version: " << glGetString(GL_VERSION) << endl;
return true;
glfwSetWindowShouldClose(window, true);
// W Key Zoom In
gCamera.ProcessKeyboard(FORWARD, gDeltaTime);
gCamera.ProcessKeyboard(BACKWARD, gDeltaTime);
gCamera.ProcessKeyboard(LEFT, gDeltaTime);
gCamera.ProcessKeyboard(RIGHT, gDeltaTime);
// Upward/Downward Movement
// Q Key Move Up
gCamera.ProcessKeyboard(UP, gDeltaTime);
gCamera.ProcessKeyboard(DOWN, gDeltaTime);
gLampIsOrbiting = true;
gLampIsOrbiting = false;
// glfw: whenever the window size changed (by OS or user resize) this callback
function executes
if (gFirstMouse)
gLastX = xpos;
gLastY = ypos;
gFirstMouse = false;
}
float xoffset = xpos - gLastX;
gLastX = xpos;
gLastY = ypos;
gCamera.ProcessMouseMovement(xoffset, yoffset);
gCamera.ProcessMouseScroll(yoffset);
int currentVertex = 0;
currentVertex++;
currentVertex++;
int currentTriangle = 0;
currentVertex++;
currentVertex++;
if (edge > 0) {
// Top triangle
// Bottom Triangle
currentTriangle++;
currentTriangle++;
currentTriangle++;
// Top Triangle
currentTriangle++;
// Bottom Triangle
currentTriangle++;
// First Triangle 1/2 Rectangular Side
currentTriangle++;
currentTriangle++;
void URender()
if (!gLampIsOrbiting)
gLightPosition.x = newPosition.x;
gLightPosition.y = newPosition.y;
gLightPosition.z = newPosition.z;
// Enable Z-Depth
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(gProgramId);
// Camera/View transformation
// Reference Matrix Uniforms from the Rule Shader Program for the Cub Color, Light
Color, Light Position, and Camera Position
// Pass Color, Light, and Camera Data to the Cube Shader Program's Corresponding
Uniforms
glUniform2fv(UVScaleLoc, 1, glm::value_ptr(gUVScale));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gTextureId);
glDrawArrays(GL_TRIANGLES, 0, gMesh.ruleVertices);
glUseProgram(gProgramId);
glBindTexture(GL_TEXTURE_2D, gPlanePattern);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(gMesh.planeVao);
glDrawArrays(GL_TRIANGLES, 0, gMesh.planeVertices);
glUseProgram(gProgramId);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gSpeakerPattern);
glBindVertexArray(gMesh.cylinderVao);
glUseProgram(gProgramId);
glBindTexture(GL_TEXTURE_2D, gPlugPattern);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(gMesh.cubeVao);
glDrawArrays(GL_TRIANGLES, 0, gMesh.cubeVertices);
glUseProgram(gProgramId);
glBindTexture(GL_TEXTURE_2D, gLogoPattern);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(gMesh.logoVao);
glDrawArrays(GL_TRIANGLES, 0, gMesh.logoVertices);
glUseProgram(gLampProgramId);
// Transform the Smaller Cube used as a Visual for the Light Source
glDrawArrays(GL_TRIANGLES, 0, gMesh.cylinderVertices);
glUseProgram(gFillProgramId);
// Transform the Smaller Cube used as a Visual for the Light Source
glDrawArrays(GL_TRIANGLES, 0, gMesh.cylinderVertices);
// Deactivate the Vertex Array Object
glBindVertexArray(0);
glUseProgram(0);
glfwSwapBuffers(gWindow);
GLfloat verts[NUM_VERTICES];
GLushort indices[NUM_INDICES];
// RULE
GLfloat ruleVerts[] = {
// KEYBOARD MAT
GLfloat planeVerts[] = {
};
// PLUG
GLfloat plugVerts[] = {
};
GLfloat logoVerts[] = {
};
// Create Buffers
glGenVertexArrays(1, &mesh.ruleVao);
glBindVertexArray(mesh.ruleVao);
glGenBuffers(1, &mesh.ruleVbo);
glBindBuffer(GL_ARRAY_BUFFER, mesh.ruleVbo);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glGenVertexArrays(1, &mesh.planeVao);
glBindVertexArray(mesh.planeVao);
// Create Buffers
glGenBuffers(1, &mesh.planeVbo);
glBindBuffer(GL_ARRAY_BUFFER, mesh.planeVbo);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glGenVertexArrays(1, &mesh.cylinderVao);
glBindVertexArray(mesh.cylinderVao);
// Create Buffers
glGenBuffers(2, mesh.cylinderVbos);
glBindBuffer(GL_ARRAY_BUFFER, mesh.cylinderVbos[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.cylinderVbos[1]);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glGenVertexArrays(1, &mesh.cubeVao);
glBindVertexArray(mesh.cubeVao);
// Create Buffers
glGenBuffers(1, &mesh.cubeVbo);
glBindBuffer(GL_ARRAY_BUFFER, mesh.cubeVbo);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glGenVertexArrays(1, &mesh.logoVao);
glBindVertexArray(mesh.logoVao);
// Create Buffers
glGenBuffers(1, &mesh.logoVbo);
glBindBuffer(GL_ARRAY_BUFFER, mesh.logoVbo);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
glDeleteVertexArrays(1, &mesh.ruleVao);
glDeleteBuffers(1, &mesh.ruleVbo);
// UCreateTexture Function
if (image)
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
// Texture Paramater
if (channels == 3)
else if (channels == 4)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image);
else
cout << "Not implemented to handle image with " << channels << " channels" << endl;
return false;
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(image);
glBindTexture(GL_TEXTURE_2D, 0);
return true;
return false;
// UDestroyTexture Function
glGenTextures(1, &textureId);
// UCreateShaders Function
int success = 0;
char infoLog[512];
programId = glCreateProgram();
glCompileShader(vertexShaderId);
if (!success)
return false;
glCompileShader(fragmentShaderId);
if (!success)
return false;
glAttachShader(programId, vertexShaderId);
glAttachShader(programId, fragmentShaderId);
if (!success)
return false;
glUseProgram(programId);
return true;
glDeleteProgram(programId);