Skip to main content

开始使用

我们的教程从建立一个空白的渲染窗口开始,这虽然是最简单的,却包含了丰富的知识点:

  • 如何利用GLFW
  • 建立绘制窗口
  • 设置窗口的背景(渲染舞台)
  • 构造场景
  • 绘制场景

利用GLFW

在我们的教程中借助了GLFW库,它可以创建并管理渲染窗口和OpenGL上下文,同时还提供了处理键盘和鼠标输入的功能。

在本教程中将与GLFW相关的程序都封装在了window.h中。这里,我们定义了一个类:GLWindow,它具备了以下一些功能:


#pragma once

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <string>
#include <functional>

class GLWindow
{
public:
// 以下函数可用于在后续的案例程序中定义当鼠标被操纵时发生的响应事件。
std::function<void(MouseEvent* event)> onMouseDown;
std::function<void(MouseEvent* event)> onMouseUp;
std::function<void(MouseEvent* event)> onMouseMove;
std::function<void(MouseEvent* event)> onMouseDrag;
std::function<void(WheelEvent* event)> onWheel;
std::function<void(ResizeEvent* event)> onResize;
public:
// 初始化一个渲染窗口,并完成关键的OpenGL参数设置
GLWindow();
virtual ~GLWindow();
void setTitle(const std::string& title);
std::string title();
void setSize(int w, int h);
cil::Vector2i size();
cil::Vector2i pixelSize();
// 该函数可以确保最新的图像显示在屏幕上。
void flush();
// 是一个无限循环,直到窗口被关闭。当窗口没有被关闭时,会检查键盘、鼠标和其他输入设备的状态,并将这些消息传递给应用程序。
void exec();
}

建立绘制窗口

我们在主程序中,引入了上文介绍的window.h,另外我们还需要引入包含了illustrator的核心模块和各种插件的头文件。可以参考下面的代码:

#include "../common/window.h"
#include "../common/stb_image.h" // 处理导入外部的图片文件
#include "cilcore.h"
#include "cilcamera.h" // 按照实际的业务需求选择包含camera插件

初始化窗口

利用window.h中定义的GLWindow类,定义一个窗口,并且为它定义窗口名称。

int main() {

GLWindow window;
window.setTitle("tutorial01_blank");
// 获取窗口的大小
auto pixelSize = window.pixelSize();

...

window.exec();
return 0;
}

设置屏幕背景

利用_simpleBackground接口来创建一个background对象,它包含的成员变量有:屏幕大小、背景颜色、DepthMask、stencilMask、坐标系。一般您只需要提供屏幕大小和背景颜色两个参数。

	auto background = _simpleBackground(_ivec2(pixelSize), _clr4(0.9, 0.8, 0.7, 1.0));

构造场景

在第一章中我们介绍了场景树组织,其中渲染通道是一个与场景管理相关的概念,它具备独立的背景、摄像机和渲染节点。因此,我们将屏幕背景作为一个输入参数,来创建一个渲染通道也就是pass对象。

	// 这个渲染通道中,我们只设置了背景
auto pass = _pass(nullptr, background);
// 该渲染通道构成了等待绘制的渲染场景
auto scene = _scene({ pass });

绘制场景

尽管我们目前只在场景中添加了一个背景对象,但足够我们来学习如何去绘制一个渲染场景。您需要创建一个指向渲染器对象的智能指针renderer,当窗口没有被关闭时,主程序会一直更新窗口中的渲染场景,比如当用户修改窗口大小,程序会响应Resize事件,立即再次绘制场景。

	auto renderer = std::make_shared<Renderer>();

// 绘制场景,形成图像缓冲区
renderer->render(scene);
// 将图像显示在屏幕上
window.flush();

window.onResize = [&](ResizeEvent* event) -> void {
auto pixelSize = window.pixelSize();
*background->size = pixelSize;
renderer->render(scene);
window.flush();
};