Mugichoko's blog

Mugichoko’s blog

プログラミングを中心としたメモ書き.

GLSL #3: 固定パイプラインを使った三角形の描画

目標

GLFWを使って作成したウィンドウ(下記の前回記事参照)に,固定パイプラインを使って三角形を描画する.ここで初めてGLEWを使います.

mugichoko.hatenablog.com

実装環境

GLEWのダウンロード

  1. ここから「glew-1.13.0.zip」をダウンロード
  2. 「C:\Libraries\」に「glew-1.13.0」フォルダを解凍
    • 以降,この「C:\Libraries\glew-1.13.0」を「Path」と呼ぶ

Visual Studioのプロジェクト作成

  1. Visual Studioを開いて「新しいプロジェクト」を作成
  2. 「インクルードディレクトリ」に以下を追加
    • Path\include
  3. 「ライブラリディレクトリ」に以下を追加
    • Debug: Path\lib\Debug
    • Release: Path\lib\Release
  4. 「追加の依存ファイル」に必要なライブラリを追加
    • Debug: glew32d.lib
    • Release: glew32.lib

尚,GLFWの設定に関しては,過去の記事を参照のこと.

サンプルプログラム

window.h

ウィンドウの基底クラスを記述したヘッダファイル.前回から,変更なし.

//
// window.h
//

// 前回から変更なし

window.cpp

ウィンドウの基底クラスを記述したソースファイル.コンストラクタ内に,GLEWの初期化処理を追加した.

//
// window.cpp
//
#include "window.h"

namespace gl
{
    window::window(
        int w,
        int h,
        const string &name
    ) : name(name)
    {
        width = w;
        height = h;

        try
        {
            // ----- Initialize GLFW 3
            // Initialize the library
            if (!glfwInit())
            {
                throw "Failed to initialize GLFW 3...";
            }
            // Create a window
            wnd = glfwCreateWindow(w, h, name.c_str(), NULL, NULL);
            if (!wnd)
            {
                glfwTerminate();
                throw "Failed to create a window...";
            }
        }
        catch (string e)
        {
            cerr << "Error: " << e.c_str() << endl;
            exit(EXIT_FAILURE);
        }

        glfwMakeContextCurrent(wnd);

        setCallbacks();

        // ----- Initialize GLEW
        try
        {
            if (glewInit() != GLEW_OK)
            {
                glfwTerminate();
                throw "Failed to initialize GLEW...";
            }
        }
        catch (string e)
        {
            cerr << "Error: " << e.c_str() << endl;
            exit(EXIT_FAILURE);
        }

        // ----- Version check
        cout << "Vendor: " << glGetString(GL_VENDOR) << endl;
        cout << "Renderer: " << glGetString(GL_RENDERER) << endl;
        cout << "Version: " << glGetString(GL_VERSION) << endl;
        cout << "GLSL: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl;
        cout << endl;
    }

    window::~window()
    {
        if (wnd)
        {
            glfwTerminate();
        }
    }

    // ----- Callbacks
    void window::setCallbacks()
    {
        // Register this pointer
        glfwSetWindowUserPointer(wnd, this);
        // Error
        glfwSetErrorCallback(errorCallback);
        // Key
        glfwSetKeyCallback(wnd, keyCallback);
        // Scroll
        glfwSetScrollCallback(wnd, scrollCallback);
    }
    // Error
    void window::errorCallback(
        int err,
        const char *desc
    )
    {
        cerr << desc << endl;
    }
    // Key
    void window::keyCallback(
        GLFWwindow* window,
        int key,
        int scancode,
        int action,
        int mods
    )
    {
        if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
        {
            glfwSetWindowShouldClose(window, GL_TRUE);
        }
    }
    // Scroll
    void window::scrollCallback(
        GLFWwindow* window,
        double xoffset,
        double yoffset
    )
    {
        // Get arbitrary pointer
        gl::window* _this = static_cast<gl::window*>(glfwGetWindowUserPointer(window));

        _this->xoffset = xoffset;
        _this->yoffset = yoffset;
    }
}

main.cpp

MyWindow::render関数内に,固定パイプラインを用いた三角形の描画に関する記述を追加した.

//
// main.cpp
//
#include "window.h"

class MyWindow : gl::window
{
public:
    MyWindow(
        int w,
        int h,
        const string name
    ): window(w, h, name)
    {
    }

    void render()
    {
        // Rendering loop
        glClearColor(0.3f, 0.5f, 0.8f, 0.0f);
        while (!glfwWindowShouldClose(wnd))
        {
            // Clear color and depth buffers
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

            // Draw
            glLoadIdentity();
            glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f);

            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            glRotatef((float)glfwGetTime() * 50.f, 0.f, 0.f, 1.f);

            glBegin(GL_TRIANGLES);
            glColor3f(1.f, 0.f, 0.f);
            glVertex3f(-0.6f, -0.4f, 0.f);
            glColor3f(0.f, 1.f, 0.f);
            glVertex3f(0.6f, -0.4f, 0.f);
            glColor3f(0.f, 0.f, 1.f);
            glVertex3f(0.f, 0.6f, 0.f);
            glEnd();

            // Swap front and back buffers
            glfwSwapBuffers(wnd);
            // Poll for and process events
            glfwPollEvents();
        }
    }
};

int main()
{
    MyWindow wnd(640, 480, "GLFW 3 Window");
    wnd.render();

    return 0;
}

結果

動いた!目標達成です.カラフルな三角形がゆっくりと回転します.

f:id:Mugichoko:20170515133214j:plain