OGLplus で複数の△ポリゴンの描画

oglplus/001_triangle.cpp をベースにして複数のポリゴン描画を行ってみました。

[ソース]

#include <vector>

#define GL_VERSION_4_1
#include <GL/glew.h>

#include <oglplus/gl.hpp>
//#include <oglplus/all.hpp>

#include <oglplus/context.hpp>
#include <oglplus/buffer.hpp>
#include <oglplus/vertex_attrib.hpp>
#include <oglplus/vertex_array.hpp>
#include <oglplus/shader.hpp>
#include <oglplus/program.hpp>

#include <GL/Glut.h>

#include <cstdlib>
#include <gl/graphics.hpp>
#include <boost/thread.hpp>

namespace glp = oglplus;
typedef glp::Context glc;

struct triangle : boost::noncopyable{
    
    triangle(std::initializer_list<GLfloat> triangle_verts){
        // Set the vertex shader source
        vs.Source(R"delimiter(
            #version 330
            in vec3 Position;
            void main(void){
                gl_Position = vec4(Position, 1.0);
            }
        )delimiter");
        
        // compile it
        vs.Compile();

        // set the fragment shader source
        fs.Source(R"delimiter(
            #version 330
            out vec4 fragColor;
            void main(void){
                fragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }
        )delimiter");
        // compile it
        fs.Compile();

        // attach the shaders to the program
        prog.AttachShader(vs);
        prog.AttachShader(fs);
        // link and use it
        prog.Link();
        prog.Use();

        // bind the VAO for the triangle
        vertex_array.Bind();

        // bind the VBO for the triangle vertices
        verts.Bind(glp::Buffer::Target::Array);
        // upload the data
        glp::Buffer::Data(glp::Buffer::Target::Array,
            triangle_verts.size(),
            triangle_verts.begin()
        );
        // setup the vertex attribs array for the vertices
        glp::VertexAttribArray vert_attr(prog, "Position");
        vert_attr.Setup(3, glp::DataType::Float);
        vert_attr.Enable();
    }
    
    void
    render() const{
        vertex_array.Bind();
        glc::DrawArrays(glp::PrimitiveType::Triangles, 0, 3);
    }
private:
    // Vertex shader
    glp::VertexShader vs;

    // Fragment shader
    glp::FragmentShader fs;

    // Program
    glp::Program prog;

    // A vertex array object for the rendered triangle
    glp::VertexArray vertex_array;
    // VBO for the triangle's vertices
    glp::Buffer verts;
};


int
main(int argc, char *argv[]){
    namespace glp = oglplus;
    typedef glp::Context glc;
    
    gl::graphics g(argc, argv, 500, 500, "test");
    
    // glew の初期化
    auto err = glewInit();
    if (err != GLEW_OK)
    {
        fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
    }
    
    glc::ClearColor(0.5f, 0.7f, 0.9f, 1.0f);
    glc::ClearDepth(1.0f);

    // △ポリゴンの生成
    triangle obj1({
        0.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f
    });

    triangle obj2({
         0.0f,  0.0f, 0.0f,
        -1.0f,  0.0f, 0.0f,
         0.0f, -1.0f, 0.0f
    });
    //-------------------------------------------------------------------------
    
    gl::displayfunc(g, [&](){
        glc::Clear().ColorBuffer().DepthBuffer();
        obj1.render();
        obj2.render();
    });
    
    gl::reshapefunc(g, [&](int width, int height){
        glc::Viewport(width, height);
    });

    // キー入力イベント
    gl::keyboardfunc(g, [](unsigned char key, int x, int y){
        if(key == 'q') return exit(0);
    });

    // idle
    gl::idlefunc(g, [&](){
        boost::this_thread::sleep(boost::posix_time::milliseconds(16));
        glutPostRedisplay();
    });

    g.run();
    
    return 0;
}

[出力]

描画方法はちょっと変えましたが、大まかな処理はそのままです。
glut の描画処理は、以前 Boost.Geometry で使用したライブラリを使っています。

OpenGL 側の描画処理はまだよく分かっていないですね…。
VAO?VBO? なにそれおいしいの。
Bind とかさっぱり分からん…。


あと上記の場合だとシェーダプログラムが重複しているので Boost.Flyweight とか使ってみたいですね。

[OGLplus]

  • 0.4.0