#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#pragma comment(lib, "glew32.lib")
#include <stdio.h>
#include <GL/glew.h>
#include <GL/freeglut/freeglut.h>
#define WIDTH 320
#define HEIGHT 240
GLuint shaderProg;
GLuint vertexShader, fragmentShader;
//shader fileを読み込みコンパイルする
void readShaderCompile(GLuint shader, const char *file){
FILE *fp;
char *buf;
GLsizei size, len;
GLint compiled;
// ファイルを開く
fopen_s(&fp,file, "rb");
if(!fp) printf("ファイルを開くことができません %s\n", file);
//ファイルの末尾に移動し現在位置を得る
fseek(fp, 0, SEEK_END);
size = ftell(fp);//ファイルサイズを取得
// ファイルサイズのメモリを確保
buf = (GLchar *)malloc(size);
if(buf == NULL){
printf("メモリが確保できませんでした \n");
}
// ファイルを先頭から読み込む
fseek(fp, 0, SEEK_SET);
fread(buf, 1, size, fp);
//シェーダオブジェクトにプログラムをセット
glShaderSource(shader, 1, (const GLchar **)&buf, &size);
//シェーダ読み込み領域の解放
free(buf);
fclose(fp);
// シェーダのコンパイル
glCompileShader(shader);
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
if( compiled == GL_FALSE ){
printf( "コンパイルできませんでした!!: %s \n ", file);
glGetProgramiv( shader, GL_INFO_LOG_LENGTH, &size );
if( size > 0 ){
buf = (char *)malloc(size);
glGetShaderInfoLog( shader, size, &len, buf);
printf(buf);
free(buf);
}
}
}
//リンクする
void link( GLuint prog ){
GLsizei size, len;
GLint linked;
char *infoLog ;
glLinkProgram( prog );
glGetProgramiv( prog, GL_LINK_STATUS, &linked );
if( linked == GL_FALSE ){
printf("リンクできませんでした!! \n");
glGetProgramiv( prog, GL_INFO_LOG_LENGTH, &size );
if( size > 0 ){
infoLog = (char *)malloc(size);
glGetProgramInfoLog( prog, size, &len, infoLog );
printf(infoLog);
free(infoLog);
}
}
}
//GLSLの初期化
void initGlsl(GLuint *program, const char *vertexFile){
//glewの初期化
GLenum err = glewInit();
if (err != GLEW_OK){
printf("Error: %s\n", glewGetErrorString(err));
}
// GPU,OpenGL情報
printf("VENDOR= %s \n", glGetString(GL_VENDOR));
printf("GPU= %s \n", glGetString(GL_RENDERER));
printf("OpenGL= %s \n", glGetString(GL_VERSION));
printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));
//シェーダーオブジェクトの作成
vertexShader = glCreateShader(GL_VERTEX_SHADER);
//シェーダーの読み込みとコンパイル
readShaderCompile(vertexShader, vertexFile);
// シェーダプログラムの作成
*program = glCreateProgram();
// シェーダオブジェクトをシェーダプログラムに関連付ける
glAttachShader(*program, vertexShader);
// シェーダオブジェクトの削除
glDeleteShader(vertexShader);
// シェーダプログラムのリンク
link(*program);
}
void initGlsl(GLuint *program, const char *vertexFile, const char
*fragmentFile){
//glewの初期化
GLenum err = glewInit();
if (err != GLEW_OK){
printf("Error: %s\n", glewGetErrorString(err));
}
// GPU,OpenGL情報
printf("VENDOR= %s \n", glGetString(GL_VENDOR));
printf("GPU= %s \n", glGetString(GL_RENDERER));
printf("OpenGL= %s \n", glGetString(GL_VERSION));
printf("GLSL= %s \n", glGetString(GL_SHADING_LANGUAGE_VERSION));
//シェーダーオブジェクトの作成
vertexShader = glCreateShader(GL_VERTEX_SHADER);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
//シェーダーの読み込みとコンパイル
readShaderCompile(vertexShader, vertexFile);
readShaderCompile(fragmentShader, fragmentFile);
// プログラムオブジェクトの作成
*program = glCreateProgram();
// シェーダオブジェクトをシェーダプログラムに関連付ける
glAttachShader(*program, vertexShader);
glAttachShader(*program, fragmentShader);
// シェーダオブジェクトの削除
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// シェーダプログラムのリンク
link(*program);
}
void Triangle(int x,int y,int size,float linesize){
glLineWidth(linesize);
//モード
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_TRIANGLES);
glColor4f(1.0f,0.0f,0.0f,1.0f);glVertex2i(x-size/2,y+size/2);
glColor4f(0.0f,1.0f,0.0f,1.0f);glVertex2i(x,y-size/2);
glColor4f(0.0f,0.0f,1.0f,1.0f);glVertex2i(x+size/2,y+size/2);
glEnd();
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Triangle(90,100,100,10);//固定機能で描画
glUseProgram(shaderProg);//シェーダー描画に切り替え
Triangle(230,100,100,10);//シェーダーで描画
glUseProgram(0);//シェーダー解除
glutSwapBuffers();
}
void idle(void){
glutPostRedisplay();
}
void Init(){
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);
}
void main(int argc, char *argv[]){
glutInitWindowPosition(100, 100);
glutInitWindowSize(WIDTH, HEIGHT);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("固定機能とシェーダーで描画");
glutDisplayFunc(display);
glutIdleFunc(idle);
initGlsl(&shaderProg, "vertex.shader");
Init();
glutMainLoop();
glDeleteProgram(shaderProg);
return;
}
|