OGLPlus を Windows で動かしてみた

OGLPlus に関してはここら辺を参照して下さい。
OGLplus はまだ Linux しかサポートされていませんが、無理やりがんばって Windows で動かしてみました。
glew が使える環境であれば多分問題ないはず…。

[手元の環境]


Windows の場合だと glew を使用しないとコンパイル出来ませんでした。
また、全てを動かすためには下記のサイトのような感じに OGLPlus のソースを直接修正する必要があります。


ちょっと量が多すぎるのでここでは書きませんが、だいたいのエラーは『関数ポインタ型を引数として受け取っている箇所』でエラーになっているので、typename Func などで受け取るようにすればたいていは動くようになると思います。

あと 0.5.0 だと #define near と名前が衝突するバグがあるので注意して下さい。
これを踏まえて Windows で動くソースは以下のような感じになりました。

[ソース]

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

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

#include <GL/Glut.h>

#include <memory>
#include <cstdlib>

namespace oglplus {

// example.hpp
struct Example
{
    virtual ~Example(void)
    { }

    // Hint for the main function whether to continue rendering
    // Implementations of the main function may choose to ignore
    // the result of this function
    virtual bool Continue(double duration)
    {
        return duration < 3.0; // [seconds]
    }

    virtual void Reshape(size_t width, size_t height) = 0;

    virtual bool UsesMouseMotion(void) const
    {
        return false;
    }

    virtual void MouseMoveNormalized(float x, float y, float aspect)
    {
    }

    virtual void MouseMove(size_t x, size_t y, size_t width, size_t height)
    {
        return MouseMoveNormalized(
            (float(x) - width * 0.5f) / (width * 0.5f),
            (float(y) - height* 0.5f) / (height* 0.5f),
            float(width)/height
        );
    }

    virtual void Render(double time) = 0;
};

std::shared_ptr<Example> makeExample(void);


// 001_triangle.cpp
class TriangleExample : public Example
{
private:
    // wrapper around the current OpenGL context
    Context gl;

    // Vertex shader
    VertexShader vs;

    // Fragment shader
    FragmentShader fs;

    // Program
    Program prog;

    // A vertex array object for the rendered triangle
    VertexArray triangle;
    // VBO for the triangle's vertices
    Buffer verts;
public:
    TriangleExample(void)
    {
        // Set the vertex shader source
        vs.Source(" \
            #version 330\n \
            in vec3 Position; \
            void main(void) \
            { \
                gl_Position = vec4(Position, 1.0); \
            } \
        ");
        // compile it
        vs.Compile();

        // set the fragment shader source
        fs.Source(" \
            #version 330\n \
            out vec4 fragColor; \
            void main(void) \
            { \
                fragColor = vec4(1.0, 0.0, 0.0, 1.0); \
            } \
        ");
        // 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
        triangle.Bind();

        GLfloat triangle_verts[9] = {
            0.0f, 0.0f, 0.0f,
            1.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f
        };
        // bind the VBO for the triangle vertices
        verts.Bind(Buffer::Target::Array);
        // upload the data
        Buffer::Data(Buffer::Target::Array, 9, triangle_verts);
        // setup the vertex attribs array for the vertices
        VertexAttribArray vert_attr(prog, "Position");
        vert_attr.Setup(3, DataType::Float);
        vert_attr.Enable();

        gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.ClearDepth(1.0f);
    }

    void Reshape(size_t width, size_t height)
    {
        gl.Viewport(width, height);
    }

    void Render(double)
    {
        gl.Clear().ColorBuffer().DepthBuffer();

        gl.DrawArrays(PrimitiveType::Triangles, 0, 3);
    }
};

std::shared_ptr<Example> makeExample(void)
{
    return std::unique_ptr<Example>(new TriangleExample);
}

} // namespace oglplus


std::shared_ptr<oglplus::Example> example;

void
display(){
    example->Render(0.0);
    glutSwapBuffers();
    glFlush();
}

void
resize(int w, int h){
    example->Reshape(w, h);
}

void
idle(){
    glutPostRedisplay();
}

int
main(int argc, char *argv[]){
    
    // glut の初期化
    glutInit(&argc, argv);
    glutInitWindowSize(500, 500);
    glutCreateWindow(argv[0]);
    glutDisplayFunc(display);
    glutReshapeFunc(resize);
    glutIdleFunc(idle);
    glutPostRedisplay();

    // glew の初期化
    auto err = glewInit();
    if (err != GLEW_OK)
    {
        fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
    }

    // glew の初期化後にインスタンスを生成
    example = oglplus::makeExample();
    
    // メインループ
    glutMainLoop();
    return 0;
}

[出力]


ウィンドウ周りの処理は glut を使用して描画を行っています。
OGLPlus の処理は example 001_triangle.cpp をそのまま使用しています。
全部試したわけじゃないですがだいたいの example は動くかな?
動かすまでは大変ですが、サンプルとかは結構充実しているので色々と遊べると思います。


と、まぁこんな感じでまだ色々と大変ですが、こういうコアなライブラリが C++11 が書かれていれば C++11 を使用するきっかけになると思うので頑張って欲しいですね。