Shader开发(八)创建第一个三角形
在上一节中,我们成功搭建了openFrameworks开发环境。现在,让我们迈出Shader开发的关键一步——创建第一个三角形网格。三角形是3D图形学的基础单元,掌握三角形的创建和渲染,就为后续的复杂Shader开发奠定了坚实基础。
创建三角形网格
在 openFrameworks 中,ofMesh
类用于定义和操作网格。要创建一个三角形,我们需要:
使用
ofMesh
的默认构造函数初始化一个网格对象。通过
addVertex()
方法添加三个顶点,每个顶点由glm::vec3
表示(openFrameworks 使用 GLM 库处理向量)。
以下是创建三角形的代码:
void ofApp::setup(){ofMesh triangle;triangle.addVertex(glm::vec3(0.0, 0.0, 0.0)); // 左下角顶点triangle.addVertex(glm::vec3(0.0, 768.0f, 0.0)); // 左上角顶点triangle.addVertex(glm::vec3(1024.0, 768.0, 0.0)); // 右上角顶点
}
代码解析:
glm::vec3
:三维向量,表示顶点的(x, y, z)坐标坐标系统:屏幕像素坐标系,原点在左上角
Z坐标:暂时设为0,表示在屏幕平面上
💡 重要提示:这段代码创建了网格,但还无法在屏幕上看到效果,我们需要在渲染函数中绘制它。
绘制三角形
理解渲染循环
openFrameworks采用事件驱动的渲染架构:
setup():初始化阶段,只执行一次
draw():渲染阶段,每帧执行一次
修改代码结构
为了在draw()函数中访问三角形,我们需要调整代码结构:
ofApp.h文件修改:
#pragma once#include "ofMain.h"class ofApp : public ofBaseApp{public:void setup() override;void update() override;void draw() override;void exit() override;// ....// 以上代码保持不变 private:ofMesh triangle; // 将三角形声明为成员变量};
ofApp.cpp文件修改:
void ofApp::setup(){// 在成员变量上创建三角形triangle.addVertex(glm::vec3(0.0, 0.0, 0.0));triangle.addVertex(glm::vec3(0.0, 768.0f, 0.0));triangle.addVertex(glm::vec3(1024.0, 768.0, 0.0));
}void ofApp::draw(){triangle.draw(); // 每帧绘制三角形
}
默认着色器
当我们调用triangle.draw()
时,openFrameworks会:
应用默认着色器:包含顶点着色器和片元着色器
坐标变换:将顶点坐标转换为屏幕像素坐标
默认颜色:渲染为白色实心形状
运行程序后,你将看到一个白色三角形,背景为灰色。
一个白色三角形遮住了一半的窗口
屏幕坐标系
openFrameworks 基于 OpenGL,其屏幕坐标系的原点在左上角。
OpenGL屏幕坐标系特点:
坐标轴 | 方向 | 说明 |
---|---|---|
X轴 | 向右为正 | 0到窗口宽度 |
Y轴 | 向下为正 | 0到窗口高度 |
原点 | 左上角 | (0, 0) |
我们的三角形顶点分析:
(0, 0, 0)
:屏幕左上角(0, 768, 0)
:屏幕左下角(1024, 768, 0)
:屏幕右下角
💡 坐标系提醒:Y轴向下为正可能与数学坐标系不同,这是计算机图形学的标准约定。
通过按键移动顶点
为了加深对坐标系的理解,我们可以通过按键事件动态修改顶点位置。以下代码展示如何在按键时将三角形的右上角顶点向上移动:
void ofApp::keyPressed(int key){// 获取第三个顶点(右下角)的当前位置glm::vec3 curPos = triangle.getVertex(2);// 每次按键向上移动20像素(Y坐标减少)triangle.setVertex(2, curPos + glm::vec3(0, -20, 0));
}
代码功能:
getVertex(2)
:获取索引为2的顶点(第三个顶点)setVertex(2, newPos)
:更新顶点位置glm::vec3(0, -20, 0)
:Y轴负方向移动(向上)
随意键盘上任意按键后,三角形显示如下图所示:
准备编写自定义着色器
掌握网格操作后,下一步是学习自定义着色器。着色器是运行在 GPU 上的程序,用于控制顶点和像素渲染。后续教程将介绍如何替换默认着色器,创建自定义视觉效果。