当前位置: 首页 > news >正文

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 上的程序,用于控制顶点和像素渲染。后续教程将介绍如何替换默认着色器,创建自定义视觉效果。

http://www.lryc.cn/news/611711.html

相关文章:

  • 微信小程序多媒体功能实现
  • 微信小程序初次运行项目失败
  • 深入理解SpringMVC DispatcherServlet源码及全流程原理
  • 开发教育全链路管理系统 + 微信小程序,为各类教育主体注入数字化动力!
  • [LVGL] 配置lv_conf.h | 条件编译 | 显示屏lv_display
  • 微信小程序中使用TensorFlowJS从环境搭建到模型训练及推理模型得到预测结果
  • Python驱动的无人机多光谱-点云融合技术在生态三维建模与碳储量/生物量/LULC估算中的全流程实战
  • 无人机航拍数据集|第5期 无人机高压输电线铁塔鸟巢目标检测YOLO数据集601张yolov11/yolov8/yolov5可训练
  • 大疆无人机连接Jetson主板
  • 【CUDA】C2 矩阵计算
  • conda 环境配置国内镜像加速(2025)
  • Conda虚拟环境安装包
  • DNS 服务器
  • 服务器巡检项目
  • Dart语言“跨界”指南:从JavaScript到Kotlin,如何用多语言思维快速上手
  • C++ - 仿 RabbitMQ 实现消息队列--服务器模块实现
  • Linux网络编程基础-简易TCP服务器框架
  • 服务器——“查询不到显卡驱动,且输入nvidia-smi报错”的解决办法
  • Docker的安装,服务器与客户端之间的通信
  • copy_file_range系统调用及示例
  • 【网络运维】Linux:简单DHCP服务器的部署
  • Profinet转Ethernet IP网关接入五轴车床上下料机械手控制系统的配置实例
  • 03-mysql/redis/apache安装记录
  • 开疆智能ModbusTCP转Profinet网关连接安川YRC1000机器人配置案例
  • PHP官方及第三方下载地址全指南(2025最新版)
  • apache-superset config.py、superset_config.py完整配置项解读
  • SQL的条件查询
  • SQL120 贷款情况
  • CSS高频属性速查指南
  • 基于智能体技术的AIGC源码