Skip to content

Instantly share code, notes, and snippets.

@krysseltillada
Created March 4, 2016 18:57
Show Gist options
  • Save krysseltillada/363b249fae6953a89530 to your computer and use it in GitHub Desktop.
Save krysseltillada/363b249fae6953a89530 to your computer and use it in GitHub Desktop.
exercise 4 (offset vertex position using uniforms)
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <iostream>
#include <cstdlib>
#include "main.hpp"
const int windowWidth = 800;
const int windowHeight = 600;
const int windowX = 200;
const int windowY = 300;
const char *WindowName = "Exercise 4";
void initCoreFunc(int *const c_ptrN, char **const c_ptrC) {
glutInit(c_ptrN, c_ptrC);
glutInitContextVersion(3, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(windowWidth, windowHeight);
glutInitWindowPosition(windowX, windowY);
glutCreateWindow(WindowName);
glewExperimental = GL_TRUE;
if (glewInit())
std::cerr << "cannot init context " << std::endl;
glutDisplayFunc(&Run);
glutMainLoop();
}
int main(int argn, char **argc)
{
initCoreFunc(&argn, argc);
std::cout << "hello world" << std::endl;
std::cin.get();
return 0;
}
#version 330
out vec4 fragmentColor;
smooth in vec4 outputVertexColor;
void main ()
{
fragmentColor = outputVertexColor;
}
#include "main.hpp"
bool ifInit = false;
static GLuint BuildShader(std::initializer_list <std::string> shaderFileNameList) {
std::vector < std::pair <std::string, GLenum> > shaderCodeType;
std::vector < GLuint > shaderObjects;
GLuint programObject;
for (std::initializer_list <std::string>::iterator it = shaderFileNameList.begin();
it != shaderFileNameList.end(); ++it) {
std::string fileName = *it;
unsigned int count = 0;
for (int charCount = 0; charCount != fileName.length(); ++charCount) {
if (fileName.substr(count + 1) == "vert") {
shaderCodeType.push_back(std::make_pair(LoadShaderFile(fileName), GL_VERTEX_SHADER));
break;
}
else if (fileName.substr(count + 1) == "frag") {
shaderCodeType.push_back(std::make_pair(LoadShaderFile(fileName), GL_FRAGMENT_SHADER));
break;
}
else { ++count; }
}
}
for (std::vector < std::pair < std::string, GLenum> >::const_iterator cit = shaderCodeType.cbegin();
cit != shaderCodeType.cend(); ++cit) {
shaderObjects.push_back(CompileShader(cit->second, cit->first.c_str()));
std::cout << cit->first << std::endl;
}
programObject = BuildProgram(shaderObjects);
for (std::vector <GLuint>::const_iterator cit = shaderObjects.cbegin();
cit != shaderObjects.cend(); ++cit)
glDeleteShader(*cit);
return programObject;
}
static std::string LoadShaderFile(const std::string &fileName) {
std::fstream readFile(fileName, std::fstream::in);
std::string line, srcCode;
if (!readFile)
std::cerr << "error reading shader File " << fileName << std::endl;
for (; std::getline(readFile, line);)
srcCode += line + "\n";
if (srcCode[srcCode.length() - 1] != '\0')
srcCode.push_back('\0');
return srcCode;
}
static GLuint CompileShader(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> errorLog(new GLchar[logLength + 1]);
glGetShaderInfoLog(shaderObject, logLength + 1, nullptr, errorLog.get());
std::cerr << "error " << ((shaderType == GL_VERTEX_SHADER) ? "vertex" :
(shaderType == GL_FRAGMENT_SHADER) ? "fragment" : "none") << " shader" << std::endl
<< errorLog.get() << std::endl;
}
return shaderObject;
}
static GLuint BuildProgram(std::vector < GLuint > shaderObjectList) {
GLuint programObject = glCreateProgram();
GLint LinkStatus;
for (int shaderCount = 0; shaderCount != shaderObjectList.size(); ++shaderCount)
glAttachShader(programObject, shaderObjectList[shaderCount]);
glLinkProgram(programObject);
glGetProgramiv(programObject, GL_LINK_STATUS, &LinkStatus);
if (!LinkStatus) {
GLint logLength;
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &logLength);
std::unique_ptr <GLchar> errorLog(new GLchar[logLength + 1]);
glGetProgramInfoLog(programObject, logLength + 1, nullptr, errorLog.get());
std::cerr << "LINKING ERROR " << std::endl
<< errorLog.get() << std::endl;
}
for (int shaderCount = 0; shaderCount != shaderObjectList.size(); ++shaderCount)
glDetachShader(programObject, shaderObjectList[shaderCount]);
return programObject;
}
const GLfloat vertexArrayData[] = {
-0.2f, -0.2f, 0.0f, 1.0f,
0.2f, -0.2f, 0.0f, 1.0f,
0.2f, 0.2f, 0.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
};
GLuint programObject;
GLuint vertexBufferObject;
GLint timeLocation;
GLint DurationLocation;
GLfloat circleDuration = 2.0f;
GLfloat xOff = 0.0f, yOff = 0.0f;
static void InitObject() {
programObject = BuildShader({ "vertexShader.vert", "fragmentShader.frag" });
glGenBuffers(1, &vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof (vertexArrayData), vertexArrayData, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
timeLocation = glGetUniformLocation(programObject, "deltaTime");
DurationLocation = glGetUniformLocation(programObject, "circleDuration");
}
static void circularOffset(float &xOffset, float &yOffset) {
const float circleDuration = 5.0f;
const float angleLength = 3.14159f * 2.0f / circleDuration;
const float deltaRatio = fmodf(glutGet(GLUT_ELAPSED_TIME) / 1000.0f, circleDuration);
xOffset = cosf(angleLength * deltaRatio) * 0.5f;
yOffset = sinf(angleLength * deltaRatio) * 0.5f;
}
void Update() {
glUseProgram(programObject);
glUniform1f(DurationLocation, circleDuration);
glUniform1f(timeLocation, glutGet(GLUT_ELAPSED_TIME));
glUseProgram(0);
}
void Run() {
if (!ifInit) {
InitObject();
ifInit = true;
}
Update();
Render();
Clear();
}
void Render() {
glUseProgram(programObject);
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 *> (48));
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
glutSwapBuffers();
glutPostRedisplay();
}
void Clear() {
glClearColor(0 / 255.0f, 162 / 255.0f, 232 / 255.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
#ifndef MAIN_HPP
#define MAIN_HPP
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <vector>
#include <utility>
#include <memory>
#include <iostream>
#include <fstream>
#include <string>
#include <initializer_list>
static GLuint BuildShader(std::initializer_list <std::string>);
static std::string LoadShaderFile(const std::string &);
static GLuint CompileShader(GLenum , const char *);
static GLuint BuildProgram(std::vector <GLuint> );
static void InitObject();
static void circlularOffset(float &, float &);
static void Update();
void WindowResize(int, int, int, int);
void Run();
void Render();
void Clear();
#endif
#version 330
layout (location = 0) in vec4 inputVertexPosition;
layout (location = 1) in vec4 inputVertexColor;
smooth out vec4 outputVertexColor;
uniform float deltaTime;
uniform float circleDuration;
void main ()
{
float circleLength = 3.14159f * 2.0f / circleDuration;
float mDelta = mod(deltaTime / 1000.0f, circleDuration);
vec4 finalOffset = vec4 (cos (mDelta * circleLength) * 0.2f,
sin (mDelta * circleLength) * 0.2f, 0.0f, 0.0f);
gl_Position = inputVertexPosition + finalOffset;
outputVertexColor = inputVertexColor;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment