Created
December 14, 2012 20:19
-
-
Save anonymous/4288344 to your computer and use it in GitHub Desktop.
OpenGL example
This file contains 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
add_executable(triangle triangle.cc utility.hh) | |
target_link_libraries(triangle glut GLEW GL) |
This file contains 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
smooth out vec4 color; | |
uniform float loopDuration; | |
uniform float time; | |
uniform float zNear; | |
uniform float zFar; | |
const vec4 red = vec4(1, 0, 0, 1); | |
const vec4 green = vec4(1, 1, 1, 1); | |
float dist(float a, float b) { | |
return abs(a - b); | |
} | |
void main() { | |
float currTime = mod(time, loopDuration); | |
float currLerp = currTime / loopDuration; | |
float lerpValue = dist(gl_FragCoord.z / zFar, 0) ; | |
color = vec4(lerpValue, lerpValue, lerpValue, 1);// mix(red, green, lerpValue); | |
}; |
This file contains 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 <iostream> | |
#include <GL/glew.h> | |
#include <GL/freeglut.h> | |
#include "utility.hh" | |
#include <cstring> | |
GLuint program; | |
GLuint boxVBO; | |
GLuint timeUniformLocation; | |
GLuint perspectiveMatrixUnf; | |
float theMatrix[16]; | |
void init() { | |
GLint compile_ok = false, link_ok = false; | |
program = glCreateProgram(); | |
GLuint vs = CreateShader(program, "vertex.v.glsl"); | |
GLuint fs = CreateShader(program, "fragment.f.glsl"); | |
glLinkProgram(program); | |
glGetProgramiv(program, GL_LINK_STATUS, &link_ok); | |
if (!link_ok) { | |
print_log(program); | |
std::cerr << "Program linking error" << std::endl; | |
exit(0); | |
} | |
GLuint loopDurationUnf = glGetUniformLocation(program, "loopDuration"); | |
perspectiveMatrixUnf = glGetUniformLocation(program, "perspectiveMatrix"); | |
GLuint frustumScaleUnf = glGetUniformLocation(program, "frustumScale"); | |
GLuint zNearUnf = glGetUniformLocation(program, "zNear"); | |
GLuint zFarUnf = glGetUniformLocation(program, "zFar"); | |
timeUniformLocation = glGetUniformLocation(program, "time"); | |
glUseProgram(program); | |
glUniform1f(loopDurationUnf, 5); | |
glUniform1f(frustumScaleUnf, 1); | |
glUniform1f(zNearUnf, 1); | |
glUniform1f(zFarUnf, 4); | |
glUseProgram(0); | |
glDeleteShader(vs); | |
glDeleteShader(fs); | |
float fzNear = 1; | |
float fzFar = 4; | |
memset(theMatrix, 0, sizeof(float) * 16); | |
theMatrix[0] = 1; | |
theMatrix[5] = 1; | |
theMatrix[10] = (fzFar + fzNear) / (fzNear - fzFar); | |
theMatrix[14] = (2 * fzFar * fzNear) / (fzNear - fzFar); | |
theMatrix[11] = -1.0f; | |
glUseProgram(program); | |
glUniformMatrix4fv(perspectiveMatrixUnf, 1, GL_FALSE, theMatrix); | |
glUseProgram(0); | |
GLfloat r = 0.1, n = -2; | |
GLfloat box_vertices[] = { | |
-r,r,n,0, | |
r,r,n,0, | |
r,-r,n,0, | |
-r,-r,n,0, | |
r,r,n,0, | |
r,r,n-2,0, | |
r,-r,n-2,0, | |
r,-r,n-0,0, | |
r,r,n-2,0, | |
-r,r,n-2,0, | |
-r,-r,n-2,0, | |
r,-r,n-2,0, | |
-r,r,n-2,0, | |
-r,r,n,0, | |
-r,-r,n,0, | |
-r,-r,n-2,0, | |
-r,r,n-2,0, | |
r,r,n-2,0, | |
r,r,n,0, | |
-r,r,n,0, | |
-r,-r,n,0, | |
-r,-r,n-2,0, | |
r,-r,n-2,0, | |
r,-r,n,0 | |
}; | |
boxVBO = CreateVertexBuffer(box_vertices, sizeof(box_vertices)); | |
std::cout << box_vertices[93] << std::endl; | |
GLuint vao; | |
glGenVertexArrays(1, &vao); | |
glBindVertexArray(vao); | |
glEnable(GL_CULL_FACE); | |
glCullFace(GL_BACK); | |
glFrontFace(GL_CW); | |
} | |
void reshape (int w, int h) | |
{ | |
theMatrix[0] = 1 / (w / (float)h); | |
theMatrix[5] = 1; | |
glUseProgram(program); | |
glUniformMatrix4fv(perspectiveMatrixUnf, 1, GL_FALSE, theMatrix); | |
glUseProgram(0); | |
glViewport(0, 0, (GLsizei) w, (GLsizei) h); | |
} | |
void display() { | |
glClearColor(0.3, 0.3, 0.3, 0); | |
glClear(GL_COLOR_BUFFER_BIT); | |
glUseProgram(program); | |
// provide time for shaders | |
glUniform1f(timeUniformLocation, glutGet(GLUT_ELAPSED_TIME)/1000.f); | |
glBindBuffer(GL_ARRAY_BUFFER, boxVBO); | |
glEnableVertexAttribArray(0); | |
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); | |
glDrawArrays(GL_QUADS, 0, 96); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glDisableVertexAttribArray(0); | |
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (void*)0); | |
glDrawArrays(GL_TRIANGLES, 0, 36); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glDisableVertexAttribArray(0); | |
glUseProgram(0); | |
glutSwapBuffers(); | |
glutPostRedisplay(); | |
} | |
void NormalKeyboardEvent(unsigned char key, int x, int y) { | |
if (key == 27) | |
glutLeaveMainLoop(); | |
} | |
void free_resources() { | |
glDeleteProgram(program); | |
} | |
int main(int argc, char** argv) { | |
glutInit(&argc, argv); | |
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); | |
glutInitWindowSize(400, 400); | |
glutCreateWindow("My triangle"); | |
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); | |
GLenum glew_status = glewInit(); | |
if (glew_status != GLEW_OK) { | |
std::cerr << "Error: " << glewGetErrorString(glew_status) << std::endl; | |
return 1; | |
} | |
init(); | |
glutDisplayFunc(display); | |
glutKeyboardFunc(NormalKeyboardEvent); | |
glutReshapeFunc(reshape); | |
glutMainLoop(); | |
free_resources(); | |
return 0; | |
} |
This file contains 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 <fstream> | |
#include <sstream> | |
#include <string> | |
#include <cmath> | |
std::string ReadFile(std::string name) { | |
std::stringstream contents; | |
std::ifstream file(name.c_str()); | |
if (file.is_open()) { | |
std::string line; | |
while (file.good()) { | |
getline(file, line); | |
contents << line << std::endl; | |
} | |
file.close(); | |
} | |
return contents.str(); | |
} | |
void print_log(GLuint object) | |
{ | |
GLint log_length = 0; | |
if (glIsShader(object)) | |
glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length); | |
else if (glIsProgram(object)) | |
glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length); | |
else { | |
std::cerr << "printlog: Not a shader or a program" << std::endl; | |
return; | |
} | |
char* log = new char[log_length]; | |
if (glIsShader(object)) | |
glGetShaderInfoLog(object, log_length, NULL, log); | |
else if (glIsProgram(object)) | |
glGetProgramInfoLog(object, log_length, NULL, log); | |
std::cerr << log << std::endl; | |
delete log; | |
} | |
GLuint CreateShader(GLuint program, std::string filename) | |
{ | |
GLenum type; | |
std::string ending = filename.substr(filename.size()-7, filename.size()); | |
if (ending == ".v.glsl") | |
type = GL_VERTEX_SHADER; | |
else if (ending == ".f.glsl") | |
type = GL_FRAGMENT_SHADER; | |
std::string bare_source = ReadFile(filename); | |
if (bare_source.empty()) { | |
std::cerr << "Error opening " << filename << std::endl; | |
return 0; | |
} | |
GLuint shader = glCreateShader(type); | |
const char *full_source[2] = { | |
"#version 330\n", | |
bare_source.c_str() | |
}; | |
glShaderSource(shader, 2, full_source, NULL); | |
glCompileShader(shader); | |
GLint compile_ok = GL_FALSE; | |
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_ok); | |
if (compile_ok == GL_FALSE) { | |
std::cerr << filename << ":"; | |
print_log(shader); | |
glDeleteShader(shader); | |
return 0; | |
} | |
glAttachShader(program, shader); | |
return shader; | |
} | |
template <typename T> | |
GLuint CreateVertexBuffer(T data[], GLsizeiptr size) { | |
GLuint position; | |
glGenBuffers(1, &position); | |
glBindBuffer(GL_ARRAY_BUFFER, position); | |
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
return position; | |
} | |
void ComputePositionOffset(float &x, float &y) { | |
const float loopDuration = 5.0f; | |
const float scale = 3.14159f * 2.0f / loopDuration; | |
float elapsedTime = glutGet(GLUT_ELAPSED_TIME) / 1000.0f; | |
float currentTimeThroughLoop = fmodf(elapsedTime, loopDuration); | |
x = cosf(currentTimeThroughLoop * scale) * 0.5f; | |
y = sinf(currentTimeThroughLoop * scale) * 0.5f; | |
} |
This file contains 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
layout(location = 0) in vec4 position; | |
uniform float loopDuration; | |
uniform float time; | |
uniform float zNear; | |
uniform float zFar; | |
uniform float frustumScale; | |
void main() { | |
float timeScale = 3.14159f * 2.0f / loopDuration; | |
float currTime = mod(time, loopDuration); | |
vec4 offset = vec4( | |
sin(currTime * timeScale), | |
cos(currTime * timeScale), | |
0, 0 | |
); | |
vec4 cameraPos = position + vec4(offset.x, offset.y, 0.0, 0.0); | |
vec4 clipPos; | |
clipPos.xy = cameraPos.xy * frustumScale; | |
clipPos.z = cameraPos.z * (zNear + zFar) / (zNear - zFar); | |
clipPos.z += 2 * zNear * zFar / (zNear - zFar); | |
clipPos.w = -cameraPos.z; | |
gl_Position = clipPos; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment