スポンサーリンク

GLSLを試す (9) Geometry Shader(4)- 三角形一枚から三角形一枚

前回までは頂点を入力にしていたが、三角形を入力する場合はGL_GEOMETRY_INPUT_TYPEにGL_TRIANGLESを指定、GL_GEOMETRY_OUTPUT_TYPEにはGL_TRIANGLE_STRIPを指定する。

https://suzulang.com/glsl-9-geometry-shader-1

C++側 ジオメトリシェーダの設定

//! @brief プログラムのリンクを行う(geometryシェーダ使用時)。
//! @details ジオメトリシェーダがある場合はglLinkProgramの前に設定を行わなければいけない。
//! 別に関数を用意した方がわかりやすいのでここではこれを使う
GLSLCompileCond link_program_with_geometry(
    GLuint* ProgramID,
    GLuint vertexShaderID,
    GLuint geometryShaderID,
    GLuint fragmentShaderID,
    std::string* error = nullptr) {

    GLint Result = GL_FALSE;
    int InfoLogLength;

    ////////////////////////////////////////
    // プログラムをリンクします。
    *ProgramID = glCreateProgram();

    glAttachShader(*ProgramID, vertexShaderID);
    glAttachShader(*ProgramID, geometryShaderID);
    glAttachShader(*ProgramID, fragmentShaderID);


    ////////////////////////////////////////
    // ジオメトリシェーダを使うときの設定をここでする
    // この作業は glAttachShaderとglLinkProgramの間に入れる
    glProgramParameteri(*ProgramID, GL_GEOMETRY_VERTICES_OUT, 3);//ジオメトリシェーダからの最大出力頂点数
    //glProgramParameteri(*ProgramID, GL_GEOMETRY_INPUT_TYPE, GL_POINTS);
    //glProgramParameteri(*ProgramID, GL_GEOMETRY_OUTPUT_TYPE, GL_POINTS);
    glProgramParameteri(*ProgramID, GL_GEOMETRY_INPUT_TYPE, GL_TRIANGLES);//ジオメトリシェーダには三角形が入力される
    glProgramParameteri(*ProgramID, GL_GEOMETRY_OUTPUT_TYPE, GL_TRIANGLE_STRIP);//ジオメトリシェーダからは三角形が出力される

    glLinkProgram(*ProgramID);

    ////////////////////////////////////////
    // プログラムをチェックします。
    glGetProgramiv(*ProgramID, GL_LINK_STATUS, &Result);
    glGetProgramiv(*ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    std::vector<char> ProgramErrorMessage((std::max)(InfoLogLength, int(1)));
    glGetProgramInfoLog(*ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);

    if (error) {
        *error = &ProgramErrorMessage[0];

        return GLSLCompileCond::LINK_ERROR;
    }

    return GLSLCompileCond::SUCCESS;
}
//描画関数
void disp(void) {

    glViewport(0, 0, width, height);

    glClearColor(0.2, 0.2, 0.2, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram(programID);
    GLuint loc_ModelViewMatrix = glGetUniformLocation(programID, "ModelViewMatrix");
    GLuint loc_ProjectionMatrix = glGetUniformLocation(programID, "ProjectionMatrix");


    glUniformMatrix4fv(loc_ModelViewMatrix, 1, GL_FALSE, mmodel);
    glUniformMatrix4fv(loc_ProjectionMatrix, 1, GL_FALSE, mproj);

    {
        glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);

        auto bindbufP = EnableAndBindFArrayBuffer(0, buf_points, 3, GL_FLOAT);
        auto bindbufC = EnableAndBindFArrayBuffer(1, buf_colors, 3, GL_FLOAT);

        //glDrawArrays(GL_POINTS, 0, 3);
        glDrawArrays(GL_TRIANGLES, 0, 3);

    }
    glFlush();
}

ジオメトリシェーダ

ジオメトリシェーダだけをこのように変更する

#version 460

layout (triangles) in; //入力は三角形
layout (triangle_strip) out; //出力も三角形

layout (max_vertices = 3) out;

//geometry shaderへの入力は配列で受け取らなければいけない
//ただし名前はvertex shader側のoutと一致させる
in vec4 vertexColor[]; 

// 出力は普通。名前はfragment shader側のinと一致させる
out vec4 vColor;

void main()
{

    gl_Position = gl_in[0].gl_Position;
    vColor = vertexColor[0];
    EmitVertex();
    gl_Position = gl_in[1].gl_Position;
    vColor = vertexColor[1]*0.1;
    EmitVertex();
    gl_Position = gl_in[2].gl_Position;
    vColor = vertexColor[2]*0.1;
    EmitVertex();
    EndPrimitive();
}

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: