Skip to content

Instantly share code, notes, and snippets.

@krysseltillada
Created May 12, 2016 05:04
Show Gist options
  • Save krysseltillada/df0179a81c88c9af2fa9a5220abbb60e to your computer and use it in GitHub Desktop.
Save krysseltillada/df0179a81c88c9af2fa9a5220abbb60e to your computer and use it in GitHub Desktop.
ex 14 (depth clamping, clipping)
#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
#version 330
flat in vec4 outputColor;
out vec4 fragmentColor;
void main ()
{
fragmentColor = outputColor;
}
#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;
}
#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;
}
#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