Created
March 18, 2016 09:20
-
-
Save krysseltillada/4bfbd38f7d202c62ff8a to your computer and use it in GitHub Desktop.
exercise 8 perspective transform (widescreen aspect ratio, camera position transformation)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 330 | |
smooth in vec4 OutputVertex; | |
out vec4 FragmentColor; | |
void main () | |
{ | |
FragmentColor = OutputVertex; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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