GLFW3.0.1とGLEW1.10.0での簡易サンプル
VBOとシェーダーを使ったもの。
動けばOK
行列はglmを使った。楽ちん。
三角形が回るサンプル。
アプリケーション
// glew32s.libを使う. #define GLEW_STATIC #include <stdio.h> #include <stdlib.h> #include <GL/glew.h> #include <GLFW/glfw3.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> const int g_WindowWidth = 640; const int g_WindowHeight = 480; GLuint g_VBO = 0; GLuint g_Indices = 0; GLFWwindow* g_Window = NULL; glm::mat4 g_World; glm::mat4 g_View; glm::mat4 g_Proj; float g_RotZ = 0.0f; void printLog(GLuint obj) { int infologLength = 0; int maxLength = 0; if(glIsShader(obj)) { glGetShaderiv(obj, GL_INFO_LOG_LENGTH, &maxLength); } else { glGetProgramiv(obj, GL_INFO_LOG_LENGTH, &maxLength); } char* infoLog = new char[maxLength]; if(glIsShader(obj)) { glGetShaderInfoLog(obj, maxLength, &infologLength, infoLog); } else { glGetProgramInfoLog(obj, maxLength, &infologLength, infoLog); } if(infologLength > 0) { printf("%s\n", infoLog); } delete [] infoLog; } char* file2string(const char* path) { FILE* fd = fopen(path, "r"); if(!fd) { fprintf(stderr, "Can't open file '%s' for reading\n", path); return NULL; } fseek(fd, 0, SEEK_END); long len = ftell(fd); printf("File '%s' is %ld long\n", path, len); fseek(fd, 0, SEEK_SET); char* str = (char*)malloc(len * sizeof(char)); if(!str) { fprintf(stderr, "Can't malloc, space for '%s'\n", path); return NULL; } long r = fread(str, sizeof(char), len, fd); str[r-1] = '\0'; fclose(fd); return str; } int main() { // 初期化. if(!glfwInit()) { exit(EXIT_FAILURE); } g_Window = glfwCreateWindow(g_WindowWidth, g_WindowHeight, "Test", NULL, NULL); if(!g_Window) { glfwTerminate(); exit(EXIT_FAILURE); } glfwMakeContextCurrent(g_Window); GLenum err = glewInit(); if(err != GLEW_OK) { glfwTerminate(); exit(EXIT_FAILURE); } // カメラ設定. float ratio = float(g_WindowWidth)/float(g_WindowHeight); g_Proj = glm::perspective(30.0f, ratio, 1.f, 50.f); g_View = glm::lookAt(glm::vec3(0, 0, 10), glm::vec3(0,0,0), glm::vec3(0,1,0)); // ジオメトリ設定. GLfloat vertexBuffer [] = { 0, 2, 0, -2, -2, 0, 2, -2, 0 }; GLubyte indexBuffer[] = { 0, 1, 2 }; glGenBuffers(1, &g_VBO); glGenBuffers(1, &g_Indices); glBindBuffer(GL_ARRAY_BUFFER, g_VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexBuffer), vertexBuffer, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_Indices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexBuffer), indexBuffer, GL_STATIC_DRAW); // シェーダー. char* src_vs = file2string("vertex.vert"); char* src_fs = file2string("fragment.frag"); GLuint vs, fs, sp; vs = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vs, 1, (const GLchar**)&src_vs, NULL); glCompileShader(vs); printLog(vs); fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs, 1, (const GLchar**)&src_fs, NULL); glCompileShader(fs); printLog(fs); free(src_vs); free(src_fs); sp = glCreateProgram(); glAttachShader(sp, vs); glAttachShader(sp, fs); glBindFragDataLocation(sp, 0, "outColor"); glLinkProgram(sp); printLog(sp); glUseProgram(sp); GLint sp_pos = glGetAttribLocation(sp, "pos"); GLint sp_world = glGetUniformLocation(sp, "world"); GLint sp_view = glGetUniformLocation(sp, "view"); GLint sp_proj = glGetUniformLocation(sp, "proj"); // メインループ. while(!glfwWindowShouldClose(g_Window)) { if(glfwGetKey(g_Window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(g_Window, GL_TRUE); } glViewport(0, 0, g_WindowWidth, g_WindowHeight); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 identity(1); g_World = glm::rotate(identity, g_RotZ, glm::vec3(0, 0, 1)); glColor3f(1, 0, 0); g_RotZ += 0.5f; glBindBuffer(GL_ARRAY_BUFFER, g_VBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_Indices); // ユニフォーム. glUniformMatrix4fv(sp_world, 1, GL_FALSE, glm::value_ptr(g_World)); glUniformMatrix4fv(sp_view, 1, GL_FALSE, glm::value_ptr(g_View)); glUniformMatrix4fv(sp_proj, 1, GL_FALSE, glm::value_ptr(g_Proj)); glEnableVertexAttribArray(0); glVertexAttribPointer(sp_pos, 3, GL_FLOAT, GL_FALSE, sizeof(float)*3, 0); glEnableVertexAttribArray(sp_pos); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, 0); glDisableVertexAttribArray(sp_pos); glfwSwapBuffers(g_Window); glfwPollEvents(); } // 破棄. glDeleteBuffers(1, &g_VBO); glDeleteBuffers(1, &g_Indices); glfwDestroyWindow(g_Window); // 終了処理. glfwTerminate(); return 0; }
頂点シェーダー
#version 140 uniform mat4 world; uniform mat4 view; uniform mat4 proj; in vec3 pos; void main() { gl_Position = proj * view * world * vec4(pos, 1.0); }
フラグメントシェーダー
#version 140 out vec4 outColor; void main() { outColor = vec4(0.0, 1.0, 0.0, 1.0); }