質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.80%

glsl エラー「プログラム最後の検証動作が失敗」とは何が原因なのか知りたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 243

score -60

提示コードのですがShader::Load();関数部ですがコメント部内部の関数でエラー[ 最後の検証動作が失敗 ]というとことでGL_FALSEを返すのですがこれはどういった事が原因として挙げられるのでしょうか?いろいろデバッグしましたがエラーメッセージが出ないので原因がわかりません。ProgramInfoLog();関数を色々な場所に置きましたがエラーメッセージが出ている箇所がありません。

公式リファレンス原文 [ params returns GL_TRUE or if the last validation operation on program was successful, and GL_FALSE otherwise. ]

google翻訳 [ paramsは、プログラムの最後の検証操作が成功した場合はGL_TRUEを返し、それ以外の場合はGL_FALSEを返します。 ]

[ glGetProgramiv() ] 関数リファレンス: https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetProgramiv.xml

/*#########################################################################
# 単色の二次元テキストレンダリング 頂点シェーダー
###########################################################################*/
#version 330
#extension GL_ARB_explicit_attrib_location: enable 

// ###################### 頂点属性 ###################### 
layout(location = 0) in vec4 vertexPosition;    //頂点座標


// ###################### 出力 ###################### 
layout(location = 1) out vec2 texCoord;    //テキスト

// ###################### Uniform ###################### 
uniform mat4 uViewProjection;    //ビュープロジェクション行列

void main()
{

    vec4 vertex = vec4(vertexPosition.x,vertexPosition.y,0.0,1.0);        //頂点座標
    gl_Position =  (uViewProjection * vertex);

    texCoord = vertexPosition.zw;

}
/*#########################################################################
# 単色の二次元テキストレンダリング フラグメントシェーダー
###########################################################################*/
#version 330
#extension GL_ARB_explicit_attrib_location: enable 

// ###################### 入力 ###################### 
layout(location = 1 ) in vec2 texCoord;

// ###################### 出力 ###################### 
out vec4 color;

// ###################### Unifrom ###################### 
uniform sampler2D text;     //文字テクスチャ
uniform vec4 uTextColor;    //色

void main()
{    
    vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, texCoord).r);
    color = uTextColor * sampled;
}  
#include "Shader.hpp"

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <glm/gtc/type_ptr.hpp>

// ##################################### コンストラクタ ##################################### 
FrameWork::Shader::Shader()
{
    program = 0;    //シェーダープログラムを初期化
}

// ##################################### シェーダーをロード ##################################### 
bool FrameWork::Shader::Load(const char* vert, const char* frag)
{
    program = loadProgram(vert, frag);

    int params;
    glGetProgramiv(program, GL_LINK_STATUS, &params);
    if (params == GL_FALSE)
    {
        std::cerr << "プログラムの最後のリンク操作が失敗" << std::endl;
    }
//////////////////////////////////////////////////////////////////////////////////////////
    glGetProgramiv(program, GL_VALIDATE_STATUS, &params);
    if (params == GL_FALSE)
    {
        ProgramInfoLog(program);
        std::cerr << "プログラムの最後の検証動作が失敗" << std::endl;
    }
/////////////////////////////////////////////////////////////////////////////////////////


    if (program == 0)
    {
        std::cerr << "シェーダープログラム作成エラー" << std::endl;
        return false;
    }

    return true;
}

// ##################################### プログラムオブジェクトをロード ##################################### 
GLuint FrameWork::Shader::loadProgram(const char* vert, const char* frag)
{
    std::vector<GLchar> vsrc;
    const bool vstat = ReadShaderSource(vert, vsrc);

    std::vector<GLchar> fsrc;
    const bool fstat = ReadShaderSource(frag, fsrc);

    if (vstat && fstat)
    {
        return CreateProgram(vsrc.data(), fsrc.data());        
    }
    else 
    {
        return 0;
    }
}

// ##################################### シェーダーファイルを読み込む ##################################### 
bool FrameWork::Shader::ReadShaderSource(const char* name, std::vector<GLchar>& buffer)
{
    if (name == NULL)
    {
        assert(0 && "シェーダーファイルが指定されていません。");
        return false;
    }

    std::ifstream file(name, std::ios::binary);
    if (file.fail() == true)
    {
        std::cerr << "ソースファイルが読み込めません: " << name << std::endl;
        file.close();
        return false;
    }
    else
    {
        file.seekg(0L, std::ios::end);
        GLsizei length = static_cast<GLsizei>(file.tellg());
        buffer.resize(length + 1);

        file.seekg(0L, std::ios::beg);
        file.read(buffer.data(), length);
        buffer[length] = '\0';

        file.close();
    }
    file.close();

    return true;
}

// ##################################### シェーダーエラーログを取得 ##################################### 
GLboolean FrameWork::Shader::CompileInfoLog(GLuint shader,const char* str)
{
    GLint status;

    //コンパイル結果
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE)
    {
        std::cerr << str << std::endl;
    }

    //エラーログの長さを得る
    GLsizei bufSize;
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &bufSize);

    if (bufSize > 1)
    {
        std::vector<GLchar> infoLog(bufSize);
        GLsizei length;
        glGetShaderInfoLog(shader, bufSize, &length, &infoLog[0]);

        std::cerr<< &infoLog[0] << std::endl;
    }

    return (GLboolean)status;
}

// ##################################### プログラムオブジェクト作成 ##################################### 
GLuint FrameWork::Shader::CreateProgram(const char* vsrc, const char* fsrc)
{
    const GLuint program = glCreateProgram();    //シェーダープログラムを作成

    if (vsrc != NULL)
    {
        const GLuint vobj = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vobj, 1, &vsrc, NULL);
        glCompileShader(vobj);
        CompileInfoLog(vobj, vsrc);
        glAttachShader(program, vobj);
        glDeleteShader(vobj);
    }
    else 
    {
        std::cerr << "頂点シェーダー読み込み失敗" << std::endl;
    }

    if (fsrc != NULL)
    {
        const GLuint fobj = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fobj, 1, &fsrc, NULL);
        glCompileShader(fobj);
        CompileInfoLog(fobj, fsrc);
        glAttachShader(program, fobj);
        glDeleteShader(fobj);
    }
    else 
    {
        std::cerr << "フラグメントシェーダー読み込み失敗" << std::endl;
    }

    glLinkProgram(program);        //リンクプログラム
    ProgramInfoLog(program);    //リンク時のログを表示

    return program;
}

// ##################################### プログラムのエラーを表示 ##################################### 
GLboolean FrameWork::Shader::ProgramInfoLog(GLuint program)
{
    GLsizei bufSize;
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufSize);

    if (bufSize > 1) 
    {
        std::vector<GLchar> infoLog(bufSize);    
        GLsizei length;
        glGetProgramInfoLog(program, bufSize, &length, &infoLog[0]);
        std::cerr<<"Program Info Log: "<< infoLog.data() <<std::endl;
        return false;
    }
    else
    {
        return true;
    }
}

// ##################################### Attriblocationを取得 ##################################### 
GLint FrameWork::Shader::getAttribLocation(const char* str)
{
    return glGetAttribLocation(program,str);
}

// ##################################### 頂点シェーダーに属性変数を関連ずける ##################################### 
void FrameWork::Shader::setBindAttribLocation(const char* str)
{
    GLint n = glGetAttribLocation(program, str);

    //エラー処理
    if (n == -1)
    {
        std::cerr <<"setBindAttribVertex(): "<< n << std::endl;
    }
    else 
    {
        glBindAttribLocation(program, n, str);
    }
}

// ##################################### フラグメントシェーダーに属性変数を関連ずける ##################################### 
void FrameWork::Shader::setBindAttribFragment(const char* str)
{
    GLint n = glGetAttribLocation(program, str);

    //エラー処理
    if (n == -1)
    {
        std::cerr << "setBindAttribFragment(): " << n << std::endl;
    }
    else 
    {
        glBindFragDataLocation(program, n, str);
    }
}

// ##################################### 有効にする ##################################### 
void FrameWork::Shader::setEnable()
{
    glUseProgram(program);
}

// ##################################### 無効にする ##################################### 
void FrameWork::Shader::setDisable()
{
    glUseProgram(0);
}

// ##################################### Uniform 設定 ##################################### 

//vec1
void FrameWork::Shader::setUniform1f(const char* name, const float vec)
{
    const GLuint object = glGetUniformLocation(program, name);
    if (object == -1) { assert(0); }    //エラー処理
    glUniform1f(object,vec);
}

//vec2
void FrameWork::Shader::setUniform2f(const char* name, const glm::vec2 vec)
{
    const GLuint object = glGetUniformLocation(program, name);
    if (object == -1) { assert(0); }    //エラー処理
    glUniform2f(object,vec.x,vec.y);
}

//vec3
void FrameWork::Shader::setUniform3f(const char* name, const glm::vec3 vec)
{
    const GLuint object = glGetUniformLocation(program, name);
    if (object == -1) { assert(0); }    //エラー処理
    glUniform3f(object,vec.x, vec.y,vec.z);
}

//vec4
void FrameWork::Shader::setUniform4f(const char* name, const glm::vec4 vec)
{    
    const GLuint object = glGetUniformLocation(program,name);
    if (object == -1) { assert(0); }    //エラー処理
    glUniform4f(object, vec.x, vec.y, vec.z, vec.w);    
}

//行列2
void FrameWork::Shader::setUniformMatrix2fv(const char* name, const glm::mat2 m)
{
    const GLuint object = glGetUniformLocation(program, name);
    if (object == -1) { assert(0); }    //エラー処理
    glUniformMatrix2fv(object,1,false,glm::value_ptr(m));
}

//行列3
void FrameWork::Shader::setUniformMatrix3fv(const char* name, const glm::mat3 m)
{
    const GLuint object = glGetUniformLocation(program, name);
    if (object == -1) { assert(0); }    //エラー処理
    glUniformMatrix3fv(object, 1, false, glm::value_ptr(m));
}

//行列4
void FrameWork::Shader::setUniformMatrix4fv(const char* name, const glm::mat4 m)
{
    const GLuint object = glGetUniformLocation(program, name);
    if (object == -1) { assert(0); }    //エラー処理
    glUniformMatrix4fv(object, 1, false, glm::value_ptr(m));
}

// ##################################### デストラクタ ##################################### 
FrameWork::Shader::~Shader()
{
    glDeleteProgram(program);
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    2021/06/19 15:18

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 1

check解決した方法

-1

フレームワークで変更したシェーダーファイルをゲーム側に反映していないためでした。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る