Skip to content

Instantly share code, notes, and snippets.

@krysseltillada
Created March 18, 2016 09:20
Show Gist options
  • Save krysseltillada/4bfbd38f7d202c62ff8a to your computer and use it in GitHub Desktop.
Save krysseltillada/4bfbd38f7d202c62ff8a to your computer and use it in GitHub Desktop.
exercise 8 perspective transform (widescreen aspect ratio, camera position transformation)
#ifndef CAMERA_HPP
#define CAMERA_HPP
class Camera {
public:
Camera() :
zNear(0.0f), zFar(0.0f), fov(0.0f),
x(0.0f), y(0.0f), z(0.0f) { }
float zNear, zFar, fov;
float x, y, z;
};
#endif
#version 330
layout (location = 0) in vec4 VertexPosition;
layout (location = 1) in vec4 VertexColor;
uniform mat4 perspectiveMatrix;
uniform vec3 cameraOffset;
uniform vec2 offset;
smooth out vec4 OutputVertex;
void main ()
{
vec4 cameraSpacePosition = VertexPosition + vec4(offset.x, offset.y, 0.0f, 0.0f);
cameraSpacePosition += -vec4(cameraOffset.x, cameraOffset.y, -cameraOffset.z, 0.0f);
gl_Position = perspectiveMatrix * cameraSpacePosition;
OutputVertex = VertexColor;
}
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <iostream>
#include "main.hpp"
const char *windowTitle = "exercise 8";
const int width = 800;
const int height = 600;
const int defXPos = 200;
const int defYPos = 200;
void initCoreFunc(int *const argn, char **const argc) {
glutInit(argn, argc);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitContextVersion(3, 3);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutInitWindowPosition(defXPos, defYPos);
glutCreateWindow(windowTitle);
glewExperimental = GL_TRUE;
if (glewInit())
std::cerr << "cannot initialized the context" << std::endl;
glutDisplayFunc(&Run);
glutKeyboardFunc(&Keyboard);
glutReshapeFunc(&Resize);
glutMainLoop();
}
int main(int argn, char **argc)
{
initCoreFunc(&argn, argc);
return 0;
}
#version 330
smooth in vec4 OutputVertex;
out vec4 FragmentColor;
void main ()
{
FragmentColor = OutputVertex;
}
#include "main.hpp"
GLboolean ifInit = GL_FALSE;
const GLfloat Prism[] = {
//** 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 **//
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
};
GLfloat perspectiveMatrix[4 * 4];
GLuint vertexBufferObject;
GLuint shaderProgram;
GLuint vertexShaderObject;
GLuint fragmentShaderObject;
GLuint perspectiveMatrixUniformLocation;
GLuint CameraOffsetUniformLocation;
GLuint cubeOffsetUniformLocation;
Camera cameraPosition;
float width = 0.0, height = 0.0;
void Run() {
if (!ifInit) {
Start();
ifInit = GL_TRUE;
}
Update();
Render();
Clear();
}
void Keyboard(unsigned char key, int x, int y) {
switch (key) {
case 'w':
cameraPosition.y += 0.1f;
break;
case 's':
cameraPosition.y -= 0.1f;
break;
case 'a':
cameraPosition.x -= 0.1f;
break;
case 'd':
cameraPosition.x += 0.1f;
break;
case 'q':
cameraPosition.z += 0.1f;
break;
case 'e':
cameraPosition.z -= 0.1f;
break;
case 'z':
cameraPosition.fov += 0.1f;
break;
case 'x':
cameraPosition.fov -= 0.1f;
break;
default:
break;
}
}
void Resize(int w, int h) {
width = w;
height = h;
perspectiveMatrix[0] = cameraPosition.fov / (w / static_cast <float> (h));
perspectiveMatrix[5] = cameraPosition.fov;
glUseProgram(shaderProgram);
glUniformMatrix4fv(perspectiveMatrixUniformLocation, 1, GL_FALSE, perspectiveMatrix);
glUseProgram(0);
glViewport(0, 0, w, h);
}
namespace {
void vboInitialization() {
glGenBuffers(1, &vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof (Prism), Prism, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Render() {
glUseProgram(shaderProgram);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast <void *> (0));
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast <void *> (sizeof (Prism) / 2));
glDrawArrays(GL_TRIANGLES, 0, 36);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
glutSwapBuffers();
glutPostRedisplay();
}
void Start() {
vboInitialization();
std::string vertexShaderCode, fragmentShaderCode;
vertexShaderCode = Shader::LoadShaderFile("CameraSpace.vert");
fragmentShaderCode = Shader::LoadShaderFile("FragmentProgram.frag");
vertexShaderObject = Shader::CompileShader(GL_VERTEX_SHADER, vertexShaderCode.c_str());
fragmentShaderObject = Shader::CompileShader(GL_FRAGMENT_SHADER, fragmentShaderCode.c_str());
shaderProgram = Shader::BuildProgram({ vertexShaderObject, fragmentShaderObject });
memset(perspectiveMatrix, 0, sizeof (float)* (4 * 4));
cameraPosition.fov = 1.0f;
cameraPosition.zNear = 1.0f;
cameraPosition.zFar = 10.0f;
perspectiveMatrix[0] = cameraPosition.fov;
perspectiveMatrix[5] = cameraPosition.fov;
perspectiveMatrix[10] = (cameraPosition.zNear + cameraPosition.zFar) / (cameraPosition.zNear - cameraPosition.zFar);
perspectiveMatrix[11] = -1.0f;
perspectiveMatrix[14] = (2 * cameraPosition.zNear * cameraPosition.zFar) / (cameraPosition.zNear - cameraPosition.zFar);
perspectiveMatrixUniformLocation = glGetUniformLocation(shaderProgram, "perspectiveMatrix");
CameraOffsetUniformLocation = glGetUniformLocation(shaderProgram, "cameraOffset");
cubeOffsetUniformLocation = glGetUniformLocation(shaderProgram, "offset");
glUseProgram(shaderProgram);
glUniformMatrix4fv(perspectiveMatrixUniformLocation, 1, GL_FALSE, perspectiveMatrix);
glUniform3f(CameraOffsetUniformLocation, cameraPosition.x, cameraPosition.y, cameraPosition.z);
glUseProgram(0);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);
}
void Clear() {
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
void Update() {
perspectiveMatrix[0] = cameraPosition.fov / (width / static_cast <float>(height));
perspectiveMatrix[5] = cameraPosition.fov;
glUseProgram(shaderProgram);
glUniform2f(cubeOffsetUniformLocation, 0.3f, 0.3f);
glUniform3f(CameraOffsetUniformLocation, cameraPosition.x, cameraPosition.y, cameraPosition.z);
glUniformMatrix4fv(perspectiveMatrixUniformLocation, 1, GL_FALSE, perspectiveMatrix);
glUseProgram(0);
}
}
#ifndef MAIN_HPP
#define MAIN_HPP
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <cstdlib>
#include <string>
#include "ShaderUtility.hpp"
#include "Camera.hpp"
void Run();
void Keyboard(unsigned char, int, int);
void Resize(int, int);
namespace {
void vboInitialization();
void Render();
void Start();
void Clear();
void Update();
}
#endif
#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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment