現在、GLSLの勉強をしているのですが、シェーダオブジェクトをリンクする処理が失敗してしまい、困っています。
皆様の知識と経験をお貸しいただければ幸いです。
エラーメッセージ
シェーダプログラムのリンクに失敗しました
プログラム ログ:
ERROR:Definition for "void main()" not found.
###該当のソースコード
言語:C,GLSL
/////////////////////////////////////////////////// //maincpp /////////////////////////////////////////////////// //include #include <iostream> #include <fstream> #include <sstream> #include <GL/glew.h> #include <GL/glut.h> using namespace std; //link #pragma comment (lib, "glew32.lib") //global int windowPositionX = 100; //ウィンドウを開く位置 int windowPositionY = 100; int windowWidth = 512; //ウィンドウ幅 int windowHeight = 512; //ウィンドウ高さ char windowTitle[] = "GLSLプロジェクト"; //タイトル GLuint vaoHandle; //prototype void Initialize(); void Display(); void Reshape(int x, int y); void Keyboard(unsigned char key, int x, int y); void CompileShder(); void LinkShaderObject(GLuint vertShader, GLuint fragShader); const GLchar* ReadFile(const GLchar* file); //===================================== //初期化処理 //===================================== void Initialize() { //GLEWの初期化 if (glewInit() != GLEW_OK) { cout << "Error : GLEWの初期化に失敗しました\n"; exit(0); } //ウィンドウを塗りつぶす際の色を指定 glClearColor(1.0, 1.0, 1.0, 1.0); CompileShder(); } //========================================= //ウィンドウの拡大縮小に対する処理 //w:現在のウィンドウ幅 //h:現在のウィンドウの高さ //========================================= void Reshape(int x, int y) { windowWidth = x; windowHeight = y; //ウィンドウの最小サイズを制限 if (windowWidth < 1) windowWidth = 1; if (windowHeight < 1) windowHeight = 1; //ビューポートの設定 glViewport(0, 0, windowWidth, windowHeight); } //========================================= //ウィンドウへの描画 //========================================= void Display() { //ウィンドウを塗りつぶす(カラーバッファ指定) glClear(GL_COLOR_BUFFER_BIT); //ビューポートの設定 glViewport(0, 0, windowWidth, windowHeight); glBindVertexArray(vaoHandle); glDrawArrays(GL_TRIANGLES, 0, 3); } //========================================= //キーボードから入力されたとき //key:タイプされたキーの情報 //x,y:マウスの位置 //========================================= void Keyboard(unsigned char key, int x, int y) { switch (key) { case '\033': //'\033'はESCのASCIIコード exit(0); break; default: break; } } //===================================== //メインエントリポイント //===================================== int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitWindowPosition(windowPositionX, windowPositionY); //新たに開くウィンドウの位置を指定 glutInitWindowSize(windowWidth, windowHeight); //新たに開くウィンドウの幅と高さを指定 glutInitDisplayMode(GLUT_RGBA); //ディスプレイの表示モードを設定(RGBA指定) glutCreateWindow(windowTitle); //ウィンドウを開く glutDisplayFunc(Display); //ウィンドウ内に描画する関数へのポインタ(ウィンドウの再描画の際に呼ばれる) glutReshapeFunc(Reshape); //ウィンドウがリサイズされたときに実行される関数へのポインタを渡す //glutIdleFunc(Idle); //プログラムが暇なときに実行される関数へのポインタを渡す //glutMouseFunc(Mouse); //マウスのボタンが押されたときに実行される関数へのポインタを渡す //glutMotionFunc(Motion); //マウスのボタンを押しながら動かしたときに実行される関数へのポインタを渡す //glutPassiveMotionFunc(PassiveMotion); //マウスのボタンを押さずに動かしたときに実行される関数へのポインタを渡す //glutKeyboardFunc(Keyboard); //キーがタイプされたときに実行される関数へのポインタを渡す //glutSpecialFunc(Special); //特殊キーがタイプされたときに実行される関数へのポインタを渡す Initialize(); glutMainLoop(); return 0; } //===================================== //シェーダオブジェクトのコンパイル //===================================== void CompileShder() { GLuint vertShader, fragShader; //頂点シェーダのコンパイル vertShader = glCreateShader(GL_VERTEX_SHADER); //シェーダオブジェクトのハンドル作成 if (0 == vertShader) { fprintf(stderr, "頂点シェーダ作成エラー\n"); exit(1); } //ソースコードをシェーダオブジェクトにコピー const GLchar* vertShaderCode = ReadFile("shader/basic.vert"); //ファイルを読み込み const GLchar* vertShaderCodeArry[] = { vertShaderCode }; //配列にソースコードへのポインタを格納 glShaderSource(vertShader, 1, vertShaderCodeArry, NULL); //ソースコードをシェーダオブジェクトへロード //シェーダをコンパイル glCompileShader(vertShader); //コンパイルステータスを検証 GLint result; glGetShaderiv(vertShader, GL_COMPILE_STATUS, &result); //コンパイルステータスを問い合わせる if (GL_FALSE == result) { fprintf(stderr, "頂点シェーダのコンパイルに失敗しました\n"); GLint logLen; glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &logLen); //ログの長さを問い合わせる if (logLen > 0) { char* log = (char*)malloc(logLen); GLsizei written; glGetShaderInfoLog(vertShader, logLen, &written, log); //ログを取り出す fprintf(stderr, "シェーダ ログ: \n%s", log); free(log); } } //フラグメントシェーダのコンパイル fragShader = glCreateShader(GL_FRAGMENT_SHADER); //シェーダオブジェクトのハンドル作成 if (0 == fragShader) { fprintf(stderr, "フラグメントシェーダ作成エラー\n"); exit(1); } //ソースコードをシェーダオブジェクトにコピー const GLchar* fragShaderCode = ReadFile("shader/basic.frag"); //ファイルを読み込み const GLchar* fragShaderCodeArray[] = { fragShaderCode }; //配列にソースコードへのポインタを格納 glShaderSource(fragShader, 1, fragShaderCodeArray, NULL); //ソースコードをシェーダオブジェクトへロード //シェーダをコンパイル glCompileShader(fragShader); //コンパイルステータスを検証 glGetShaderiv(fragShader, GL_COMPILE_STATUS, &result); //コンパイルステータスを問い合わせる if (GL_FALSE == result) { fprintf(stderr, "フラグメントシェーダのコンパイルに失敗しました\n"); GLint logLen; glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLen); //ログの長さを問い合わせる if (logLen > 0) { char* log = (char*)malloc(logLen); GLsizei written; glGetShaderInfoLog(fragShader, logLen, &written, log); //ログを取り出す fprintf(stderr, "シェーダ ログ: \n%s", log); free(log); } } LinkShaderObject(vertShader, fragShader); float positionData[] = { -0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f, 0.0f, 0.8f, 0.0f }; float colorData[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; // 頂点バッファオブジェクトの作成 GLuint vboHandles[2]; //頂点バッファオブジェクトのメモリを参照するポインタを格納する配列 glGenBuffers(2, vboHandles); //頂点バッファオブジェクト作成して配列に格納 GLuint positionBufferHandle = vboHandles[0]; GLuint colorBufferHandle = vboHandles[1]; glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle); //バッファオブジェクト有効にする(頂点バッファオブジェクト指定) glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), positionData, GL_STATIC_DRAW); //バッファオブジェクトのメモリを確保して、そこにデータを転送(頂点バッファオブジェクト指定) glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle); glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), colorData, GL_STATIC_DRAW); glGenVertexArrays(1, &vaoHandle); glBindVertexArray(vaoHandle); glEnableVertexAttribArray(0); // Vertex position glEnableVertexAttribArray(1); // Vertex color glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL); glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte *)NULL); } //===================================== //シェーダオブジェクトのリンク //===================================== void LinkShaderObject(GLuint vertShader, GLuint fragShader) { //プログラムオブジェクト作成 GLuint programHandle = glCreateProgram(); //プログラムオブジェクトのハンドル作成 if (0 == programHandle) { fprintf(stderr, "プログラムオブジェクト作成でエラーがありました\n"); exit(1); } //シェーダーをプログラムオブジェクトにアタッチ glAttachShader(programHandle, vertShader); glAttachShader(programHandle, fragShader); //プログラムをリンク glLinkProgram(programHandle); //ステータスを検証 GLint status; glGetProgramiv(programHandle, GL_LINK_STATUS, &status); //コンパイルステータスを問い合わせる if (GL_FALSE == status) { fprintf(stderr, "シェーダ プログラムのリンクに失敗しました\n"); GLint logLen; glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &logLen); //ログの長さを問い合わせる if (logLen > 0) { char* log = (char*)malloc(logLen); GLsizei written; glGetProgramInfoLog(programHandle, logLen, &written, log); //ログを取り出す fprintf(stderr, "プログラム ログ: \n%s", log); free(log); } } else { glUseProgram(programHandle); //リンクが成功したら、プログラムをOpenGLパイプラインにインストール } } //===================================== //ファイルの読み込み //file:読み込むソースファイル //===================================== const GLchar* ReadFile(const GLchar* file) { ifstream inFile(file); //ファイル読み込み if (!inFile) { fprintf(stderr, "Error opening file: %s\n", file); exit(1); } stringstream code; code << inFile.rdbuf(); inFile.close(); string codeStr(code.str()); return codeStr.c_str(); //codeStrオブジェクトに含まれる文字列をヌル終端文字列に変換 } /////////////////////////////////////////////////// //シェーダソース //basic.vert /////////////////////////////////////////////////// #version 430 layout (location=0) in vec3 vertexPosition; layout (location=1) in vec3 vertexColor; out vec3 color; void main() { color = vertexColor; gl_Position = vec4(vertexPosition, 1.0); } /////////////////////////////////////////////////// //シェーダソース //basic.frag /////////////////////////////////////////////////// #version 430 in vec3 color; layout (location=0) out vec4 flagColor; void main() { flagColor = vec4(color, 1.0); }
ブレークポイントなどで調べてみたところ、glShaderSource()関数でシェーダオブジェクトへソースコードをロードした後、シェーダオブジェクトの中身は改行文字"\0"しか格納されておらず。それが原因かと考えているのですが。試行錯誤してもうまくいきませんでした。
使用しているPCが対応しているバージョンは以下の通りです。
OpenGL:4.30
GLSL:4.30
参考資料
OpenGL4.0シェーディング言語
よろしくお願いします!
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。