Created
May 12, 2016 05:04
-
-
Save krysseltillada/df0179a81c88c9af2fa9a5220abbb60e to your computer and use it in GitHub Desktop.
ex 14 (depth clamping, clipping)
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_HEADER | |
#define CAMERA_HEADER | |
class Camera { | |
public: | |
Camera() : x(0.0f), | |
y(0.0f), | |
z(0.0f), | |
zNear(0.0f), | |
zFar(0.0f), | |
fov(0.0f) {} | |
float x, y, z; | |
float zNear, zFar, fov; | |
}; | |
#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 | |
flat in vec4 outputColor; | |
out vec4 fragmentColor; | |
void main () | |
{ | |
fragmentColor = outputColor; | |
} |
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 <string> | |
#include <cstdlib> | |
#include <stdexcept> | |
#include "Camera.hpp" | |
#include "Shader.hpp" | |
#define WINDOW_WIDTH 800 | |
#define WINDOW_HEIGHT 600 | |
#define WINDOW_POSX 200 | |
#define WINDOW_POSY 200 | |
const char *windowTitle = "exercise14"; | |
const int numberOfVertices = 36; | |
#define RIGHT_EXTENT 0.8f | |
#define LEFT_EXTENT -RIGHT_EXTENT | |
#define TOP_EXTENT 0.20f | |
#define MIDDLE_EXTENT 0.0f | |
#define BOTTOM_EXTENT -TOP_EXTENT | |
#define FRONT_EXTENT -1.25f | |
#define REAR_EXTENT -1.75f | |
#define GREEN_COLOR 0.75f, 0.75f, 1.0f, 1.0f | |
#define BLUE_COLOR 0.0f, 0.5f, 0.0f, 1.0f | |
#define RED_COLOR 1.0f, 0.0f, 0.0f, 1.0f | |
#define GREY_COLOR 0.8f, 0.8f, 0.8f, 1.0f | |
#define BROWN_COLOR 0.5f, 0.5f, 0.0f, 1.0f | |
const float vertexData[] = { | |
//Object 1 positions | |
LEFT_EXTENT, TOP_EXTENT, REAR_EXTENT, | |
LEFT_EXTENT, MIDDLE_EXTENT, FRONT_EXTENT, | |
RIGHT_EXTENT, MIDDLE_EXTENT, FRONT_EXTENT, | |
RIGHT_EXTENT, TOP_EXTENT, REAR_EXTENT, | |
LEFT_EXTENT, BOTTOM_EXTENT, REAR_EXTENT, | |
LEFT_EXTENT, MIDDLE_EXTENT, FRONT_EXTENT, | |
RIGHT_EXTENT, MIDDLE_EXTENT, FRONT_EXTENT, | |
RIGHT_EXTENT, BOTTOM_EXTENT, REAR_EXTENT, | |
LEFT_EXTENT, TOP_EXTENT, REAR_EXTENT, | |
LEFT_EXTENT, MIDDLE_EXTENT, FRONT_EXTENT, | |
LEFT_EXTENT, BOTTOM_EXTENT, REAR_EXTENT, | |
RIGHT_EXTENT, TOP_EXTENT, REAR_EXTENT, | |
RIGHT_EXTENT, MIDDLE_EXTENT, FRONT_EXTENT, | |
RIGHT_EXTENT, BOTTOM_EXTENT, REAR_EXTENT, | |
LEFT_EXTENT, BOTTOM_EXTENT, REAR_EXTENT, | |
LEFT_EXTENT, TOP_EXTENT, REAR_EXTENT, | |
RIGHT_EXTENT, TOP_EXTENT, REAR_EXTENT, | |
RIGHT_EXTENT, BOTTOM_EXTENT, REAR_EXTENT, | |
// 0, 2, 1, | |
// 3, 2, 0, | |
//Object 2 positions | |
TOP_EXTENT, RIGHT_EXTENT, REAR_EXTENT, | |
MIDDLE_EXTENT, RIGHT_EXTENT, FRONT_EXTENT, | |
MIDDLE_EXTENT, LEFT_EXTENT, FRONT_EXTENT, | |
TOP_EXTENT, LEFT_EXTENT, REAR_EXTENT, | |
BOTTOM_EXTENT, RIGHT_EXTENT, REAR_EXTENT, | |
MIDDLE_EXTENT, RIGHT_EXTENT, FRONT_EXTENT, | |
MIDDLE_EXTENT, LEFT_EXTENT, FRONT_EXTENT, | |
BOTTOM_EXTENT, LEFT_EXTENT, REAR_EXTENT, | |
TOP_EXTENT, RIGHT_EXTENT, REAR_EXTENT, | |
MIDDLE_EXTENT, RIGHT_EXTENT, FRONT_EXTENT, | |
BOTTOM_EXTENT, RIGHT_EXTENT, REAR_EXTENT, | |
TOP_EXTENT, LEFT_EXTENT, REAR_EXTENT, | |
MIDDLE_EXTENT, LEFT_EXTENT, FRONT_EXTENT, | |
BOTTOM_EXTENT, LEFT_EXTENT, REAR_EXTENT, | |
BOTTOM_EXTENT, RIGHT_EXTENT, REAR_EXTENT, | |
TOP_EXTENT, RIGHT_EXTENT, REAR_EXTENT, | |
TOP_EXTENT, LEFT_EXTENT, REAR_EXTENT, | |
BOTTOM_EXTENT, LEFT_EXTENT, REAR_EXTENT, | |
//Object 1 colors | |
GREEN_COLOR, | |
GREEN_COLOR, | |
GREEN_COLOR, | |
GREEN_COLOR, | |
BLUE_COLOR, | |
BLUE_COLOR, | |
BLUE_COLOR, | |
BLUE_COLOR, | |
RED_COLOR, | |
RED_COLOR, | |
RED_COLOR, | |
GREY_COLOR, | |
GREY_COLOR, | |
GREY_COLOR, | |
BROWN_COLOR, | |
BROWN_COLOR, | |
BROWN_COLOR, | |
BROWN_COLOR, | |
//Object 2 colors | |
RED_COLOR, | |
RED_COLOR, | |
RED_COLOR, | |
RED_COLOR, | |
BROWN_COLOR, | |
BROWN_COLOR, | |
BROWN_COLOR, | |
BROWN_COLOR, | |
BLUE_COLOR, | |
BLUE_COLOR, | |
BLUE_COLOR, | |
GREEN_COLOR, | |
GREEN_COLOR, | |
GREEN_COLOR, | |
GREY_COLOR, | |
GREY_COLOR, | |
GREY_COLOR, | |
GREY_COLOR, | |
}; | |
const GLshort indexData[] = | |
{ | |
0, 2, 1, | |
3, 2, 0, | |
4, 5, 6, | |
6, 7, 4, | |
8, 9, 10, | |
11, 13, 12, | |
14, 16, 15, | |
17, 16, 14, | |
}; | |
Camera camera; | |
GLfloat perspectiveMatrix[4 * 4]; | |
GLuint perspectiveMatrixUniformLocation; | |
GLuint offsetUniformLocation; | |
GLuint objectOffsetUniformLocation; | |
GLuint vbo; | |
GLuint ebo; | |
GLuint vao1; | |
GLuint vao2; | |
GLuint shaderProgram; | |
bool ifInit = GL_FALSE; | |
bool ifDepthTest = false, ifAspect = false, ifDepthClamp = false, | |
ifBackCull = false, ifFrontCull = false, ifFrontBackCull = false; | |
float width = 0.0f, height = 0.0f; | |
void Render() { | |
glUseProgram(shaderProgram); | |
glUniform3f(objectOffsetUniformLocation, 0.0f, 0.0f, 0.5f); | |
glBindVertexArray(vao1); | |
glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_SHORT, (void *)0); | |
glUniform3f(objectOffsetUniformLocation, 0.0f, 0.0f, 0.0f); | |
glDrawElementsBaseVertex(GL_TRIANGLES, sizeof(indexData) / sizeof(float), | |
GL_UNSIGNED_SHORT, 0, numberOfVertices / 2); | |
glBindVertexArray(0); | |
glUseProgram(0); | |
glutSwapBuffers(); | |
glutPostRedisplay(); | |
} | |
void Init() { | |
camera.fov = 1.0f; | |
camera.zFar = 3.0f; | |
camera.zNear = 1.0f; | |
memset(perspectiveMatrix, 0, sizeof(float)* 16); | |
perspectiveMatrix[0] = camera.fov; | |
perspectiveMatrix[5] = camera.fov; | |
perspectiveMatrix[10] = (camera.zNear + camera.zFar) / (camera.zNear - camera.zFar); | |
perspectiveMatrix[11] = -1.0f; | |
perspectiveMatrix[14] = (2 * camera.zNear * camera.zFar) / (camera.zNear - camera.zFar); | |
std::string vertexCode = Shader::ShaderUtility::LoadShaderFile("perspective.vert"); | |
std::string fragmentCode = Shader::ShaderUtility::LoadShaderFile("fragment.frag"); | |
GLuint vso = Shader::ShaderUtility::CompileShader(vertexCode.c_str(), GL_VERTEX_SHADER); | |
GLuint fso = Shader::ShaderUtility::CompileShader(fragmentCode.c_str(), GL_FRAGMENT_SHADER); | |
shaderProgram = Shader::ShaderUtility::BuildProgram({ vso, fso }); | |
perspectiveMatrixUniformLocation = glGetUniformLocation(shaderProgram, "perspectiveMatrix"); | |
offsetUniformLocation = glGetUniformLocation(shaderProgram, "cameraOffset"); | |
objectOffsetUniformLocation = glGetUniformLocation(shaderProgram, "objectOffset"); | |
glUseProgram(shaderProgram); | |
glUniformMatrix4fv(perspectiveMatrixUniformLocation, 1, GL_FALSE, perspectiveMatrix); | |
glUniform3f(offsetUniformLocation, camera.x, camera.y, camera.z); | |
glUseProgram(0); | |
glGenBuffers(1, &vbo); | |
glBindBuffer(GL_ARRAY_BUFFER, vbo); | |
glBufferData(GL_ARRAY_BUFFER, sizeof (vertexData), vertexData, GL_STATIC_DRAW); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glGenBuffers(1, &ebo); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); | |
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexData), indexData, GL_STATIC_DRAW); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
glGenVertexArrays(1, &vao1); | |
glGenVertexArrays(1, &vao2); | |
glBindBuffer(GL_ARRAY_BUFFER, vbo); | |
GLuint vertexAttribIndex1 = glGetAttribLocation(shaderProgram, "inputVertex"); | |
GLuint vertexAttribIndex2 = glGetAttribLocation(shaderProgram, "inputColor"); | |
glBindVertexArray(vao1); | |
glBindBuffer(GL_ARRAY_BUFFER, vbo); | |
glEnableVertexAttribArray(vertexAttribIndex1); | |
glEnableVertexAttribArray(vertexAttribIndex2); | |
glVertexAttribPointer(vertexAttribIndex1, 3, GL_FLOAT, GL_FALSE, 0, 0); | |
glVertexAttribPointer(vertexAttribIndex2, 4, GL_FLOAT, GL_FALSE, 0, (void*)432); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); | |
glBindVertexArray(0); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | |
glDisableVertexAttribArray(vertexAttribIndex1); | |
glDisableVertexAttribArray(vertexAttribIndex2); | |
} | |
void Clear() { | |
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
glClearDepth(1.0f); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
} | |
void Update() { | |
if (ifAspect) { | |
perspectiveMatrix[0] = camera.fov / (width / height); | |
perspectiveMatrix[5] = camera.fov; | |
glUseProgram(shaderProgram); | |
glUniformMatrix4fv(perspectiveMatrixUniformLocation, 1, GL_FALSE, perspectiveMatrix); | |
glUseProgram(0); | |
} | |
else { | |
perspectiveMatrix[0] = camera.fov; | |
perspectiveMatrix[5] = camera.fov; | |
glUseProgram(shaderProgram); | |
glUniformMatrix4fv(perspectiveMatrixUniformLocation, 1, GL_FALSE, perspectiveMatrix); | |
glUseProgram(0); | |
} | |
if (ifDepthTest) { | |
glEnable(GL_DEPTH_TEST); | |
glDepthMask(GL_TRUE); | |
glDepthRange(0.0f, 1.0f); | |
glDepthFunc(GL_LEQUAL); | |
} | |
else { glDisable(GL_DEPTH_TEST); } | |
if (ifDepthClamp) | |
glEnable(GL_DEPTH_CLAMP); | |
else | |
glDisable(GL_DEPTH_CLAMP); | |
if (ifBackCull) { | |
glEnable(GL_CULL_FACE); | |
glCullFace(GL_BACK); | |
glFrontFace(GL_CW); | |
} | |
else { glDisable(GL_CULL_FACE); } | |
if (ifFrontCull) { | |
glEnable(GL_CULL_FACE); | |
glCullFace(GL_FRONT); | |
glFrontFace(GL_CW); | |
} | |
else { glDisable(GL_CULL_FACE); } | |
if (ifFrontBackCull) { | |
glEnable(GL_CULL_FACE); | |
glCullFace(GL_FRONT_AND_BACK); | |
glFrontFace(GL_CW); | |
} | |
else { glDisable(GL_CULL_FACE); } | |
glUseProgram(shaderProgram); | |
glUniform3f(offsetUniformLocation, camera.x, camera.y, camera.z); | |
glUseProgram(0); | |
} | |
void Run() { | |
if (!ifInit) { | |
std::cout << "a to activate aspect ratio " << std::endl | |
<< "d for depth testing " << std::endl | |
<< "f for frontface culling " << std::endl | |
<< "b for backface culling" << std::endl | |
<< "n for front and back culling" << std::endl | |
<< "c for depth clamping" << std::endl; | |
std::cout << "camera movement: " << std::endl | |
<< "u forward, h left, k right, j backward, z zoom in, x zoom out, o up, l down" << std::endl; | |
Init(); | |
ifInit = GL_TRUE; | |
} | |
Clear(); | |
Render(); | |
Update(); | |
} | |
void KeyEvent(unsigned char key, int x, int y) { | |
switch (key) { | |
case 'u': | |
camera.z += 0.1; | |
break; | |
case 'h': | |
camera.x += 0.1; | |
break; | |
case 'k': | |
camera.x -= 0.1; | |
break; | |
case 'j': | |
camera.z -= 0.1; | |
break; | |
case 'z': | |
camera.fov += 0.1; | |
break; | |
case 'x': | |
camera.fov -= 0.1; | |
break; | |
case 'o': | |
camera.y -= 0.1; | |
break; | |
case 'l': | |
camera.y += 0.1; | |
break; | |
case 'a': | |
if (!ifAspect) { | |
std::cout << "--> aspect ratio enabled " << std::endl; | |
ifAspect = GL_TRUE; | |
} | |
else { | |
std::cout << "--> aspect ratio disabled " << std::endl; | |
ifAspect = GL_FALSE; | |
} | |
break; | |
case 'd': | |
if (!ifDepthTest) { | |
std::cout << "--> depth test enabled " << std::endl; | |
ifDepthTest = GL_TRUE; | |
} | |
else { | |
std::cout << "--> depth test disabled " << std::endl; | |
ifDepthTest = GL_FALSE; | |
} | |
break; | |
case 'f': | |
if (!ifFrontCull) { | |
std::cout << "--> front face culling enabled " << std::endl; | |
ifFrontCull = GL_TRUE; | |
} | |
else { | |
std::cout << "--> front face culling disabled " << std::endl; | |
ifFrontCull = GL_FALSE; | |
} | |
break; | |
case 'b': | |
if (!ifBackCull) { | |
std::cout << "--> back face culling enabled " << std::endl; | |
ifBackCull = GL_TRUE; | |
} | |
else { | |
std::cout << "--> back face culling disabled " << std::endl; | |
ifBackCull = GL_FALSE; | |
} | |
break; | |
case 'n': | |
if (!ifFrontBackCull) { | |
std::cout << "--> front and back culling enabled " << std::endl; | |
ifFrontBackCull = GL_TRUE; | |
} | |
else { | |
std::cout << "--> front and back culling disabled " << std::endl; | |
ifFrontBackCull = GL_FALSE; | |
} | |
break; | |
case 'c': | |
if (!ifDepthClamp) { | |
std::cout << "--> depth clamping enabled " << std::endl; | |
ifDepthClamp = GL_TRUE; | |
} | |
else { | |
std::cout << "--> depth clamping disabled " << std::endl; | |
ifDepthClamp = GL_FALSE; | |
} | |
break; | |
default: | |
break; | |
} | |
} | |
void Resize(int w, int h) { | |
glViewport(0, 0, w, h); | |
width = w; | |
height = h; | |
} | |
void initWindow(int *const cptr_argn, char **const cptr_argc) { | |
glutInit(cptr_argn, cptr_argc); | |
glutInitContextProfile(GLUT_CORE_PROFILE); | |
glutInitContextVersion(3, 3); | |
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); | |
glutInitWindowPosition(WINDOW_POSX, WINDOW_POSY); | |
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); | |
glutCreateWindow(windowTitle); | |
GLenum initStatus; | |
glewExperimental = GL_TRUE; | |
try { | |
if ( (initStatus = glewInit()) ) { | |
std::cerr << glewGetErrorString(initStatus) << std::endl; | |
throw std::runtime_error((const char *)glewGetErrorString(initStatus)); | |
} | |
std::clog << glGetString(GL_VERSION) << std::endl; | |
} | |
catch (std::runtime_error err) { | |
std::cerr << "attempting to initialize " << std::endl; | |
if ((initStatus = glewInit())) { | |
std::cerr << glewGetErrorString(initStatus) << std::endl; | |
throw std::runtime_error("failed to attemp to intialize the context"); | |
} | |
} | |
glutDisplayFunc(&Run); | |
glutKeyboardFunc(&KeyEvent); | |
glutReshapeFunc(&Resize); | |
glutMainLoop(); | |
} | |
int main(int argn, char **argc) | |
{ | |
initWindow(&argn, argc); | |
return EXIT_SUCCESS; | |
} |
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 | |
in vec4 inputVertex; | |
in vec4 inputColor; | |
uniform mat4 perspectiveMatrix; | |
uniform vec3 cameraOffset; | |
uniform vec3 objectOffset; | |
flat out vec4 outputColor; | |
void main () | |
{ | |
vec4 cameraSpacePosition = inputVertex + vec4(objectOffset.x, objectOffset.y, objectOffset.z, 0.0f); | |
cameraSpacePosition.xyz += cameraOffset.xyz; | |
outputColor = inputColor; | |
gl_Position = perspectiveMatrix * cameraSpacePosition; | |
} |
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_UTILITY_HEADER | |
#define SHADER_UTILITY_HEADER | |
#include <GL/glew.h> | |
#include <GL/freeglut.h> | |
#include <fstream> | |
#include <vector> | |
#include <iostream> | |
#include <initializer_list> | |
#include <string> | |
namespace Shader { | |
class ShaderUtility { | |
public: | |
static std::string LoadShaderFile(const std::string &fileName) { | |
std::fstream streamReader(fileName, std::fstream::in, std::fstream::trunc); | |
std::string sourceCode, line; | |
if (!streamReader) | |
std::cerr << "cannot load file " << fileName << std::endl; | |
for (; std::getline(streamReader, line);) | |
sourceCode += line + '\n'; | |
if (sourceCode[sourceCode.length() - 1] != '\0') | |
sourceCode.push_back('\0'); | |
streamReader.close(); | |
return sourceCode; | |
} | |
static GLuint CompileShader(const char *sourceCode, GLenum shaderType) { | |
GLuint ShaderObject = glCreateShader(shaderType); | |
GLint compileStatus; | |
glShaderSource(ShaderObject, 1, &sourceCode, nullptr); | |
glCompileShader(ShaderObject); | |
glGetShaderiv(ShaderObject, GL_COMPILE_STATUS, &compileStatus); | |
if (!compileStatus) { | |
GLchar *errLog; | |
GLint logLength; | |
glGetShaderiv(ShaderObject, GL_INFO_LOG_LENGTH, &logLength); | |
errLog = new GLchar[logLength + 1]; | |
glGetShaderInfoLog(ShaderObject, logLength + 1, nullptr, errLog); | |
std::cerr << "shader error:: " << ((shaderType == GL_VERTEX_SHADER) ? "vertex " : (shaderType == GL_FRAGMENT_SHADER) ? "fragment " : "none") << std::endl | |
<< errLog << std::endl; | |
delete[]errLog; | |
} | |
return ShaderObject; | |
} | |
static GLuint BuildProgram(std::initializer_list <GLuint> shaderList) { | |
GLuint programObject = glCreateProgram(); | |
GLint linkStatus; | |
for (auto shaderListIt = shaderList.begin(); shaderListIt != shaderList.end(); ++shaderListIt) | |
glAttachShader(programObject, *shaderListIt); | |
glLinkProgram(programObject); | |
glGetProgramiv(programObject, GL_LINK_STATUS, &linkStatus); | |
if (!linkStatus) { | |
GLchar *errLog; | |
GLint logLength; | |
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &logLength); | |
errLog = new GLchar[logLength + 1]; | |
glGetProgramInfoLog(programObject, logLength + 1, nullptr, errLog); | |
std::cerr << "linking error" << std::endl | |
<< errLog << std::endl; | |
delete[]errLog; | |
} | |
for (auto shaderListIt = shaderList.begin(); shaderListIt != shaderList.end(); ++shaderListIt) { | |
glDetachShader(programObject, *shaderListIt); | |
glDeleteShader(*shaderListIt); | |
} | |
return programObject; | |
} | |
}; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment