惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Security Latest
Security Latest
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
N
Netflix TechBlog - Medium
GbyAI
GbyAI
云风的 BLOG
云风的 BLOG
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
C
Cyber Attacks, Cyber Crime and Cyber Security
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Threat Research - Cisco Blogs
NISL@THU
NISL@THU
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
J
Java Code Geeks
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MyScale Blog
MyScale Blog
T
Tor Project blog
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
P
Privacy & Cybersecurity Law Blog
MongoDB | Blog
MongoDB | Blog
Simon Willison's Weblog
Simon Willison's Weblog
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
小众软件
小众软件
G
GRAHAM CLULEY
P
Privacy International News Feed
AWS News Blog
AWS News Blog
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
人人都是产品经理
人人都是产品经理
S
Schneier on Security
Scott Helme
Scott Helme
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
T
The Exploit Database - CXSecurity.com
Recent Announcements
Recent Announcements
E
Exploit-DB.com RSS Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
U
Unit 42
The Register - Security
The Register - Security
S
Securelist
Martin Fowler
Martin Fowler
Project Zero
Project Zero
大猫的无限游戏
大猫的无限游戏
Cisco Talos Blog
Cisco Talos Blog

博客园 - 西北逍遥

实验启动指令 yolov8-pose监测人体关节并保存关节坐标 kinova jaco2 机械臂控制器故障灯闪烁(双绿灯)问题解决方法 IFC标准在学术界的研究与发展历程:从理论探索到产业实践的全面梳理IFC标准在学术界的研究与发展历程:从理论探索到产业实践的全面梳理 BIM的“普通话”:解密IFC标准如何重塑建筑行业 IfcCrewResource Qt重置 Brush pyqt 操作mysql数据库 泵仿真 Qt折线的显示与隐藏 Qt绘制折线 c++ Qt绘制传热云图 - 西北逍遥 livox mid-70采集点云数据 随机配色 学习:LED灯闪烁 win10安装neo4j-community-3.5.7-windows win10安装MongoDB 3.0.15 Community python把图片合并成gif图 ubuntu20.04测试cuda start.bat Djstra求解最短路径
osg3.6绘制半球体
西北逍遥 · 2026-03-31 · via 博客园 - 西北逍遥
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/StateSet>
#include <osg/BlendFunc>
#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>
#include <cmath> //// 辅助函数:创建一个半球的 Geometry
osg::Geometry* createHemisphereGeometry(float radius = 1.0f, int slices = 30, int stacks = 15)
{
    osg::Geometry* geom = new osg::Geometry;

    osg::Vec3Array* vertices = new osg::Vec3Array;
    osg::Vec3Array* normals = new osg::Vec3Array;
    osg::Vec4Array* colors = new osg::Vec4Array;

    // 1. 生成顶点和法线
    // 注意:半球的垂直角度范围是 0 到 PI/2 (90度)
    for (int i = 0; i <= stacks; i++)
    {
        float V = (float)i / (float)stacks; // 0 -> 1
        float phi = V * 3.1415926 * 0.5f; // 0 -> PI/2 (半球)

        for (int j = 0; j <= slices; j++)
        {
            float U = (float)j / (float)slices; // 0 -> 1
            float theta = U * 3.1415926 * 2.0f; // 0 -> 2PI

            // 计算球面坐标
            float x = radius * cos(theta) * sin(phi);
            float y = radius * sin(theta) * sin(phi);
            float z = radius * cos(phi); // 当 phi=0 时,z=radius (球顶); phi=PI/2 时,z=0 (赤道)

            vertices->push_back(osg::Vec3(x, y, z));

            // 球体的法线就是顶点坐标归一化后的方向(对于单位球,顶点坐标就是法线)
            normals->push_back(osg::Vec3(x, y, z) / radius);
        }
    }

    // 2. 构建索引 (Triangle Strips)
    for (int i = 0; i < stacks; i++)
    {
        osg::DrawElementsUInt* strip = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP);

        int baseIndex = i * (slices + 1);

        for (int j = 0; j <= slices; j++)
        {
            // 下层顶点
            strip->push_back(baseIndex + j);
            // 上层顶点
            strip->push_back(baseIndex + j + slices + 1);
        }
        geom->addPrimitiveSet(strip);
    }

    // 3. 设置数据
    geom->setVertexArray(vertices);
    geom->setNormalArray(normals, osg::Array::BIND_PER_VERTEX);
    // 设置红色半透明颜色
    colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 0.15f));
    geom->setColorArray(colors, osg::Array::BIND_OVERALL);

    return geom;
}

int main()
{
    // 1. 创建 Geode
    osg::ref_ptr<osg::Geode> geode = new osg::Geode();

    // 2. 添加半球
    osg::Geometry* hemisphere = createHemisphereGeometry(2.0f, 30, 15);
    geode->addDrawable(hemisphere);

    // 3. 开启混合实现半透明
    osg::StateSet* ss = geode->getOrCreateStateSet();
    ss->setMode(GL_BLEND, osg::StateAttribute::ON);
    ss->setAttribute(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));

    // 4. 运行
    osgViewer::Viewer viewer;
    viewer.setSceneData(geode);
    viewer.setCameraManipulator(new osgGA::TrackballManipulator());

    return viewer.run();
}

a579d2179a0e8aae6f81701c7968ee01

######################