MyFirstOpenGLShader




#include <cmath>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/freeglut_ext.h>


const float vertexPositions[] = {
-0.75f, -0.75f, 0.0f, 1.0f,
0.75f, -0.75f, 0.0f, 1.0f,
0.75f, 0.75f, 0.0f, 1.0f,
};


GLuint program;
GLuint vao;
GLuint buffer;


////////////////////////////////////////////////////////////////////////////////////////////////////


// Create a NULL-terminated string by reading the provided file
static char* readShaderSource(const char* shaderFile)
{
FILE* fp = fopen(shaderFile, “r”);


if ( fp == NULL ) { return NULL; }


fseek(fp, 0L, SEEK_END);
long size = ftell(fp);


fseek(fp, 0L, SEEK_SET);
char* buf = new char[size + 1];
fread(buf, 1, size, fp);


buf[size] = ”;
fclose(fp);


return buf;
}


// Create a GLSL program object from vertex and fragment shader files
GLuint InitShader(const char* vShaderFile, const char* fShaderFile)
{
struct Shader {
const char* filename;
GLenum type;
GLchar* source;
} shaders[2] = {
{ vShaderFile, GL_VERTEX_SHADER, NULL },
{ fShaderFile, GL_FRAGMENT_SHADER, NULL }
};


GLuint program = glCreateProgram();


for ( int i = 0; i < 2; ++i ) {
Shader& s = shaders[i];
s.source = readShaderSource( s.filename );
if ( shaders[i].source == NULL ) {
std::cerr << “Failed to read ” << s.filename << std::endl;
exit( EXIT_FAILURE );
}


GLuint shader = glCreateShader( s.type );


glShaderSource( shader, 1, (const GLchar**) &s.source, NULL );
glCompileShader( shader );


GLint compiled;
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
if ( !compiled ) {
std::cerr << s.filename << ” failed to compile:” << std::endl;
GLint logSize;
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize );
char* logMsg = new char[logSize];
glGetShaderInfoLog( shader, logSize, NULL, logMsg );
std::cerr << logMsg << std::endl;
delete [] logMsg;


exit( EXIT_FAILURE );
}


delete [] s.source;


glAttachShader( program, shader );
}


/* link and error check */
glLinkProgram(program);


GLint linked;
glGetProgramiv( program, GL_LINK_STATUS, &linked );
if ( !linked ) {
std::cerr << “Shader program failed to link” << std::endl;
GLint logSize;
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize);
char* logMsg = new char[logSize];
glGetProgramInfoLog( program, logSize, NULL, logMsg );
std::cerr << logMsg << std::endl;
delete [] logMsg;


exit( EXIT_FAILURE );
}


/* use program object */
glUseProgram(program);


return program;
}


////////////////////////////////////////////////////////////////////////////////////////////////////


void init( void )
{
// Load shaders and use the resulting shader program
program = InitShader( “vshader21.glsl”, “fshader21.glsl” );
glUseProgram(program);


// VAO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);


// VBO
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);


glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white background
}


void display( void )
{
glClear( GL_COLOR_BUFFER_BIT ); // clear the window


glDrawArrays(GL_TRIANGLES, 0, 3); // draw triangle


glFlush();
}


void keyboard( unsigned char key, int x, int y )
{
switch ( key ) {
case 27:
exit( EXIT_SUCCESS );
break;
}
}


int main( int argc, char **argv )
{

glutInit(&argc, argv);
glutInitDisplayMode( GLUT_RGBA );
glutInitWindowSize( 512, 512 );
glutCreateWindow(argv[0]);

glewInit();
init();


glutDisplayFunc( display );
glutKeyboardFunc( keyboard );


glutMainLoop();
return 0;
}


실행결과

사용자 삽입 이미지