Skip to content

Instantly share code, notes, and snippets.

@krysseltillada
Last active March 15, 2016 20:13
Show Gist options
  • Save krysseltillada/63eded4120e93a6ab979 to your computer and use it in GitHub Desktop.
Save krysseltillada/63eded4120e93a6ab979 to your computer and use it in GitHub Desktop.
exercise 7 Perspective Matrix projection
#define GLEW_STATIC
#include "GL/glew.h"
#include "GL/freeglut.h"
#include <iostream>
#include <string>
#include "main.hpp"
static const int windowWidth = 800;
static const int windowHeight = 600;
static const char *windowTitle = "exercise 5";
void InitCoreFunc(int *const argn, char **cargs) {
glutInit(argn, cargs);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitContextVersion(3, 3);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowSize(windowWidth, windowHeight);
glutInitWindowPosition(200, 200);
glutCreateWindow(windowTitle);
if (glewInit())
std::cerr << "cannot init open gl context " << std::endl;
glutDisplayFunc(&Run);
glutReshapeFunc(&Resize);
glutMainLoop();
}
int main(int argn, char **argc)
{
InitCoreFunc(&argn, argc);
return 0;
}
#include "main.hpp"
bool ifInit = false; /// this tells if the open gl objects is initialized once
GLfloat zNear = 1.0f; /// how near is the plane of projection to the eye
GLfloat zFar = 3.0f; /// how far can a frustum can view
GLfloat frustumScale = 1.0f; /// how large is the field of view
const GLfloat Cube[] = { /// vertices of the cube
//** position of every vertex of a Cube **//
0.25f, 0.25f, -1.25f, 1.0f,
0.25f, -0.25f, -1.25f, 1.0f,
-0.25f, 0.25f, -1.25f, 1.0f,
0.25f, -0.25f, -1.25f, 1.0f,
-0.25f, -0.25f, -1.25f, 1.0f,
-0.25f, 0.25f, -1.25f, 1.0f,
0.25f, 0.25f, -2.75f, 1.0f,
-0.25f, 0.25f, -2.75f, 1.0f,
0.25f, -0.25f, -2.75f, 1.0f,
0.25f, -0.25f, -2.75f, 1.0f,
-0.25f, 0.25f, -2.75f, 1.0f,
-0.25f, -0.25f, -2.75f, 1.0f,
-0.25f, 0.25f, -1.25f, 1.0f,
-0.25f, -0.25f, -1.25f, 1.0f,
-0.25f, -0.25f, -2.75f, 1.0f,
-0.25f, 0.25f, -1.25f, 1.0f,
-0.25f, -0.25f, -2.75f, 1.0f,
-0.25f, 0.25f, -2.75f, 1.0f,
0.25f, 0.25f, -1.25f, 1.0f,
0.25f, -0.25f, -2.75f, 1.0f,
0.25f, -0.25f, -1.25f, 1.0f,
0.25f, 0.25f, -1.25f, 1.0f,
0.25f, 0.25f, -2.75f, 1.0f,
0.25f, -0.25f, -2.75f, 1.0f,
0.25f, 0.25f, -2.75f, 1.0f,
0.25f, 0.25f, -1.25f, 1.0f,
-0.25f, 0.25f, -1.25f, 1.0f,
0.25f, 0.25f, -2.75f, 1.0f,
-0.25f, 0.25f, -1.25f, 1.0f,
-0.25f, 0.25f, -2.75f, 1.0f,
0.25f, -0.25f, -2.75f, 1.0f,
-0.25f, -0.25f, -1.25f, 1.0f,
0.25f, -0.25f, -1.25f, 1.0f,
0.25f, -0.25f, -2.75f, 1.0f,
-0.25f, -0.25f, -2.75f, 1.0f,
-0.25f, -0.25f, -1.25f, 1.0f,
//** color of each vertex of the cube **//
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
0.8f, 0.8f, 0.8f, 1.0f,
0.8f, 0.8f, 0.8f, 1.0f,
0.8f, 0.8f, 0.8f, 1.0f,
0.8f, 0.8f, 0.8f, 1.0f,
0.8f, 0.8f, 0.8f, 1.0f,
0.8f, 0.8f, 0.8f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
};
GLfloat perspectiveMatrix[4 * 4]; /// stores the projection matrix formula
GLuint vertexBufferObject; /// handles that buffer object hidden in the API that stores a list of vertices in that buffer object from gpu
GLuint vertexShaderObject; /// handles that vertex shader object that is used in the program
GLuint fragmentShaderObject; /// handles that fragment shader object that is used in the program
GLuint programObject; /// handles that shader program we created and used in the program
GLint perspectiveMatrixUniformLocation; ///this stores the location (attribute index of a uniform) of that perspectiveMatrix in that vertex shader
GLint offsetUniformLocation; /// this stores the location (attribute index of a uniform) of that offset in that vertex shader
static void InitObject() {
std::string vertexStrCode; /// gets the string type of the vertex shader code
std::string fragmentStrCode; /// same
const char *vertexCode; /// used to store the converted string to pointer type
const char *fragmentCode;
glGenBuffers(1, &vertexBufferObject); /// creates a buffer object and stores the handle in vertexBufferObject which is that buffer object is hidden in the API
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); /// this bounds the buffer object which handles vertexBufferObject in the context by target GL_ARRAY_BUFFER
glBufferData(GL_ARRAY_BUFFER, sizeof(Cube), Cube, GL_STATIC_DRAW); /// this uses that target whoever that target bounds to will gets modified by glBufferData causing that buffer object to store the vertex array data in that buffer object that bounds in the target
glBindBuffer(GL_ARRAY_BUFFER, 0); /// this unbounds the buffer object in context causing GL_ARRAY_BUFFER to be bound in 0 (think of this like a null pointer)
vertexStrCode = Shader::LoadShaderFile("PerspectiveMatrix.vert"); /// loads the vertex shader file
fragmentStrCode = Shader::LoadShaderFile("verticesColor.frag"); /// loads the fragment shader file
vertexCode = vertexStrCode.c_str(); /// converts the string type into pointer to string
fragmentCode = fragmentStrCode.c_str(); /// same
vertexShaderObject = Shader::CompileShader(GL_VERTEX_SHADER, vertexCode); /// compiles the vertex shader code and stores the vertex shader object into the vertexShaderObject
fragmentShaderObject = Shader::CompileShader(GL_FRAGMENT_SHADER, fragmentCode); /// compiles the fragment shader code and stores the fragment shader object into fragmentShaderObject
programObject = Shader::BuildProgram({ vertexShaderObject, fragmentShaderObject }); /// this attaches the shader objects, links it, detaches it deletes it and builds it into one shader program
perspectiveMatrixUniformLocation = glGetUniformLocation(programObject, "perspectiveMatrix"); /// gets the uniform location of that name uniform variable in the vertex shader o fragment shader
offsetUniformLocation = glGetUniformLocation(programObject, "offset"); /// gets the uniform location of that name uniform variable in the fragment shader or vertex shader
memset(perspectiveMatrix, 0, sizeof (float)* 16); /// sets the value to be 0 in every element of the perspective matrix array
/// *** applies the perspective matrix formula *** ///
perspectiveMatrix[0] = frustumScale; /// this scales the x of the plane of projection
perspectiveMatrix[5] = frustumScale; /// this scales the y of the plane of projection
perspectiveMatrix[10] = (zNear + zFar) / (zNear - zFar); /// this calculates the depth or the z of that vertex
perspectiveMatrix[11] = -1.0f; /// this sets the w component to be negative by the z component of the camera vertex for ndc coordinates
perspectiveMatrix[14] = (2 * zNear * zFar) / (zNear - zFar); /// this calculates also the depth
glUseProgram(programObject); /// this uses the shader program
glUniformMatrix4fv(perspectiveMatrixUniformLocation, 1, GL_FALSE, perspectiveMatrix); /// sends the uniform matrix value in that location in the vertex shader which perspectiveMatrix
glUniform2f(offsetUniformLocation, 0.3f, 0.3f); /// same here
glUseProgram(0); /// this will not use that shader program
glEnable(GL_CULL_FACE); /// this enables face culling
glCullFace(GL_BACK); /// this culls the back side of the cube
glFrontFace(GL_CW); /// this orders the culling to be in clock wise order
}
static void Render() {
glUseProgram(programObject); /// uses that shader program
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject); /// this uses that buffer object that handles by that vertexBufferObject
glEnableVertexAttribArray(0); /// this enables the vertex attribute index for the vertex attribute array
glEnableVertexAttribArray(1); /// same
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast <void *> (0)); /// this tells how to send the data in the vertex shader
/// this sends the list of vertices in that vertex attribute index 0 that assigned 0 in the vertex shader we used
/// in every 4 floats we encountered it forms a single vertex or a vec4
/// the type of the data we send is float so GL_FLOAT
/// there is no spacing for each set of vertex
/// the byte offset starts at the front of the buffer object array which is at the beginning of the element
/// whoever GL_ARRAY_BUFFFER target bounds to that object will be refer by glVertexAttribPointer
/// so this sends the data in a total of the full size of the vertex buffer array
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast <void *> (sizeof (Cube) / 2)); /// same here but we send the data in each call in the attribute index 0 and starts at the middle element of the vertex buffer array object
glDrawArrays(GL_TRIANGLES, 0, 36); /// this draws the 36 vertices and each 3 vertices will be formed a one triangle
glBindBuffer(GL_ARRAY_BUFFER, 0); /// this unbounds the buffer object in the context
glDisableVertexAttribArray(0); /// this disables the vertex attribute index
glDisableVertexAttribArray(1); // same
glUseProgram(0); /// this will not use that shader program
glutSwapBuffers(); /// this swaps the buffer
glutPostRedisplay(); /// this swaps updates the window fast
}
static void Clear() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); /// this clears the buffer color by that intensity value
glClear(GL_COLOR_BUFFER_BIT); /// this clears the buffer color by GL_COLOR_BUFFER_BIT
}
static void Update() {
}
void Run() {
if (!ifInit) { /// if the object is not initialized then initialized once
InitObject();
ifInit = true;
}
Render(); /// renders
Update(); /// updates
Clear(); /// clears
}
void Resize(int w, int h) {
glViewport(0, 0, w, h); /// this updates the size of the viewable rendering area
}
#ifndef MAIN_HEADER
#define MAIN_HEADER
#include "GL/glew.h"
#include "GL/freeglut.h"
#include "Shader.hpp"
static void InitObject();
static void Render();
static void Clear();
static void Update();
void Run();
void Resize(int, int);
#endif
#version 330
layout(location = 0) in vec4 position; /// assigns a attribute index for the vertex shader
layout(location = 1) in vec4 color;
smooth out vec4 theColor; /// this varible is used by the next stage of the pipeline
uniform mat4 perspectiveMatrix; /// uniform variable of type mat4
uniform vec2 offset; /// uniform variable of type vec2
void main ()
{
vec4 cameraSpacePosition = position + vec4 (offset.x, offset.y, 0.0f, 0.0f); /// applies the offset and store it into camera space
gl_Position = perspectiveMatrix * cameraSpacePosition; /// multiples the matrix and the vector camera space position and results into a single clip space camera vector
theColor = color; /// sends the input color to the output color in the next stage
}
#ifndef SHADER_HEADER
#define SHADER_HEADER
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <initializer_list>
#include <string>
#include <memory>
#include <iostream>
#include <fstream>
#include <algorithm>
class Shader {
public:
static GLuint BuildProgram(std::initializer_list <GLuint> shaderObjects) {
GLuint programObject = glCreateProgram();
GLint linkStatus;
for (std::initializer_list <GLuint>::iterator Shaderit = shaderObjects.begin();
Shaderit != shaderObjects.end(); ++Shaderit)
glAttachShader(programObject, *Shaderit);
glLinkProgram(programObject);
glGetProgramiv(programObject, GL_LINK_STATUS, &linkStatus);
if (!linkStatus) {
GLint logLength;
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &logLength);
std::unique_ptr <GLchar> errLog(new GLchar[logLength + 1]);
glGetProgramInfoLog(programObject, logLength + 1, nullptr, errLog.get());
std::cerr << "program linking error: " << std::endl
<< errLog.get() << std::endl;
}
for (std::initializer_list <GLuint>::iterator Shaderit2 = shaderObjects.begin();
Shaderit2 != shaderObjects.end(); ++Shaderit2)
glDetachShader(programObject, *Shaderit2);
return programObject;
}
static std::string LoadShaderFile(const std::string &fileName) {
std::ifstream readFile(fileName, std::ifstream::in, std::ifstream::trunc);
std::string srcCode, line;
if (!readFile)
std::cout << "cannot open shader file " << fileName << std::endl;
for (; std::getline(readFile, line);)
srcCode += line + "\n";
if (srcCode[srcCode.length() - 1] != '\0')
srcCode.push_back('\0');
std::cout << srcCode << std::endl;
return srcCode;
}
static GLuint CompileShader(const GLenum &shaderType, const char *shaderCode) {
GLuint shaderObject = glCreateShader(shaderType);
GLint compileStatus;
glShaderSource(shaderObject, 1, &shaderCode, nullptr);
glCompileShader(shaderObject);
glGetShaderiv(shaderObject, GL_COMPILE_STATUS, &compileStatus);
if (!compileStatus) {
GLint logLength;
glGetShaderiv(shaderObject, GL_INFO_LOG_LENGTH, &logLength);
std::unique_ptr <GLchar> errLog(new GLchar[logLength + 1]);
glGetShaderInfoLog(shaderObject, logLength + 1, nullptr, errLog.get());
std::cerr << ((shaderType == GL_VERTEX_SHADER) ? "vertex" :
(shaderType == GL_FRAGMENT_SHADER) ? "fragment" : "none") << "shader error" << std::endl
<< errLog.get() << std::endl;
}
return shaderObject;
}
};
#endif
#version 330
smooth in vec4 theColor; /// gets that color from vertex shader
out vec4 fragmentOutput; /// this stores the color for that fragment
void main ()
{
fragmentOutput = theColor; /// assigns the color for that fragment
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment