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

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

ただいまの
回答率

87.49%

GLSL フラグメントシェーダーで色が出力されず白になってしまう原因が知りたい。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 967
退会済みユーザー

退会済みユーザー

提示画像のLoadShader();関数部の////コメント部で囲ってるコードの内部ですがなぜフラグメントシェーダーで色が付かないのでしょうか?
提示コードにもある通りしっかりout vec4 fragment;としてあると思うのですがこれはなぜでしょうか?コードにコメントを書いてコードを整形して余計なところに無駄にシェーダー関係のコードがないか確認して整理してきましたが何も怪しいものはありませんどうしたらいいのでしょうか?

イメージ説明

#version 400
//フラグメントシェーダー
out vec4 fragment;

void main()
{
    fragment = vec4(0.0,0.0,1.0,1.0);    
}
#version 400 
//頂点シェーダー

in vec3  position;//頂点座標

uniform mat4 scale;//スケール行列
uniform mat4 rotate;//回転行列
uniform mat4 move;//平行移動行列

uniform mat4 MP;

out vec4 mt;

void main()
{
    vec4 t = vec4(position,1.0);
    mat4 M = mat4(move * rotate * scale);

    gl_Position = MP * M * t;
    ///gl_Position = vec4(mt,1.0);
}
#ifndef ___GMAE_H_
#define ___GMAE_H_

#define WIDTH 640
#define HEIGHT 400

#include "stdio.h"
#include <fstream>
#include <sstream>
#include <iostream>

#include "GLEW/include/GL/glew.h"

#include "gl/GL.h"
#include "GLFW/include/GLFW/glfw3.h"
#include "Vector.hpp"


class Game
{
public:
    Vector3 cv;

    Game();

    bool Initialization();

    bool RunLoop();

    void Update();
    void GenerateOutput();


private:
    bool mIsRunLoop;//メインループ

    float mp[16] = { 0 };//透視射形行列

//頂点バッファー
    float Vertex[6][4] =
    {
        {-0.5, 0.5, -1.0, 1.0},
        {-0.5, -0.5, -1.0, 1.0},
        {0.5, -0.5, -1.0, 1.0},

        {-0.5, 0.5, -1.0, 1.0},
        {0.5, 0.5, -1.0, 1.0 },
        {0.5, -0.5, -1.0, 1.0}
    };


    //透視投影変換行列を作る
    void create_matri_mp(float top, float bottom, float left, float right,float near, float far, float result[16]);

    bool LoadShader(const char* VertName, GLenum type_a, const char* FragName, GLenum type_b);


    //シェーダーを読み込んでコンパイルして適用
    bool CompileShader(const char *fileName, GLenum type);

    GLuint vbo = 0;//頂点配列バッファオブジェクト名
    GLuint vao = 0;//頂点バッファオブジェクト名    

    GLFWwindow* Window = nullptr;//OpenGLコンテキスト    

    GLuint ShaderProgram;//シェーダープログラム


    bool Shader();//シェーダ読み込み
    void Compile_log(GLuint Shader);//シェーダーコンパイルログ
    void Link_log(GLuint Shader);//シェーダーリンクログ

    void GetShader_Log(GLuint shader_type,GLuint Log_type);//ログ
};
#endif
#include "Game.hpp"

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "Vector.hpp"


//透視投影変換行列を作る
void Game::create_matri_mp(float top, float bottom, float left, float right,
    float near, float far, float result[16])
{
    result[0] = (2 * near) / (right - left);

    result[1] = 0;
    result[2] = 0;
    result[3] = 0;
    result[4] = 0;

    result[5] = (2 * near) / (top - bottom);

    result[6] = 0;
    result[7] = 0;

    result[8] = (right + left) / (right - left);

    result[9] = (top + bottom) / (top - bottom);

    result[10] = -(far + near) / (far - near);

    result[11] = -1;

    result[12] = 0;
    result[13] = 0;

    result[14] = -(2 * far * near) / (far - near);

    result[15] = 0;

}

//コンストラクタ
Game::Game()
{
    mIsRunLoop = true;

}

//メインループ
bool Game::RunLoop()
{
    if (mIsRunLoop == true)
    {
        Update();
        GenerateOutput();
    }
    else {
        return false;
    }
    return true;

}


//シェーダー関係のログを取得
void Game::GetShader_Log(GLuint shader_type, GLuint Log_type)
{
//文字数の関係で割愛
}

//シェーダー読み込みとコンパイル
bool Game::CompileShader(const char* fileName, GLenum type)
{  
    GLuint out_shader = glCreateShader(type);

    //シェーダーを読み込み 
    std::ifstream shaderfile(fileName);
    if (shaderfile.is_open())
    {
        std::stringstream sstream;
        sstream << shaderfile.rdbuf();
        std::string str = sstream.str();
        const char* cc = str.c_str();

        out_shader = glCreateShader(type);
        glShaderSource(out_shader, 1, &cc, nullptr);
        glCompileShader(out_shader);
        printf("ファイル読み込み成功: %s\n",fileName);

        GetShader_Log(out_shader, GL_COMPILE_STATUS);
        glAttachShader(ShaderProgram, out_shader);
        shaderfile.close();

        glDeleteShader(out_shader);

        return true;
    }
    else {
        shaderfile.close();

        printf("ファイル: %s が読み込めませんでした。", fileName);
        glDeleteShader(out_shader);

        return false;
    }

}


//シェーダー読み込み関数
bool Game::LoadShader(const char* VertName ,GLenum type_a, const char* FragName,GLenum type_b)
{

    //バーテックス
    if (CompileShader(VertName, type_a) == true) 
    {
        printf("成功: 頂点\n"); 
    }
    else {
        //return false;
        printf("失敗: 頂点\n");
    }

    //フラグメント
    if (CompileShader(FragName, type_b) == true) 
    {
        printf("成功: フラグメント\n"); 
    }
    else {
        printf("失敗: フラグメント\n");
        //return false;
    }


    //座標構造体
    struct position
    {
    public:
        float x;
        float y;
        float z;

        float w;
    };

    struct position pos;

    pos.x = 1.0f;
    pos.y = 0;
    pos.z = 0;

    pos.w = 1.0f;
    float r = 0.0f;

    float rotate[16] = {
        (pos.x * pos.x * (1 - cos(r)) + cos(r)),
        (pos.x * pos.y * (1 - cos(r)) - (pos.z * sin(r))),
        (pos.x * pos.z * (1 - cos(r)) + (pos.y * sin(r))),
        0,

        (pos.x * pos.y * (1 - cos(r)) + (pos.z * sin(r))),
        (pos.y * pos.y * (1 - cos(r)) + cos(r)),
        (pos.y * pos.z * (1 - cos(r)) - (pos.x * sin(r))),
        0,

        (pos.x * pos.z * (1 - cos(r)) - (pos.y * sin(r))),
        (pos.y * pos.z * (1 - cos(r)) + (pos.x * sin(r))),
        (pos.z * pos.z * (1 - cos(r)) + cos(r)),
        0,

        0,0,0,1
    };

    //スケール行列
    float scale[16] = {
        1,0,0,0,
        0,1,0,0,
        0,0,1,0,
        0,0,0,1
    };

    //平行移動
    struct position p;
    p.x = 0;
    p.y = 0;
    p.z = 0;
    p.w = 1;

    float move[16] =
    {
        1,0,0,0,
        0,1,0,0,
        0,0,1,0,
        p.x,p.y,p.z,1,
    };




/////////////////////////////////////////////////////////////////////////////////////////////////////////
    create_matri_mp(1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 10.0f, mp);//透視行列を作成


    glBindAttribLocation(ShaderProgram, 0, "Vertex");


    glUniformMatrix4fv(glGetUniformLocation(ShaderProgram, "scale"), 1, GL_TRUE, scale);
    glUniformMatrix4fv(glGetUniformLocation(ShaderProgram, "rotate"), 1, GL_TRUE, rotate);
    glUniformMatrix4fv(glGetUniformLocation(ShaderProgram, "move"), 1, GL_TRUE, move);
    glUniformMatrix4fv(glGetUniformLocation(ShaderProgram, "MP"), 1, GL_TRUE, mp);
////////////////////////////////////////////////////////////////////////////////////////////////////////

   // glLinkProgram(ShaderProgram);
 //   glUseProgram(ShaderProgram);

    return true;
}

//シェーダを実装する
bool Game::Shader()
{
    return true;
}


//初期化
bool Game::Initialization()
{
//初期化 関係
//------------------------------------------------------------------------------------------------------------------------------------------------
    //glfwの初期化に失敗
    if (glfwInit() != GL_TRUE)
    {
        printf("glfwInit()失敗\n");
        int _c = getchar();

        return 0;
    }

    //コンテキストを作成
    Window = glfwCreateWindow(640, 400, "Hello", NULL, NULL);

    //OpenGLコンテキストの作成に失敗
    if (Window == NULL)
    {
        printf("glfCreateWindow()失敗\n");
        int c = getchar();

        return 0;
    }

    //コンテキストをOpenGLの描画対象にする。
    glfwMakeContextCurrent(Window);

    //glewを初期化する。
    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK)
    {
        printf("glewInit() の初期化に失敗しました。");
        return 0;
    }

    //OpenGLバージョン指定
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 0);

    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    //垂直同期のタイミングを待つ
    glfwSwapInterval(1);
//------------------------------------------------------------------------------------------------------------------------------------------------




    if (LoadShader("Basic.vert", GL_VERTEX_SHADER, "Basic.frag", GL_FRAGMENT_SHADER) == true)//シェーダーを読み込む
    {
        printf("シェーダーを読み込む\n");
    }

    //頂点バッファvboを設定
    glGenVertexArrays(1, &vbo);
    glBindVertexArray(vbo);
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex), Vertex, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);
    glLinkProgram(ShaderProgram);
    glUseProgram(ShaderProgram);



    mIsRunLoop = true;
    return mIsRunLoop;
}

//アップデート
void Game::Update()
{
    if (glfwGetKey(Window, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(Window) != GL_FALSE)
    {
        mIsRunLoop = false;
    }



    if (glfwGetKey(Window, GLFW_KEY_UP) == GLFW_PRESS)
    {


    }else if (glfwGetKey(Window, GLFW_KEY_DOWN) == GLFW_PRESS)
    {

    }



}



//描画アップデート
void Game::GenerateOutput()
{
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glUseProgram(ShaderProgram);





    glDrawArrays(GL_POLYGON, 0, 6);






    glViewport(0, 0, WIDTH, HEIGHT);
    glfwSwapBuffers(Window);
    glfwPollEvents();

}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

いろんな引数,合ってますか?

glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex), Vertex, GL_STATIC_DRAW);

↑sizeof(Vertex)で良いか?

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

↑第二引数は3で合っているか?

glDrawArrays(GL_POLYGON, 0, 18);

↑最後の 18 とは何の値?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/09/18 12:00

    float Vertex[6][4] ← [4]にする必要って何ですか?

    キャンセル

  • 2020/09/18 15:22 編集

    質問ですがフラグメントシェーダーのコードはこれで正解なのでしょうか?

    キャンセル

  • 2020/09/18 17:29 編集

    //シェーダーを読み込み
    std::ifstream shaderfile(VertName);
    if (shaderfile.is_open())
    {
    std::stringstream sstream;
    sstream << shaderfile.rdbuf();
    std::string str = sstream.str();
    const char* cc = str.c_str();
    glShaderSource(out_vert_shader, 1, &cc, nullptr);
    glCompileShader(out_vert_shader);

    printf("ファイル読み込み成功: %s\n", VertName);

    GetShader_Log(out_vert_shader, GL_COMPILE_STATUS);
    glAttachShader(ShaderProgram, out_vert_shader);
    shaderfile.close();
    }
    else {
    shaderfile.close();
    printf("ファイル: %s が読み込めませんでした。", VertName);
    }
    を関数化せず一行にまとめたたら実行できました。今度は画面に何も表示されなくなったのですがひとまず解決とさせていただきます。

    キャンセル

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

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

関連した質問

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