Cài đặt OpenGL với Visual Studio 2013 (Community Edition), GLFW3, GLEW và GLM

Dùng từ “cài đặt” ở đây để chỉ cách thiết lập OpenGL trên các IDEs phổ biến/dễ sử dụng nhất. Trong bài viết này mình chỉ hướng dẫn cài đặt OpenGL trên các hệ điều hành phổ biến: Windows, Linux (Kubuntu 14.04.1 LTS); các IDEs: Microsoft Visual Studio 2013 (Community Edition).

Vì OpenGL không có các công cụ quản lý riêng để quản lý input, windowing, network, physics và sound riêng nên chúng ta sẽ sử dụng các thư viện ngoài để hỗ trợ. Chúng bao gồm

  • GLFW3, GLM (OpenGL Mathematics), GLEW (OpenGL Extension Wrangler)/glbinding
  • Physics engine. Chúng ta sẽ sử dụng Bullet.

Chúng ta sẽ sử dụng ngôn ngữ C(++) chính để viết các chương trình OpenGL. Với Kubuntu, mình sẽ dùng Geany và build các thư viện GLFW, GLEW riêng, vì những thư viện này không có repository riêng hoặc repository của chúng chỉ chứa các phiên bản cũ.

Cài đặt OpenGL trên Microsoft Windows/Microsoft Visual Studio 2013 (Community Edition)

Microsoft đã chính thức ngừng hỗ trợ OpenGL từ sau khi project Farenheit thất bại - một sự hợp tác giữa SGI (tác giả những phiên bản đầu tiên của OpenGL) và Microsoft trong việc kết hợp OpenGL và Direct3D thành một graphics API thống nhất. Đó là lý do vì sao trong phiên bản mới nhất của MSVC - trình biên dịch chuẩn của Visual Studio, vẫn còn sử dụng OpenGL 1.x. Để sử dụng OpenGL 4.3, ta dùng GLEW. Tác dụng của GLEW để load các extensions của các phiên bản OpenGL từ 1.0 -> 4.5, và kiểm tra xem extensions có hỗ trợ trên card đồ họa không.

Lý do mình dùng GLEW không phải vì nó phổ biến, mà là vì:

  • Chúng ta đang dùng C trộn với một ít C++, vì dù sao OpenGL cũng rất hay được viết bằng C (thuần), và cách làm việc của OpenGL cũng hướng theo kiểu state-based (mình sẽ giải thích sau).
  • Sử dụng GLEW rất dễ, để khởi động GLEW chỉ cần một vài dòng lệnh.
  • Bạn không muốn viết các code lấy các tính năng của OpenGL 4.3. GLEW sẽ làm việc này.

Download GLEW ở đây: https://sourceforge.net/projects/glew/files/glew/1.12.0/glew-1.12.0-win32.zip/download

Tạo solution trên Visual Studio 2013 (Community Edition)).
Màn hình chính của VS2013 sau khi khởi động.

Chọn File->New->Project hoặc Ctrl + Shift + N.

Thêm một source code vào thư mục chính. Ctrl + Shift + A và thử một vài dòng code xem nào: (đặt tên file là main.cpp)

Có vẻ ổn. Bây giờ bạn tạo một folder với tên “Dependencies” trong thư mục gốc của project (không phải thư mục gốc của solution!). Đây sẽ là nơi mà chúng ta bỏ các headers của GLEW (và những thứ khác nữa) vào. Mục đích của việc này là để tránh phải phụ thuộc vào các path sẵn có của Visual Studio. Nếu chẳng may phải cài lại Windows thì chúng ta cũng phải chép lại thư viện vào những nơi đó, vốn rất bất tiện để quản lý (và phân phối source code sau này).

Giải nén GLEW. Chép những headers trong /include và thư viện /lib/Release/Win32 vào thư mục Dependencies (glew32.libglew32s.lib), và glew32.dll trong /bin/Release/Win32 vào thư mục Debug của solution.

GLFW

Đây là thư viện phụ trách việc quản lý cửa sổ, context, mở OpenGL profile, input handling, và nhiều thứ khác.

Download: https://github.com/glfw/glfw/releases/download/3.1.1/glfw-3.1.1.bin.WIN32.zip

Ném nội dung folder /include vào Dependencies.
Chép hai file từ /lib-vc2013 vào Dependencies, và file DLL còn lại (glfw3.dll) vào thư mục Debug (nằm ở trong folder solution).

GLM (OpenGL Mathematics)

Đây là thư viên chứa các kiểu dữ liệu và các phép toán trên các kiểu dữ liệu: vectors, matrices (phổ biến nhất). Bắt đầu từ modern OpenGL, OpenGL sẽ không tích hợp các công cụ này mà tự developers phải quản lý lấy. Rất may cho chúng ta là những thư viện như vậy đã có sẵn, không cần phải viết lại.

Download: http://sourceforge.net/projects/ogl-math/files/glm-0.9.6.3/glm-0.9.6.3.zip/download

Giải nén và chép cả folder glm vào Dependencies.

Sau khi giải nén và chép mọi thứ, thư mục Dependencies của bạn sẽ trông như thế này.

Được rồi, mở Visual Studio, mở solution cũ của chúng ta, click phải vào project và chọn Properties, rồi click vào VC++ Directories.

Mở “Include Directories” và chọn Edit. Ở đây chúng ta sẽ cung cấp nội dung của thư mục “Dependencies” để Visual Studio có thể tìm kiếm nội dung (headers, libraries) trong thư mục này. Trong hộp thoại mở ra, nhấn vào biểu tưởng màu vàng, nhập:
$(SolutionDir)\Dependencies

$(SolutionDir) tựa như một biến môi trường (environment variable), nó trỏ tới thư mục gốc của solution. Chúng ta chỉ cần thêm \Dependencies để nó có thể trỏ tới thư mục Dependencies. Visual Studio sẽ tìm headers trong thư mục này ($(SolutionDir)\Dependencies).

Làm tương tự với Library Directories.

Tại sao không cất “Dependencies” vào $(ProjectDir) (trỏ tới thư mục Project) mà phải dùng $(SolutionDir)? Well, chúng ta sẽ “share” những thư viện này trong solution cho các projects khác nhau ở solution đó có thể cùng dùng, chứ không cất riêng ở một project nào đó.

Mở file main.cpp, nhập:

#include <cstdio> /* printf() */

#include "..\Dependencies\GL\glew.h"
#include "..\Dependencies\GLFW\glfw3.h"
#include "..\Dependencies\glm\glm.hpp"

/*
 * Links các thư viện của OpenGL, GLEW và GLFW3.
 * Ta không dùng dấu .., / để chỉ định thư mục vì ta đã chỉ định các thư mục cần tìm kiếm lúc nãy *chỉ lên trên*
 */
#pragma comment(lib, "glew32.lib")
#pragma comment(lib, "OpenGL32.lib")
#pragma comment(lib, "GlU32.lib")
#pragma comment(lib, "glfw3.lib")

int main(int argc, char *argv[])
{
    /* Cài đặt GLFW3, sử dụng OpenGL 4.3, với khứ răng cưa bốn mẫu.
     * Lưu ý, đây chỉ là hint, không phải mệnh lệnh bắt buộc.
     */
    GLenum glfwSuccess = glfwInit();
    if(glfwSuccess) printf("-- Tải thành công GLFW3. --\n");

    glfwWindowHint(GLFW_SRGB_CAPABLE, GL_FALSE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    glfwWindowHint(GLFW_DECORATED, GL_TRUE);
    glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

    GLFWmonitor *monitor = glfwGetPrimaryMonitor();
    const GLFWvidmode *ClientVideoMode = glfwGetVideoMode(monitor);

    GLFWwindow *GLWindow = glfwCreateWindow(ClientVideoMode->width, ClientVideoMode->height, "GLWindow", monitor, NULL);
    glfwMakeContextCurrent(GLWindow);

    /* Cài đặt GLEW. */
    glewExperimental = GL_TRUE;
    GLenum glewSuccess = glewInit();
    if(glewSuccess) printf("-- Tải thành công GLEW (%s) --", glewGetString(GLEW_VERSION));

    return 0;
}

Nếu chương trình biên dịch thành công, chạy nó và bạn sẽ thấy một cửa sổ lớn bằng màn hình nháy lên và sau đó tắt. Vậy là ta đã hoàn tất việc cài đặt.