前回までは頂点を入力にしていたが、三角形を入力する場合はGL_GEOMETRY_INPUT_TYPEにGL_TRIANGLESを指定、GL_GEOMETRY_OUTPUT_TYPEにはGL_TRIANGLE_STRIPを指定する。
https://suzulang.com/glsl-9-geometry-shader-1
//! @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(); }