実現したいこと
四角形が描画されるようにする
前提
glfwで四角形を描画するプログラムをこちらのサイトを参考にしながら書いています。
https://tokoik.github.io/GLFWdraft.pdf
主な機能分けは下記のようになっています。
- main.cppでウィンドウの初期化
- shader.cppのLoadshader()でシェーダのコンパイル、programIDの生成
- RenderクラスのSimplerenderメソッドで描画していましたが、簡単のためコメントアウトしてmain.cpp内で描画メソッドを呼び出している
- ObjectクラスのObject()で頂点配列オブジェクトの作成~Attribute変数に格納までの処理
- shapeクラスで描画処理
main.cpp
1#include <opencv2/opencv.hpp> 2#include <cstdlib> 3#include <iostream> 4#include <memory> 5 6// GL 7#include <GL/glew.h> 8#include <GLFW/glfw3.h> 9 10// made class 11#include "render.h" 12#include "Shape.h" 13#include "Object.h" 14 15#ifdef _DEBUG 16#pragma comment(lib, "opencv_world470d.lib") 17#else 18#pragma comment(lib, "opencv_world470.lib") 19#endif 20 21void checkGLError() 22{ 23 GLenum error; 24 while ((error = glGetError()) != GL_NO_ERROR) 25 { 26 std::cout << "OpenGL Error: " << error << std::endl; 27 } 28} 29 30using namespace std; 31using namespace cv; 32 33constexpr Object::Vertex rectangleVertex[] = 34{ 35 { -0.5f, -0.5f }, 36 { 0.5f, -0.5f }, 37 { 0.5f, 0.5f }, 38 { -0.5f, 0.5f } 39}; 40 41int main() 42{ 43 // variables--------------- 44 GLuint ProgramID; 45 46 //------------------------- 47 48 // instance---------------- 49 Render render_obj; 50 //------------------------- 51 52 if (glfwInit() == GL_FALSE) 53 { 54 cerr << "Can't initialize GLFW." << endl; 55 } 56 57 glfwWindowHint(GLFW_SAMPLES, 4); 58 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 59 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); 60 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 61 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 62 63 GLFWwindow *const window(glfwCreateWindow(640, 480, "Hello!", NULL, NULL)); 64 if (window == NULL) 65 { 66 cerr << "Can't create GLFW window" << endl; 67 return 1; 68 } 69 70 atexit(glfwTerminate); 71 72 glfwMakeContextCurrent(window); 73 74 // GLEWの初期化 75 glewExperimental = GL_TRUE; 76 if (glewInit() != GLEW_OK) 77 { 78 cerr << "Can't initialize FLEW" << endl; 79 return 1; 80 } 81 82 // 垂直同期のタイミングを待つ 83 glfwSwapInterval(1); 84 85 glClearColor(1.0f, 1.0f, 1.0f, 0.0f); 86 87 // LoadShaders 88 ProgramID = LoadShaders("Simple.vert", "Simple.frag"); 89 cout << ProgramID << endl; 90 91 unique_ptr<const Shape> shape(new Shape(2, 4, rectangleVertex)); 92 93 while (glfwWindowShouldClose(window) == GL_FALSE) 94 { 95 glClear(GL_COLOR_BUFFER_BIT); 96 97 // 描画処理----------------------------------------- 98 //render_obj.SimpleRender(shape, ProgramID); 99 glUseProgram(ProgramID); 100 shape->draw(); 101 //-------------------------------------------------- 102 103 glfwSwapBuffers(window); 104 105 glfwWaitEvents(); 106 } 107 return 0; 108}
Object.h
1#pragma once 2#include <GL/glew.h> 3#include <iostream> 4 5using namespace std; 6//図形データ 7class Object 8{ 9 // 頂点配列オブジェクト名 10 GLuint vao; 11 12 // 頂点バッファオブジェクト名 13 GLuint vbo; 14 15public: 16 17 // 頂点属性 18 struct Vertex 19 { 20 GLuint position[2]; 21 }; 22 23 Object(GLuint size, GLsizei vertexcount, const Vertex* vertex) 24 { 25 glGenVertexArrays(1, &vao); 26 glBindVertexArray(vao); 27 glGenBuffers(1, &vbo); 28 glBindBuffer(GL_ARRAY_BUFFER, vbo); 29 glBufferData(GL_ARRAY_BUFFER, vertexcount * sizeof(Vertex), vertex, GL_STATIC_DRAW); 30 31 glVertexAttribPointer(0, size, GL_FLOAT, GL_FALSE, 0, (void*)0); 32 glEnableVertexAttribArray(0); 33 } 34 35 // デストラクタ 36 virtual ~Object() 37 { 38 glDeleteVertexArrays(1, &vao); 39 glDeleteBuffers(1, &vbo); 40 } 41 42private: 43 // restrict copy 44 Object(const Object& o); 45 Object& operator=(const Object &o); 46 47public: 48 void bind() const 49 { // yuukouka 50 glBindVertexArray(vao); 51 } 52}; 53
Shape.h
1#pragma once 2#include <memory> 3 4#include "Object.h" 5 6using namespace std; 7 8class Shape { 9 // Class pointer defined 10 shared_ptr<const Object> object; 11 12protected: 13 // Number of vertexes to use 14 const GLsizei vertexcount; 15 16public: 17 Shape(GLuint size, GLsizei vertexcount, const Object::Vertex *vertex) 18 : object(new Object(size, vertexcount, vertex)) 19 , vertexcount(vertexcount) 20 { 21 } 22 23 void draw() const 24 { 25 object->bind(); 26 excute(); 27 } 28 29 virtual void excute() const 30 { 31 glDrawArrays(GL_LINE_LOOP, 0, vertexcount); 32 } 33}; 34
shader.cpp
1#include "shader.h" 2 3GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path) { 4 5 // Create the shaders 6 GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); 7 GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); 8 9 // Read the Vertex Shader code from the file 10 string VertexShaderCode; 11 ifstream VertexShaderStream(vertex_file_path, std::ios::in); 12 if (VertexShaderStream.is_open()) { 13 std::stringstream sstr; 14 sstr << VertexShaderStream.rdbuf(); 15 VertexShaderCode = sstr.str(); 16 VertexShaderStream.close(); 17 } 18 else { 19 printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path); 20 getchar(); 21 return 0; 22 } 23 24 // Read the Fragment Shader code from the file 25 string FragmentShaderCode; 26 ifstream FragmentShaderStream(fragment_file_path, std::ios::in); 27 if (FragmentShaderStream.is_open()) { 28 std::stringstream sstr; 29 sstr << FragmentShaderStream.rdbuf(); 30 FragmentShaderCode = sstr.str(); 31 FragmentShaderStream.close(); 32 } 33 34 GLint Result = GL_FALSE; 35 int InfoLogLength; 36 37 38 // Compile Vertex Shader 39 printf("Compiling shader : %s\n", vertex_file_path); 40 char const* VertexSourcePointer = VertexShaderCode.c_str(); 41 glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL); 42 glCompileShader(VertexShaderID); 43 44 // Check Vertex Shader 45 glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); 46 glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); 47 if (InfoLogLength > 0) { 48 std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1); 49 glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); 50 printf("%s\n", &VertexShaderErrorMessage[0]); 51 } 52 53 54 55 // Compile Fragment Shader 56 printf("Compiling shader : %s\n", fragment_file_path); 57 char const* FragmentSourcePointer = FragmentShaderCode.c_str(); 58 glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL); 59 glCompileShader(FragmentShaderID); 60 61 // Check Fragment Shader 62 glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); 63 glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); 64 if (InfoLogLength > 0) { 65 std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1); 66 glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); 67 printf("%s\n", &FragmentShaderErrorMessage[0]); 68 } 69 70 71 72 // Link the program 73 printf("Linking program\n"); 74 GLuint ProgramID = glCreateProgram(); 75 glAttachShader(ProgramID, VertexShaderID); 76 glAttachShader(ProgramID, FragmentShaderID); 77 glLinkProgram(ProgramID); 78 79 // Check the program 80 glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); 81 glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); 82 if (InfoLogLength > 0) { 83 std::vector<char> ProgramErrorMessage(InfoLogLength + 1); 84 glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); 85 printf("%s\n", &ProgramErrorMessage[0]); 86 } 87 88 89 glDetachShader(ProgramID, VertexShaderID); 90 glDetachShader(ProgramID, FragmentShaderID); 91 92 glDeleteShader(VertexShaderID); 93 glDeleteShader(FragmentShaderID); 94 95 return ProgramID; 96} 97 98GLuint LoadCompShader(const char* compute_file_path) { 99 100 // Create the shaders 101 GLuint ComputeShaderID = glCreateShader(GL_COMPUTE_SHADER); 102 103 // Read the Vertex Shader code from the file 104 string ComputeShaderCode; 105 ifstream ComputeShaderStream(compute_file_path, std::ios::in); 106 if (ComputeShaderStream.is_open()) { 107 std::stringstream sstr; 108 sstr << ComputeShaderStream.rdbuf(); 109 ComputeShaderCode = sstr.str(); 110 ComputeShaderStream.close(); 111 } 112 else { 113 printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", compute_file_path); 114 getchar(); 115 return 0; 116 } 117 118 GLint Result = GL_FALSE; 119 int InfoLogLength; 120 121 122 // Compile Vertex Shader 123 printf("Compiling shader : %s\n", compute_file_path); 124 char const* VertexSourcePointer = ComputeShaderCode.c_str(); 125 glShaderSource(ComputeShaderID, 1, &VertexSourcePointer, NULL); 126 glCompileShader(ComputeShaderID); 127 128 // Check Vertex Shader 129 glGetShaderiv(ComputeShaderID, GL_COMPILE_STATUS, &Result); 130 glGetShaderiv(ComputeShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); 131 if (InfoLogLength > 0) { 132 std::vector<char> ComputeShaderErrorMessage(InfoLogLength + 1); 133 glGetShaderInfoLog(ComputeShaderID, InfoLogLength, NULL, &ComputeShaderErrorMessage[0]); 134 printf("%s\n", &ComputeShaderErrorMessage[0]); 135 } 136 137 // Link the program 138 printf("Linking program\n"); 139 GLuint ProgramID = glCreateProgram(); 140 glAttachShader(ProgramID, ComputeShaderID); 141 glLinkProgram(ProgramID); 142 143 // Check the program 144 glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); 145 glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); 146 if (InfoLogLength > 0) { 147 std::vector<char> ProgramErrorMessage(InfoLogLength + 1); 148 glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); 149 printf("%s\n", &ProgramErrorMessage[0]); 150 } 151 152 153 glDetachShader(ProgramID, ComputeShaderID); 154 155 glDeleteShader(ComputeShaderID); 156 157 return ProgramID; 158}
shader.h
1#ifndef SHADER_HPP 2#define SHADER_HPP 3 4#include <iostream> 5#include <cstdlib> 6#include <vector> 7#include <sstream> 8#include <fstream> 9#include <GL/glew.h> 10#include <GLFW/glfw3.h> 11 12using namespace std; 13 14GLuint LoadShaders(const char* vertex_file_path, const char* fragment_file_path); 15 16#endif
発生している問題・エラーメッセージ
描画されない
試したこと
現状何も描画されていないウィンドウのみ表示されており、エラー文も出ていない状況です。Loadshaderに書いたコンパイル結果のエラー表示も問題なく、glgeterror()でチェックしてもエラー文なく、上記のメソッドが呼び出されているかをcoutで確認しましたが、全て呼び出されているようでした。最後のglfwWaitEvents();をpollにしても駄目でした。
補足情報(FW/ツールのバージョンなど)
- Visual Studio 2022
- Nugetでglfw,glewの最新版をインストール(GLEW-static:2.1.0.3 glfw:3.3.1)