Created
December 30, 2018 17:11
-
-
Save amoshyc/f5d6be225b284c07ce6b2e914889a771 to your computer and use it in GitHub Desktop.
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 "../Externals/Include/Include.h" | |
#include "Object.hpp" | |
#define sz(x) (int(x.size())) | |
using namespace glm; | |
using namespace std; | |
#define SHADOW_MAP_SIZE 2048 | |
Object quad; | |
Object suit; | |
vec3 light_pos = vec3(-31.75, 26.05, -97.72); | |
void My_Reshape(int width, int height); | |
static const GLfloat window_positions[] = { | |
1.0f, -1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, | |
-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f}; | |
struct { | |
struct { | |
mat4 view; | |
mat4 proj; | |
} eye; | |
} matrices; | |
struct { | |
struct { | |
GLint mvp; | |
} light; | |
struct { | |
GLuint shadow_tex; | |
GLuint skybox_tex; | |
GLint mv_matrix; | |
GLint proj_matrix; | |
GLint shadow_matrix; | |
GLint light_pos; | |
GLint is_quad; | |
GLint shadow; | |
} view; | |
struct { | |
GLuint view; | |
GLuint proj; | |
} skybox; | |
struct { | |
GLuint mode; | |
GLuint tex[3]; | |
} fuse; | |
} uniforms; | |
struct { | |
GLuint fbo; | |
GLuint depthMap; | |
} shadowBuffer; | |
struct { | |
int width = 1440 * 2 / 3; | |
int height = 900 * 2 / 3; | |
} viewportSize; | |
struct { | |
GLuint vao; | |
GLuint vbo; | |
GLuint tex; | |
} skybox; | |
struct { | |
int mode = 0; | |
GLuint vao; | |
GLuint vbo; | |
GLuint fbo[3]; | |
GLuint rbo[3]; | |
GLuint tex[3]; | |
} fuse; | |
GLuint depthProg; | |
GLuint blinnPhongProg; | |
GLuint skyboxProg; | |
GLuint fuseProg; | |
float skyboxVertices[] = { | |
-1.0f, +1.0f, -1.0f, -1.0f, -1.0f, -1.0f, +1.0f, -1.0f, -1.0f, | |
+1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, -1.0f, +1.0f, -1.0f, | |
-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, -1.0f, -1.0f, +1.0f, -1.0f, | |
-1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, -1.0f, +1.0f, | |
+1.0f, -1.0f, -1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, +1.0f, | |
+1.0f, +1.0f, +1.0f, +1.0f, +1.0f, -1.0f, +1.0f, -1.0f, -1.0f, | |
-1.0f, -1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, | |
+1.0f, +1.0f, +1.0f, +1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, | |
-1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, | |
+1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, -1.0f, | |
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, -1.0f, | |
+1.0f, -1.0f, -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f}; | |
GLuint createProgram(string name) { | |
auto vs_path = "shaders/" + name + ".vs.glsl"; | |
auto fs_path = "shaders/" + name + ".fs.glsl"; | |
auto program = glCreateProgram(); | |
auto vs_shader = glCreateShader(GL_VERTEX_SHADER); | |
auto fs_shader = glCreateShader(GL_FRAGMENT_SHADER); | |
char **vs_source = loadShaderSource(vs_path.c_str()); | |
char **fs_source = loadShaderSource(fs_path.c_str()); | |
glShaderSource(vs_shader, 1, vs_source, NULL); | |
glShaderSource(fs_shader, 1, fs_source, NULL); | |
freeShaderSource(vs_source); | |
freeShaderSource(fs_source); | |
cout << "Compiling " << vs_path << endl; | |
glCompileShader(vs_shader); | |
shaderLog(vs_shader); | |
cout << "Compiling " << fs_path << endl; | |
glCompileShader(fs_shader); | |
shaderLog(fs_shader); | |
glAttachShader(program, vs_shader); | |
glAttachShader(program, fs_shader); | |
glLinkProgram(program); | |
return program; | |
} | |
void My_Init() { | |
glEnable(GL_DEPTH_TEST); | |
glDepthFunc(GL_LEQUAL); | |
glEnable(GL_STENCIL_TEST); | |
depthProg = createProgram("shadow"); | |
uniforms.light.mvp = glGetUniformLocation(depthProg, "mvp"); | |
// ----- End Initialize Depth Shader Program ----- | |
skyboxProg = createProgram("skybox"); | |
uniforms.skybox.proj = glGetUniformLocation(skyboxProg, "proj"); | |
uniforms.skybox.view = glGetUniformLocation(skyboxProg, "view"); | |
// ----- Begin Initialize Blinn-Phong Shader Program ----- | |
blinnPhongProg = createProgram("blinnphong"); | |
uniforms.view.proj_matrix = | |
glGetUniformLocation(blinnPhongProg, "proj_matrix"); | |
uniforms.view.mv_matrix = glGetUniformLocation(blinnPhongProg, "mv_matrix"); | |
uniforms.view.shadow_matrix = | |
glGetUniformLocation(blinnPhongProg, "shadow_matrix"); | |
uniforms.view.shadow_tex = | |
glGetUniformLocation(blinnPhongProg, "shadow_tex"); | |
uniforms.view.skybox_tex = | |
glGetUniformLocation(blinnPhongProg, "skybox_tex"); | |
uniforms.view.light_pos = glGetUniformLocation(blinnPhongProg, "light_pos"); | |
uniforms.view.is_quad = glGetUniformLocation(blinnPhongProg, "is_quad"); | |
uniforms.view.shadow = glGetUniformLocation(blinnPhongProg, "shadow"); | |
// ----- End Initialize Blinn-Phong Shader Program ----- | |
fuseProg = createProgram("fuse"); | |
uniforms.fuse.tex[0] = glGetUniformLocation(fuseProg, "tex0"); | |
uniforms.fuse.tex[1] = glGetUniformLocation(fuseProg, "tex1"); | |
uniforms.fuse.tex[2] = glGetUniformLocation(fuseProg, "tex2"); | |
uniforms.fuse.mode = glGetUniformLocation(fuseProg, "mode"); | |
quad = Object("quad.obj"); | |
quad.model = mat4(); | |
quad.model = translate(quad.model, vec3(-10, -13, -8)); | |
quad.model = translate(quad.model, vec3(+3, 0, +8)); | |
quad.model = scale(quad.model, vec3(1.1, 1, 1.5)); | |
suit = Object("nanosuit.obj"); | |
suit.model = mat4(); | |
suit.model = translate(suit.model, vec3(-10, -13, -8)); | |
suit.model = scale(suit.model, vec3(0.5, 0.35, 0.5)); | |
// Skybox | |
cout << "Loading Skybox" << endl; | |
vector<string> filenames = {"right.jpg", "left.jpg", "top.jpg", | |
"bottom.jpg", "front.jpg", "back.jpg"}; | |
glGenTextures(1, &skybox.tex); | |
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox.tex); | |
for (int i = 0; i < 6; i++) { | |
auto name = filenames[i]; | |
auto path = "boxes/" + name; | |
int w, h, c; | |
unsigned char *data = stbi_load(path.c_str(), &w, &h, &c, 0); | |
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, | |
GL_RGB, GL_UNSIGNED_BYTE, data); | |
stbi_image_free(data); | |
cout << "\t" << name << ": " << w << ", " << h << endl; | |
} | |
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); | |
glGenVertexArrays(1, &skybox.vao); | |
glBindVertexArray(skybox.vao); | |
glGenBuffers(1, &skybox.vbo); | |
glBindBuffer(GL_ARRAY_BUFFER, skybox.vbo); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, | |
GL_STATIC_DRAW); | |
glEnableVertexAttribArray(0); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); | |
// ----- Begin Initialize Shadow Framebuffer Object ----- | |
glGenFramebuffers(1, &shadowBuffer.fbo); | |
glBindFramebuffer(GL_FRAMEBUFFER, shadowBuffer.fbo); | |
glGenTextures(1, &shadowBuffer.depthMap); | |
glBindTexture(GL_TEXTURE_2D, shadowBuffer.depthMap); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, SHADOW_MAP_SIZE, | |
SHADOW_MAP_SIZE, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, | |
GL_COMPARE_REF_TO_TEXTURE); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); | |
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, | |
shadowBuffer.depthMap, 0); | |
// ----- End Initialize Shadow Framebuffer Object ----- | |
glGenVertexArrays(1, &fuse.vao); | |
glBindVertexArray(fuse.vao); | |
glGenBuffers(1, &fuse.vbo); | |
glBindBuffer(GL_ARRAY_BUFFER, fuse.vbo); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(window_positions), window_positions, | |
GL_STATIC_DRAW); | |
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT) * 4, 0); | |
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT) * 4, | |
(const GLvoid *)(sizeof(GL_FLOAT) * 2)); | |
glEnableVertexAttribArray(0); | |
glEnableVertexAttribArray(1); | |
glGenFramebuffers(1, &fuse.fbo[0]); | |
glGenFramebuffers(1, &fuse.fbo[1]); | |
glGenFramebuffers(1, &fuse.fbo[2]); | |
My_Reshape(viewportSize.width, viewportSize.height); | |
} | |
void renderShadow(const mat4 &light_vp_matrix) { | |
glBindFramebuffer(GL_FRAMEBUFFER, shadowBuffer.fbo); | |
glClear(GL_DEPTH_BUFFER_BIT); | |
glViewport(0, 0, SHADOW_MAP_SIZE, SHADOW_MAP_SIZE); | |
glUseProgram(depthProg); | |
glEnable(GL_POLYGON_OFFSET_FILL); | |
glPolygonOffset(4.0f, 4.0f); | |
glUniformMatrix4fv(uniforms.light.mvp, 1, GL_FALSE, | |
value_ptr(light_vp_matrix * quad.model)); | |
quad.render(); | |
glUniformMatrix4fv(uniforms.light.mvp, 1, GL_FALSE, | |
value_ptr(light_vp_matrix * suit.model)); | |
suit.render(); | |
glDisable(GL_POLYGON_OFFSET_FILL); | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glViewport(0, 0, viewportSize.width, viewportSize.height); | |
} | |
void renderObject(const mat4 &shadow_sbpv_matrix, bool shadow, bool draw_quad, | |
bool draw_suit) { | |
glUseProgram(blinnPhongProg); | |
glUniform1i(uniforms.view.shadow, int(shadow)); | |
glUniformMatrix4fv(uniforms.view.proj_matrix, 1, GL_FALSE, | |
value_ptr(matrices.eye.proj)); | |
glUniformMatrix4fv(uniforms.view.light_pos, 1, GL_FALSE, | |
value_ptr(light_pos)); | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_2D, shadowBuffer.depthMap); | |
glUniform1i(uniforms.view.shadow_tex, 0); | |
glActiveTexture(GL_TEXTURE1); | |
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox.tex); | |
glUniform1i(uniforms.view.skybox_tex, 1); | |
if (draw_quad) { | |
mat4 quad_mv = matrices.eye.view * quad.model; | |
mat4 shadow_matrix = shadow_sbpv_matrix * quad.model; | |
glUniform1i(uniforms.view.is_quad, 1); | |
glUniformMatrix4fv(uniforms.view.mv_matrix, 1, GL_FALSE, | |
value_ptr(quad_mv)); | |
glUniformMatrix4fv(uniforms.view.shadow_matrix, 1, GL_FALSE, | |
value_ptr(shadow_matrix)); | |
quad.render(); | |
} | |
if (draw_suit) { | |
mat4 suit_mv = matrices.eye.view * suit.model; | |
mat4 shadow_matrix = shadow_sbpv_matrix * suit.model; | |
glUniform1i(uniforms.view.is_quad, 0); | |
glUniformMatrix4fv(uniforms.view.mv_matrix, 1, GL_FALSE, | |
value_ptr(suit_mv)); | |
glUniformMatrix4fv(uniforms.view.shadow_matrix, 1, GL_FALSE, | |
value_ptr(shadow_matrix)); | |
suit.render(); | |
} | |
} | |
void renderSkybox() { | |
glUseProgram(skyboxProg); | |
mat4 view = mat4(mat3(matrices.eye.view)); | |
mat4 proj = matrices.eye.proj; | |
glUniformMatrix4fv(uniforms.skybox.view, 1, GL_FALSE, value_ptr(view)); | |
glUniformMatrix4fv(uniforms.skybox.proj, 1, GL_FALSE, value_ptr(proj)); | |
glBindVertexArray(skybox.vao); | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox.tex); | |
glDrawArrays(GL_TRIANGLES, 0, 36); | |
} | |
void My_Display() { | |
static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 1.0f}; | |
static const GLfloat zero = 1.0f; | |
mat4 scale_bias_matrix = translate(mat4(), vec3(0.5f, 0.5f, 0.5f)) * | |
scale(mat4(), vec3(0.5f, 0.5f, 0.5f)); | |
const float shadow_range = 15.0f; | |
mat4 light_proj_matrix = ortho(-shadow_range, shadow_range, -shadow_range, | |
shadow_range, 0.0f, 500.0f); | |
mat4 light_view_matrix = | |
lookAt(light_pos, vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f)); | |
mat4 light_vp_matrix = light_proj_matrix * light_view_matrix; | |
mat4 shadow_sbpv_matrix = scale_bias_matrix * light_vp_matrix; | |
{ // stage 1 | |
renderShadow(light_vp_matrix); | |
glBindFramebuffer(GL_FRAMEBUFFER, fuse.fbo[0]); | |
glDrawBuffer(GL_COLOR_ATTACHMENT0); | |
glEnable(GL_DEPTH_TEST); | |
glEnable(GL_STENCIL_TEST); | |
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); | |
glStencilFunc(GL_ALWAYS, 1, 0xFF); | |
glStencilMask(0xFF); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | | |
GL_STENCIL_BUFFER_BIT); | |
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); | |
glDisable(GL_DEPTH_TEST); | |
renderObject(shadow_sbpv_matrix, false, false, true); // suit | |
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
glEnable(GL_DEPTH_TEST); | |
glStencilFunc(GL_NOTEQUAL, 1, 0xFF); | |
glStencilMask(0x00); | |
renderObject(shadow_sbpv_matrix, true, true, false); // quad | |
glStencilMask(0xFF); | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
} | |
{ // stage 2 | |
glBindFramebuffer(GL_FRAMEBUFFER, fuse.fbo[1]); | |
glDrawBuffer(GL_COLOR_ATTACHMENT0); | |
glEnable(GL_DEPTH_TEST); | |
glEnable(GL_STENCIL_TEST); | |
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); | |
glStencilFunc(GL_ALWAYS, 1, 0xFF); | |
glStencilMask(0xFF); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | | |
GL_STENCIL_BUFFER_BIT); | |
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); | |
glDisable(GL_DEPTH_TEST); | |
renderObject(shadow_sbpv_matrix, false, false, true); // suit | |
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
glEnable(GL_DEPTH_TEST); | |
glStencilFunc(GL_NOTEQUAL, 1, 0xFF); | |
glStencilMask(0x00); | |
renderObject(shadow_sbpv_matrix, false, true, true); // quad | |
glStencilMask(0xFF); | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
} | |
{ // stage 3 | |
glBindFramebuffer(GL_FRAMEBUFFER, fuse.fbo[2]); | |
glDrawBuffer(GL_COLOR_ATTACHMENT0); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | | |
GL_STENCIL_BUFFER_BIT); | |
renderObject(shadow_sbpv_matrix, false, false, true); | |
renderSkybox(); | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
} | |
glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
glUseProgram(fuseProg); | |
glUniform1i(uniforms.fuse.mode, fuse.mode); | |
glBindVertexArray(fuse.vao); | |
glActiveTexture(GL_TEXTURE0); | |
glBindTexture(GL_TEXTURE_2D, fuse.tex[0]); | |
glUniform1i(uniforms.fuse.tex[0], 0); | |
glActiveTexture(GL_TEXTURE1); | |
glBindTexture(GL_TEXTURE_2D, fuse.tex[1]); | |
glUniform1i(uniforms.fuse.tex[1], 1); | |
glActiveTexture(GL_TEXTURE2); | |
glBindTexture(GL_TEXTURE_2D, fuse.tex[2]); | |
glUniform1i(uniforms.fuse.tex[2], 2); | |
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | |
glutSwapBuffers(); | |
} | |
void My_Reshape(int width, int height) { | |
viewportSize.width = width; | |
viewportSize.height = height; | |
float viewportAspect = (float)width / (float)height; | |
matrices.eye.proj = | |
perspective(radians(80.0f), viewportAspect, 0.1f, 1000.0f); | |
matrices.eye.view = lookAt(vec3(0.0f, 0.0f, 0.0f), vec3(-1.0f, -1.0f, 0.0f), | |
vec3(0.0f, 1.0f, 0.0f)); | |
// If the windows is reshaped, we need to reset some settings of framebuffer | |
for (int i = 0; i < 3; i++) { | |
glDeleteRenderbuffers(1, &fuse.rbo[i]); | |
glDeleteTextures(1, &fuse.tex[i]); | |
glGenRenderbuffers(1, &fuse.rbo[i]); | |
glBindRenderbuffer(GL_RENDERBUFFER, fuse.rbo[i]); | |
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, | |
height); | |
glGenTextures(1, &fuse.tex[i]); | |
glBindTexture(GL_TEXTURE_2D, fuse.tex[i]); | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, | |
GL_UNSIGNED_BYTE, NULL); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fuse.fbo[i]); | |
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, | |
GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, | |
fuse.rbo[i]); | |
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
GL_TEXTURE_2D, fuse.tex[i], 0); | |
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) | |
cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl; | |
} | |
glutPostRedisplay(); | |
} | |
void My_Keyboard(unsigned char key, int x, int y) { | |
if (key == 'i') { | |
fuse.mode = (fuse.mode + 1) % 4; | |
cout << "Mode: " << fuse.mode << endl; | |
} | |
if (key == 'q') { | |
suit.model = rotate(suit.model, radians(10.0f), vec3(0, 1, 0)); | |
} | |
if (key == 'e') { | |
suit.model = rotate(suit.model, radians(-10.0f), vec3(0, 1, 0)); | |
} | |
glutPostRedisplay(); | |
} | |
void My_Timer(int val) { | |
glutPostRedisplay(); | |
glutTimerFunc(16, My_Timer, val); | |
} | |
int main(int argc, char *argv[]) { | |
// Initialize GLUT and GLEW, then create a window. | |
//////////////////// | |
glutInit(&argc, argv); | |
#ifdef _MSC_VER | |
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); | |
#else | |
glutInitDisplayMode(GLUT_3_2_CORE_PROFILE | GLUT_RGBA | GLUT_DOUBLE | | |
GLUT_DEPTH); | |
#endif | |
glutInitWindowPosition(100, 100); | |
glutInitWindowSize(1440 * 2 / 3, 900 * 2 / 3); | |
glutCreateWindow(__FILENAME__); // You cannot use OpenGL functions before | |
// this line; The OpenGL context must be | |
// created first by glutCreateWindow()! | |
#ifdef _MSC_VER | |
glewInit(); | |
#endif | |
dumpInfo(); | |
My_Init(); | |
//////////////////// | |
// Register GLUT callback functions. | |
/////////////////////////////// | |
glutDisplayFunc(My_Display); | |
glutReshapeFunc(My_Reshape); | |
glutKeyboardFunc(My_Keyboard); | |
glutTimerFunc(16, My_Timer, 0); | |
/////////////////////////////// | |
// Enter main event loop. | |
////////////// | |
glutMainLoop(); | |
////////////// | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment