Skip to content

Instantly share code, notes, and snippets.

@krysseltillada
Created March 7, 2016 18:06
Show Gist options
  • Save krysseltillada/a4879ebb5e45618837db to your computer and use it in GitHub Desktop.
Save krysseltillada/a4879ebb5e45618837db to your computer and use it in GitHub Desktop.
exercise 5 (real time fragment color interpolation)
#define GLEW_STATIC
#include "GL/glew.h"
#include "GL/freeglut.h"
#include <iostream>
#include <string>
#include "main.hpp"
static const int windowWidth = 800;
static const int windowHeight = 600;
static const char *windowTitle = "exercise 5";
void InitCoreFunc(int *const argn, char **cargs) {
glutInit(argn, cargs);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitContextVersion(3, 3);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowSize(windowWidth, windowHeight);
glutInitWindowPosition(200, 200);
glutCreateWindow(windowTitle);
if (glewInit())
std::cerr << "cannot init open gl context " << std::endl;
glutDisplayFunc(&Run);
glutReshapeFunc(&Resize);
glutMainLoop();
}
int main(int argn, char **argc)
{
InitCoreFunc(&argn, argc);
return 0;
}
#version 330
out vec4 outputColor;
const vec4 color1 = vec4(1.0f, 1.0f, 1.0f, 1.0f);
const vec4 color2 = vec4(0.0f, 1.0f, 0.0f, 1.0f);
uniform float fragmentDuration;
uniform float time;
void main ()
{
float lerp = abs(sin (time));
outputColor = mix (color1, color2, lerp);
}
#include "main.hpp"
bool ifInit = false;
GLuint vbo;
GLuint programObject;
GLint timeLocation;
GLint circleDurationLocation;
GLint fragmentColorDurationLocation;
GLfloat circleLoopDuration = 3.0f, fragmentColorDuration = 5.0f;
const GLfloat vertexArrayData[] = {
0.1f, 0.0f, 0.0f, 1.0f,
-0.1f, 0.0f, 0.0f, 1.0f,
0.0f, 0.1f, 0.0f, 1.0f,
0.1f, 0.0f, 0.0f, 1.0f,
-0.1f, 0.0f, 0.0f, 1.0f,
0.0f, 0.1f, 0.0f, 1.0f
};
static void InitObject() {
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof (vertexArrayData), vertexArrayData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
std::string sourceCode1 = Shader::LoadShaderFile("vertexShader.vert");
std::string sourceCode2 = Shader::LoadShaderFile("fragmentShader.frag");
GLuint shaderObject;
GLuint fragmentObject;
shaderObject = Shader::CompileShader(GL_VERTEX_SHADER, sourceCode1.c_str());
fragmentObject = Shader::CompileShader(GL_FRAGMENT_SHADER, sourceCode2.c_str());
programObject = Shader::BuildProgram({ shaderObject, fragmentObject });
timeLocation = glGetUniformLocation(programObject, "time");
circleDurationLocation = glGetUniformLocation(programObject, "circleDuration");
fragmentColorDurationLocation = glGetUniformLocation(programObject, "fragmentDuration");
glUseProgram(programObject);
glUniform1f(circleDurationLocation, circleLoopDuration);
glUniform1f(fragmentColorDurationLocation, fragmentColorDuration);
glUniform1f(timeLocation, glutGet(GLUT_ELAPSED_TIME));
glUseProgram(0);
}
static void Render() {
glUseProgram(programObject);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast <void *> (0));
glUniform1f(circleDurationLocation, circleLoopDuration);
glDrawArrays(GL_TRIANGLES, 0, 3);
glUniform1f(circleDurationLocation, (circleLoopDuration / 10.0f) );
glDrawArrays(GL_TRIANGLES, 3, 6);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(0);
glUseProgram(0);
glutSwapBuffers();
glutPostRedisplay();
}
static void Clear() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
static void Update() {
glUseProgram(programObject);
glUniform1f(timeLocation, glutGet(GLUT_ELAPSED_TIME) / 1000.0f);
glUseProgram(0);
}
void Run() {
if (!ifInit) {
InitObject();
ifInit = true;
}
Render();
Update();
Clear();
}
void Resize(int w, int h) {
glViewport(0, 0, w, h);
}
#ifndef MAIN_HEADER
#define MAIN_HEADER
#include "GL/glew.h"
#include "GL/freeglut.h"
#include "Shader.hpp"
static void InitObject();
static void Render();
static void Clear();
static void Update();
void Run();
void Resize(int, int);
#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
#version 330
layout (location = 0) in vec4 vertexPosition;
uniform float time;
uniform float circleDuration;
void main ()
{
float circleLength = 3.14159f * 2.0f/ circleDuration;
float mtime = mod (time, circleDuration);
vec4 offset = vec4 (cos (circleLength * mtime) * 0.5f,
sin (circleLength * mtime) * 0.5f, 0.0f, 0.0f);
gl_Position = vertexPosition + offset;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment