그래픽스) opengv 공부용
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "Shaders/LoadShaders.h"
GLuint h_ShaderProgram; // handle to shader program
GLint loc_ModelViewProjectionMatrix, loc_primitive_color; // indices of uniform variables
// include glm/*.hpp only if necessary
//#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> //translate, rotate, scale, ortho, etc.
glm::mat4 ModelViewProjectionMatrix;
glm::mat4 ViewMatrix, ProjectionMatrix, ViewProjectionMatrix;
#define TO_RADIAN 0.01745329252f
#define TO_DEGREE 57.295779513f
#define BUFFER_OFFSET(offset) ((GLvoid *) (offset))
#define LOC_VERTEX 0
int win_width = 0, win_height = 0;
float centerx = 0.0f, centery = 0.0f, rotate_angle = 0.0f;
GLfloat axes[4][2];
GLfloat axes_color[3] = { 0.0f, 0.0f, 0.0f };
GLuint VBO_axes, VAO_axes;
void prepare_axes(void) { // Draw axes in their MC.
axes[0][0] = -win_width / 2.5f; axes[0][1] = 0.0f;
axes[1][0] = win_width / 2.5f; axes[1][1] = 0.0f;
axes[2][0] = 0.0f; axes[2][1] = -win_height / 2.5f;
axes[3][0] = 0.0f; axes[3][1] = win_height / 2.5f;
// Initialize vertex buffer object.
glGenBuffers(1, &VBO_axes);
glBindBuffer(GL_ARRAY_BUFFER, VBO_axes);
glBufferData(GL_ARRAY_BUFFER, sizeof(axes), axes, GL_STATIC_DRAW);
// Initialize vertex array object.
glGenVertexArrays(1, &VAO_axes);
glBindVertexArray(VAO_axes);
glBindBuffer(GL_ARRAY_BUFFER, VBO_axes);
glVertexAttribPointer(LOC_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void update_axes(void) {
axes[0][0] = -win_width / 2.5f; axes[1][0] = win_width / 2.5f;
axes[2][1] = -win_height / 2.5f;
axes[3][1] = win_height / 2.5f;
glBindBuffer(GL_ARRAY_BUFFER, VBO_axes);
glBufferData(GL_ARRAY_BUFFER, sizeof(axes), axes, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void draw_axes(void) {
glUniform3fv(loc_primitive_color, 1, axes_color);
glBindVertexArray(VAO_axes);
glDrawArrays(GL_LINES, 0, 4);
glBindVertexArray(0);
}
GLfloat line[2][2];
GLfloat line_color[3] = { 1.0f, 0.0f, 0.0f };
GLuint VBO_line, VAO_line;
void prepare_line(void) { // y = x - win_height/4
line[0][0] = (1.0f / 4.0f - 1.0f / 2.5f)*win_height;
line[0][1] = (1.0f / 4.0f - 1.0f / 2.5f)*win_height - win_height / 4.0f;
line[1][0] = win_width / 2.5f;
line[1][1] = win_width / 2.5f - win_height / 4.0f;
// Initialize vertex buffer object.
glGenBuffers(1, &VBO_line);
glBindBuffer(GL_ARRAY_BUFFER, VBO_line);
glBufferData(GL_ARRAY_BUFFER, sizeof(line), line, GL_STATIC_DRAW);
// Initialize vertex array object.
glGenVertexArrays(1, &VAO_line);
glBindVertexArray(VAO_line);
glBindBuffer(GL_ARRAY_BUFFER, VBO_line);
glVertexAttribPointer(LOC_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void update_line(void) { // y = x - win_height/4
line[0][0] = (1.0f / 4.0f - 1.0f / 2.5f)*win_height;
line[0][1] = (1.0f / 4.0f - 1.0f / 2.5f)*win_height - win_height / 4.0f;
line[1][0] = win_width / 2.5f;
line[1][1] = win_width / 2.5f - win_height / 4.0f;
glBindBuffer(GL_ARRAY_BUFFER, VBO_line);
glBufferData(GL_ARRAY_BUFFER, sizeof(line), line, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void draw_line(void) { // Draw line in its MC.
// y = x - win_height/4
glUniform3fv(loc_primitive_color, 1, line_color);
glBindVertexArray(VAO_line);
glDrawArrays(GL_LINES, 0, 2);
glBindVertexArray(0);
}
#define AIRPLANE_BIG_WING 0
#define AIRPLANE_SMALL_WING 1
#define AIRPLANE_BODY 2
#define AIRPLANE_BACK 3
#define AIRPLANE_SIDEWINDER1 4
#define AIRPLANE_SIDEWINDER2 5
#define AIRPLANE_CENTER 6
GLfloat big_wing[6][2] = { { 0.0, 0.0 }, { -20.0, 15.0 }, { -20.0, 20.0 }, { 0.0, 23.0 }, { 20.0, 20.0 }, { 20.0, 15.0 } };
GLfloat small_wing[6][2] = { { 0.0, -18.0 }, { -11.0, -12.0 }, { -12.0, -7.0 }, { 0.0, -10.0 }, { 12.0, -7.0 }, { 11.0, -12.0 } };
GLfloat body[5][2] = { { 0.0, -25.0 }, { -6.0, 0.0 }, { -6.0, 22.0 }, { 6.0, 22.0 }, { 6.0, 0.0 } };
GLfloat back[5][2] = { { 0.0, 25.0 }, { -7.0, 24.0 }, { -7.0, 21.0 }, { 7.0, 21.0 }, { 7.0, 24.0 } };
GLfloat sidewinder1[5][2] = { { -20.0, 10.0 }, { -18.0, 3.0 }, { -16.0, 10.0 }, { -18.0, 20.0 }, { -20.0, 20.0 } };
GLfloat sidewinder2[5][2] = { { 20.0, 10.0 }, { 18.0, 3.0 }, { 16.0, 10.0 }, { 18.0, 20.0 }, { 20.0, 20.0 } };
GLfloat center[1][2] = { { 0.0, 0.0 } };
GLfloat airplane_color[7][3] = {
{ 150 / 255.0f, 129 / 255.0f, 183 / 255.0f }, // big_wing
{ 245 / 255.0f, 211 / 255.0f, 0 / 255.0f }, // small_wing
{ 111 / 255.0f, 85 / 255.0f, 157 / 255.0f }, // body
{ 150 / 255.0f, 129 / 255.0f, 183 / 255.0f }, // back
{ 245 / 255.0f, 211 / 255.0f, 0 / 255.0f }, // sidewinder1
{ 245 / 255.0f, 211 / 255.0f, 0 / 255.0f }, // sidewinder2
{ 255 / 255.0f, 0 / 255.0f, 0 / 255.0f } // center
};
GLuint VBO_airplane, VAO_airplane;
void prepare_airplane() {
GLsizeiptr buffer_size = sizeof(big_wing)+sizeof(small_wing)+sizeof(body)+sizeof(back)
+sizeof(sidewinder1)+sizeof(sidewinder2)+sizeof(center);
// Initialize vertex buffer object.
glGenBuffers(1, &VBO_airplane);
glBindBuffer(GL_ARRAY_BUFFER, VBO_airplane);
glBufferData(GL_ARRAY_BUFFER, buffer_size, NULL, GL_STATIC_DRAW); // allocate buffer object memory
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(big_wing), big_wing);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(big_wing), sizeof(small_wing), small_wing);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(big_wing)+sizeof(small_wing), sizeof(body), body);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(big_wing)+sizeof(small_wing)+sizeof(body), sizeof(back), back);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(big_wing)+sizeof(small_wing)+sizeof(body)+sizeof(back),
sizeof(sidewinder1), sidewinder1);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(big_wing)+sizeof(small_wing)+sizeof(body)+sizeof(back)
+sizeof(sidewinder1), sizeof(sidewinder2), sidewinder2);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(big_wing)+sizeof(small_wing)+sizeof(body)+sizeof(back)
+sizeof(sidewinder1)+sizeof(sidewinder2), sizeof(center), center);
// Initialize vertex array object.
glGenVertexArrays(1, &VAO_airplane);
glBindVertexArray(VAO_airplane);
glBindBuffer(GL_ARRAY_BUFFER, VBO_airplane);
glVertexAttribPointer(LOC_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void draw_airplane() { // Draw airplane in its MC.
glBindVertexArray(VAO_airplane);
glUniform3fv(loc_primitive_color, 1, airplane_color[AIRPLANE_BIG_WING]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 6);
glUniform3fv(loc_primitive_color, 1, airplane_color[AIRPLANE_SMALL_WING]);
glDrawArrays(GL_TRIANGLE_FAN, 6, 6);
glUniform3fv(loc_primitive_color, 1, airplane_color[AIRPLANE_BODY]);
glDrawArrays(GL_TRIANGLE_FAN, 12, 5);
glUniform3fv(loc_primitive_color, 1, airplane_color[AIRPLANE_BACK]);
glDrawArrays(GL_TRIANGLE_FAN, 17, 5);
glUniform3fv(loc_primitive_color, 1, airplane_color[AIRPLANE_SIDEWINDER1]);
glDrawArrays(GL_TRIANGLE_FAN, 22, 5);
glUniform3fv(loc_primitive_color, 1, airplane_color[AIRPLANE_SIDEWINDER2]);
glDrawArrays(GL_TRIANGLE_FAN, 27, 5);
glUniform3fv(loc_primitive_color, 1, airplane_color[AIRPLANE_CENTER]);
glPointSize(5.0);
glDrawArrays(GL_POINTS, 32, 1);
glPointSize(1.0);
glBindVertexArray(0);
}
void display(void) {
int i;
float x, r, s, delx, delr, dels;
glm::mat4 ModelMatrix;
glClear(GL_COLOR_BUFFER_BIT);
ModelMatrix = glm::mat4(1.0f);
ModelViewProjectionMatrix = ViewProjectionMatrix * ModelMatrix;
glUniformMatrix4fv(loc_ModelViewProjectionMatrix, 1, GL_FALSE, &ModelViewProjectionMatrix[0][0]);
draw_axes();
draw_line();
draw_airplane();
ModelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(centerx, centery, 0.0f));
ModelMatrix = glm::rotate(ModelMatrix, rotate_angle, glm::vec3(0.0f, 0.0f, 1.0f));
ModelViewProjectionMatrix = ViewProjectionMatrix * ModelMatrix;
glUniformMatrix4fv(loc_ModelViewProjectionMatrix, 1, GL_FALSE, &ModelViewProjectionMatrix[0][0]);
draw_airplane(); // 0
ModelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(-win_width / 4.0f, -win_height / 4.0f, 0.0f));
ModelMatrix = glm::rotate(ModelMatrix, 90.0f*TO_RADIAN, glm::vec3(0.0f, 0.0f, 1.0f));
ModelMatrix = glm::scale(ModelMatrix, glm::vec3(3.0f, 3.0f, 1.0f));
ModelViewProjectionMatrix = ViewProjectionMatrix * ModelMatrix;
glUniformMatrix4fv(loc_ModelViewProjectionMatrix, 1, GL_FALSE, &ModelViewProjectionMatrix[0][0]);
draw_airplane(); // 1
ModelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(win_width / 2.5f, -win_height / 8.0f, 0.0f));
ModelMatrix = glm::rotate(ModelMatrix, 270.0f*TO_RADIAN, glm::vec3(0.0f, 0.0f, 1.0f));
ModelViewProjectionMatrix = ViewProjectionMatrix * ModelMatrix;
glUniformMatrix4fv(loc_ModelViewProjectionMatrix, 1, GL_FALSE, &ModelViewProjectionMatrix[0][0]);
draw_airplane(); // 2
ModelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(win_height / 4.0f, 0.0f, 0.0f));
ModelMatrix = glm::rotate(ModelMatrix, 45.0f*TO_RADIAN, glm::vec3(0.0f, 0.0f, 1.0f));
ModelMatrix = glm::scale(ModelMatrix, glm::vec3(1.0f, -1.0f, 1.0f));
ModelMatrix = glm::rotate(ModelMatrix, -45.0f*TO_RADIAN, glm::vec3(0.0f, 0.0f, 1.0f));
ModelMatrix = glm::translate(ModelMatrix, glm::vec3(-win_height / 4.0f, 0.0f, 0.0f));
ModelMatrix = glm::translate(ModelMatrix, glm::vec3(win_width / 2.5f, -win_height / 8.0f, 0.0f));
ModelMatrix = glm::scale(ModelMatrix, glm::vec3(2.0f, 2.0f, 1.0f));
ModelMatrix = glm::translate(ModelMatrix, glm::vec3(-win_width / 2.5f, win_height / 8.0f, 0.0f));
ModelMatrix = glm::translate(ModelMatrix, glm::vec3(win_width / 2.5f, -win_height / 8.0f, 0.0f));
ModelMatrix = glm::rotate(ModelMatrix, 270.0f*TO_RADIAN, glm::vec3(0.0f, 0.0f, 1.0f));
ModelViewProjectionMatrix = ViewProjectionMatrix * ModelMatrix;
glUniformMatrix4fv(loc_ModelViewProjectionMatrix, 1, GL_FALSE, &ModelViewProjectionMatrix[0][0]);
draw_airplane(); // 3
delx = win_width/14.0f; delr = 15.0f; dels = 1.1f;
x = -delx; r = delr; s = dels;
for (i = 0; i < 5; i++, x -= delx, r += delr, s *= dels) {
ModelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(x, 15.0f*sqrtf(-x), 0.0f));
ModelMatrix = glm::rotate(ModelMatrix, r*TO_RADIAN, glm::vec3(0.0f, 0.0f, 1.0f));
glTranslatef(x, 15.0f*sqrtf(-x), 0.0f);
ModelMatrix = glm::scale(ModelMatrix, glm::vec3(s, s, 1.0f));
ModelViewProjectionMatrix = ViewProjectionMatrix * ModelMatrix;
glUniformMatrix4fv(loc_ModelViewProjectionMatrix, 1, GL_FALSE, &ModelViewProjectionMatrix[0][0]);
draw_airplane(); // 4
}
glFlush();
}
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 27: // ESC key
glutLeaveMainLoop(); // Incur destuction callback for cleanups.
break;
}
}
void special(int key, int x, int y) {
#define SENSITIVITY 2.0
switch (key) {
case GLUT_KEY_LEFT:
centerx -= SENSITIVITY;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT:
centerx += SENSITIVITY;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:
centery -= SENSITIVITY;
glutPostRedisplay();
break;
case GLUT_KEY_UP:
centery += SENSITIVITY;
glutPostRedisplay();
break;
}
}
int leftbuttonpressed = 0;
void mouse(int button, int state, int x, int y) {
if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
leftbuttonpressed = 1;
else if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_UP))
leftbuttonpressed = 0;
}
void motion(int x, int y) {
static int delay = 0;
static float tmpx = 0.0, tmpy = 0.0;
float dx, dy;
if (leftbuttonpressed) {
centerx = x - win_width/2.0f, centery = (win_height - y) - win_height/2.0f;
if (delay == 8) {
dx = centerx - tmpx;
dy = centery - tmpy;
if (dx > 0.0) {
rotate_angle = atan(dy / dx) + 90.0f*TO_RADIAN;
}
else if (dx < 0.0) {
rotate_angle = atan(dy / dx) - 90.0f*TO_RADIAN;
}
else if (dx == 0.0) {
if (dy > 0.0) rotate_angle = 180.0f*TO_RADIAN;
else rotate_angle = 0.0f;
}
tmpx = centerx, tmpy = centery;
delay = 0;
}
glutPostRedisplay();
delay++;
}
}
void reshape(int width, int height) {
win_width = width, win_height = height;
glViewport(0, 0, win_width, win_height);
ProjectionMatrix = glm::ortho(-win_width / 2.0, win_width / 2.0,
-win_height / 2.0, win_height / 2.0, -1000.0, 1000.0);
ViewProjectionMatrix = ProjectionMatrix * ViewMatrix;
update_axes();
update_line();
glutPostRedisplay();
}
void cleanup(void) {
glDeleteVertexArrays(1, &VAO_axes);
glDeleteBuffers(1, &VBO_axes);
glDeleteVertexArrays(1, &VAO_line);
glDeleteBuffers(1, &VBO_line);
glDeleteVertexArrays(1, &VAO_airplane);
glDeleteBuffers(1, &VBO_airplane);
}
void register_callbacks(void) {
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutReshapeFunc(reshape);
glutCloseFunc(cleanup);
}
void prepare_shader_program(void) {
ShaderInfo shader_info[3] = {
{ GL_VERTEX_SHADER, "Shaders/simple.vert" },
{ GL_FRAGMENT_SHADER, "Shaders/simple.frag" },
{ GL_NONE, NULL }
};
h_ShaderProgram = LoadShaders(shader_info);
glUseProgram(h_ShaderProgram);
loc_ModelViewProjectionMatrix = glGetUniformLocation(h_ShaderProgram, "u_ModelViewProjectionMatrix");
loc_primitive_color = glGetUniformLocation(h_ShaderProgram, "u_primitive_color");
}
void initialize_OpenGL(void) {
glEnable(GL_MULTISAMPLE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glClearColor(44 / 255.0f, 180 / 255.0f, 49 / 255.0f, 1.0f);
ViewMatrix = glm::mat4(1.0f);
}
void prepare_scene(void) {
prepare_axes();
prepare_line();
prepare_airplane();
}
void initialize_renderer(void) {
register_callbacks();
prepare_shader_program();
initialize_OpenGL();
prepare_scene();
}
void initialize_glew(void) {
GLenum error;
glewExperimental = GL_TRUE;
error = glewInit();
if (error != GLEW_OK) {
fprintf(stderr, "Error: %s\n", glewGetErrorString(error));
exit(-1);
}
fprintf(stdout, "*********************************************************\n");
fprintf(stdout, " - GLEW version supported: %s\n", glewGetString(GLEW_VERSION));
fprintf(stdout, " - OpenGL renderer: %s\n", glGetString(GL_RENDERER));
fprintf(stdout, " - OpenGL version supported: %s\n", glGetString(GL_VERSION));
fprintf(stdout, "*********************************************************\n\n");
}
void greetings(char *program_name, char messages[][256], int n_message_lines) {
fprintf(stdout, "**************************************************************\n\n");
fprintf(stdout, " PROGRAM NAME: %s\n\n", program_name);
fprintf(stdout, " This program was coded for CSE4170 students\n");
fprintf(stdout, " of Dept. of Comp. Sci. & Eng., Sogang University.\n\n");
for (int i = 0; i < n_message_lines; i++)
fprintf(stdout, "%s\n", messages[i]);
fprintf(stdout, "\n**************************************************************\n\n");
initialize_glew();
}
#define N_MESSAGE_LINES 2
void main(int argc, char *argv[]) {
char program_name[64] = "Sogang CSE4170 Simple2DTransformation_GLSL_3.0";
char messages[N_MESSAGE_LINES][256] = {
" - Keys used: 'ESC', four arrows",
" - Mouse used: L-click and move"
};
glutInit (&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_MULTISAMPLE);
glutInitWindowSize (1200*0.95, 800*0.95);
glutInitContextVersion(4, 0);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow(program_name);
greetings(program_name, messages, N_MESSAGE_LINES);
initialize_renderer();
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glutMainLoop ();
}
glutInitWindowSize() / glutInitWindowPosition()
--> 여기에서 사용되는 좌표계는 윈도우 좌표계로서 모니터의 상단좌측이 (0,0)이 되며 오른쪽으로 갈수록 값이 증가하며 아래로 내려올수록 값이 증가. 각각 창의 size와 첫 position.
glutInitWindowPosition(0,0)으로 둘 시, 시작하면 (0,0)에서 창이 띄워짐.
glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
-->색깔설정. 마지막은 투명도.
GLfloat airplain_color[7][3]의 엘리먼트에 각 숫자를 넣음으로써 숫자 변경이 가능.
0.0부터 1.0까지, 0부터 255에 대응시킴. 가령 150/255.0f로 표현.
register_callbacks()
--> 사용자의 반응에 적용.
키보드 키를 누를 시 반응: ketboard() && glutKeyboardFunc()
사용자가 창에 입력하면 ASCII 문자를 생성할 때마다 키보드 콜백이 생성. Key는, 콜백 매개 변수는 생성된 ASCII 문자이며, x 및 y 콜백 매개 변수는 키를 눌렀을 때의 창의 상대 좌표에 마우스 위치를 나타냄.
마우스 누를 시: glutMouseFunc()
사용자가 창에서 마우스 버튼을 눌렀다 놓으면 각 버튼을 누를 때마다 각 릴리스에서 마우스 콜백이 생성됨.. 버튼 매개 변수는 GLUT_LEEPT_BUTTON, GLUT_MIND_BUTTON 또는 GLUT_RIGHT_BUTTON 중 하나입니다. 마우스 버튼이 두 개뿐인 시스템의 경우 GLUT_MIND_BUTTON 콜백을 생성할 수 없습니다. 단일 마우스 버튼을 사용하는 시스템의 경우 GLUT_LEEPT_BUTTON 콜백만 생성할 수 있습니다. 상태 매개 변수는 각각 GLUT_UP 또는 GLUT_DOWN으로 콜백이 릴리스 때문인지 또는 프레스 때문인지를 나타냅니다.
x 및 y 콜백 매개 변수는 마우스 버튼 상태가 변경되었을 때의 창 상대 좌표를 나타냅니다. 특정 버튼에 대한 GLUT_DOWN 콜백이 트리거된 경우, 프로그램은 마우스 버튼이 창 밖으로 이동하더라도 동일한 버튼에 대한 GLUT_UP 콜백이 생성된다고 가정할 수 있습니다(창에 여전히 마우스 콜백이 등록되어 있다고 가정함).
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include "LoadShaders.h"
//----------------------------------------------------------------------------
GLchar* ReadShader( const char* filename ) {
FILE* infile = fopen( filename, "rb" );
if ( !infile ) {
#ifdef _DEBUG
fprintf(stdout, "Unable to open file '%s'\n", filename);
#endif /* DEBUG */
return NULL;
}
fseek( infile, 0, SEEK_END );
int len = ftell( infile );
fseek( infile, 0, SEEK_SET );
GLchar* source = (GLchar*)malloc((len + 1) * sizeof(GLchar));
fread( source, 1, len, infile );
fclose( infile );
source[len] = 0;
return source;
}
//----------------------------------------------------------------------------
GLuint LoadShaders( ShaderInfo* shaders ) {
if ( shaders == NULL ) { return 0; }
GLuint program = glCreateProgram();
ShaderInfo* entry = shaders;
while ( entry->type != GL_NONE ) {
GLuint shader = glCreateShader( entry->type );
entry->shader = shader;
GLchar* source = ReadShader( entry->filename );
if ( source == NULL ) {
for ( entry = shaders; entry->type != GL_NONE; ++entry ) {
glDeleteShader( entry->shader );
entry->shader = 0;
}
return 0;
}
glShaderSource( shader, 1, &source, NULL );
free(source);
glCompileShader( shader );
GLint compiled;
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
if ( !compiled ) {
#ifdef _DEBUG
GLsizei len;
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &len );
GLchar* log = (GLchar*)malloc((len + 1) * sizeof(GLchar));
glGetShaderInfoLog( shader, len, &len, log );
fprintf(stdout, "Shader compilation failed: %s\n", log);
free(log);
#endif /* DEBUG */
return 0;
}
glAttachShader( program, shader );
++entry;
}
glLinkProgram( program );
GLint linked;
glGetProgramiv( program, GL_LINK_STATUS, &linked );
if ( !linked ) {
#ifdef _DEBUG
GLsizei len;
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &len );
GLchar* log = (GLchar*)malloc((len + 1) * sizeof(GLchar));
glGetProgramInfoLog( program, len, &len, log );
fprintf(stdout, "Shader linking failed: %s\n", log);
free(log);
#endif /* DEBUG */
for ( entry = shaders; entry->type != GL_NONE; ++entry ) {
glDeleteShader( entry->shader );
entry->shader = 0;
}
return 0;
}
return program;
}
#ifndef __LOAD_SHADERS_H__
#define __LOAD_SHADERS_H__
#include <GL/gl.h>
typedef struct {
GLenum type;
const char* filename;
GLuint shader;
} ShaderInfo;
GLuint LoadShaders( ShaderInfo* );
#endif // __LOAD_SHADERS_H__
#version 330
in vec4 v_color;
layout (location = 0) out vec4 final_color;
void main(void) {
final_color = v_color;
}
#version 330
uniform mat4 u_ModelViewProjectionMatrix;
uniform vec3 u_primitive_color;
layout (location = 0) in vec4 a_position;
out vec4 v_color;
void main(void) {
v_color = vec4(u_primitive_color, 1.0f);
gl_Position = u_ModelViewProjectionMatrix * a_position;
}