手动计算球面顶点的坐标,纹理坐标,来画球并贴纹理

其中createSphereGeom()函数的的二个参数为18,意思是在经纬度上每10度设一个点,因为经度一共是180度,180/18=10,相当于横着把球分为18份,每一份相当于一个圆盘,然后再把圆盘分为18*2=36份,每一份相当于一个扇形。

由于要贴纹理,所以在实现的时候,最上面的一个顶点是36+1=37个顶点重合了,最下面的一个顶点一样,中间每一圈的最开始的顶点和最后一个顶点重合,每一圈都有36+1=37个顶点,总共有(36+1)*(18+1)=703个顶点。

为什么每一圈是37个顶点而不是36,其实如果不贴纹理就只是画球,那36个顶点就可以了,但是纹理是一张矩形的图片,你要把一个矩形上的每个点映射到球面上,那每一圈就需要多一个点。

如下图,把一张纸分为4份,上面有5个点,再把这张纸卷成圆筒,最左边和最右边的点重合了,看起来就只有4个点了。当然如果不需要贴纹理,那就不用重合的点了。

纹理的坐标原点是在左下角,为了和物体位置的坐标xyz区分,纹理坐标叫做str,s相当于x,t相当y。s是横坐标,t是纵坐标。

下面看完整的代码,想要运行,你需要安装好osg

#include <math.h>

#include <osg/Geode>
#include <osg/Group>
#include <osg/Vec3>
#include <osg/Geometry>
#include <osg/ref_ptr>
#include <osg/Vec2>
#include <osg/Texture2D> #include <osgDB/ReadFile> #include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers> #include <osgGA/StateSetManipulator> /**
@brief : 创建一个球的几何节点
@param : [in] dRadius 球的半径
@param : [in] iHint 每180/iHint度设置一个点,默认18
@return: 一个球的osg::Geometry*
*/
osg::Geometry* createSphereGeom(double dRadius = 1., int iHint = 18)
{
osg::ref_ptr<osg::Geometry> rpGeom = new osg::Geometry;
osg::ref_ptr<osg::Vec3Array> rpVertexes = new osg::Vec3Array;//顶点数组
osg::ref_ptr<osg::Vec3Array> rpNormal = new osg::Vec3Array;//法线数组
osg::ref_ptr<osg::Vec2Array> rpTexCoord = new osg::Vec2Array;//纹理数组 for (int i = 0; i <= iHint; i++)//从上到下添加点,有等于号是为了之后贴纹理时可以和图片的点一一对应
{
for (int j = 0; j <= iHint * 2; j++)//逆时针添加点
{
osg::Vec3 vec3VertexT(
sin(osg::PI*i / iHint)*cos(osg::PI*j / iHint),
sin(osg::PI*i / iHint)*sin(osg::PI*j / iHint),
cos(osg::PI*i / iHint));//球面坐标公式
rpVertexes->push_back(vec3VertexT * dRadius);//添加顶点
rpNormal->push_back(vec3VertexT);//添加法线
rpTexCoord->push_back(osg::Vec2(double(j) / 2.0 / iHint
, 1 - double(i) / iHint));//添加纹理坐标
}
} osg::ref_ptr<osg::Vec4Array> rpColors = new osg::Vec4Array;
rpColors->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0)); rpGeom->setVertexArray(rpVertexes);
rpGeom->setNormalArray(rpNormal);
rpGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
rpGeom->setColorArray(rpColors);
rpGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
rpGeom->setTexCoordArray(0, rpTexCoord); //添加图元
osg::ref_ptr<osg::DrawElementsUInt> rpFace = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP);
for (int i = 0; i < iHint; i++) {
for (int j = 0; j <= iHint * 2; j++) {
rpFace->push_back(i*(iHint * 2 + 1) + j);
rpFace->push_back((i + 1)*(iHint * 2 + 1) + j);
}
}
rpGeom->addPrimitiveSet(rpFace); return rpGeom.release();
} /**
@brief : 给球贴纹理
@param : [in/out] pNode 球的节点
@return:
*/
void setTex(osg::Node* pNode)
{
osg::ref_ptr<osg::Image> rpImage = osgDB::readImageFile("../star/moon.jpg");
osg::ref_ptr<osg::Texture2D> rpTexture = new osg::Texture2D(); rpTexture->setImage(rpImage);
rpTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);//设置S方向的环绕模式
rpTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);//设置R方向的环绕模式
//rpTextureT->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_NEAREST);
//rpTextureT->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); osg::ref_ptr<osg::StateSet> pState = pNode->getOrCreateStateSet();
pState->setTextureAttributeAndModes(0, rpTexture, osg::StateAttribute::ON);
} int main(int argc, char** argv)
{
osg::ref_ptr<osgViewer::Viewer> rpViewer = new osgViewer::Viewer();
osg::ref_ptr<osg::Group> rpRoot = new osg::Group(); osg::ref_ptr<osg::Geode> rpGeode = new osg::Geode;
rpGeode->addChild(createSphereGeom(1., 45));
setTex(rpGeode);//在球上贴纹理 rpRoot->addChild(rpGeode);
rpViewer->setSceneData(rpRoot); rpViewer->addEventHandler(new osgGA::StateSetManipulator(rpViewer->getCamera()->getOrCreateStateSet()));//添加w事件处理
rpViewer->addEventHandler(new osgViewer::StatsHandler);//添加s事件处理 rpViewer->run();
return 0;
}

程序运行截图

未贴纹理的球:

隐藏表面,只显示线的球,即按w键后的球:

只显示点的球:

osg纯手工画球+贴纹理的更多相关文章

  1. HTML5+CSS3+Jquery实现纯手工的垂直时光轴【附源码】

    前言 由于工作中需要,系统中需要记录不同时间发生的事件,为了提升用户体验,决定用时光轴来实现.[据说这个东西挺火的,QQ空间和FB都在用...] 这个时光轴是在 三生石上 这位博主的时光轴基础上修改的 ...

  2. 用纯css画个三角形

    用纯css画个三角形以下是源代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

  3. 纯手工打造漂亮的瀑布流,五大插件一个都不少Bootstrap+jQuery+Masonry+imagesLoaded+Lightbox!

    前两天写的文章<纯手工打造漂亮的垂直时间轴,使用最简单的HTML+CSS+JQUERY完成100个版本更新记录的华丽转身!>受到很多网友的喜爱,今天特别推出姊妹篇<纯手工打造漂亮的瀑 ...

  4. 纯手工打造漂亮的垂直时间轴,使用最简单的HTML+CSS+JQUERY完成100个版本更新记录的华丽转身!

    前言 FineUI控件库发展至今已经有 5 个年头,目前论坛注册的QQ会员 5000 多人,捐赠用户 500 多人(捐赠用户转化率达到10%以上,在国内开源领域相信这是一个梦幻数字!也足以证明Fine ...

  5. JAVA+PHP+阿里云组件纯手工实现POP、SMTP、IMAP开发邮件服务器(二)

    java开发邮件服务器的接收模块 用java建立socket服务端,监听端口25,实现SMTP协议.即可完成邮件服务器的接收模块. 这里要注意的是,SMTP协议其实可以分为两种.一种是你用手机.PC等 ...

  6. [置顶] 纯手工打造漂亮的瀑布流,五大插件一个都不少Bootstrap+jQuery+Masonry+imagesLoaded+Lightbox!

    前两天写的文章<纯手工打造漂亮的垂直时间轴,使用最简单的HTML+CSS+JQUERY完成100个版本更新记录的华丽转身!>受到很多网友的喜爱,今天特别推出姊妹篇<纯手工打造漂亮的瀑 ...

  7. [置顶] 纯手工打造漂亮的垂直时间轴,使用最简单的HTML+CSS+JQUERY完成100个版本更新记录的华丽转身!

    前言 FineUI控件库发展至今已经有 5 个年头,目前论坛注册的QQ会员 5000 多人,捐赠用户 500 多人(捐赠用户转化率达到10%以上,在国内开源领域相信这是一个梦幻数字!也足以证明Fine ...

  8. 【转】纯手工玩转 Nginx 日志

    Nginx 日志对于大部分人来说是个未被发掘的宝藏,总结之前做某日志分析系统的经验,和大家分享一下 Nginx 日志的纯手工分析方式. Nginx 日志相关配置有 2 个地方:access_log 和 ...

  9. 纯手工编写的PE可执行程序

    [文章标题]: 纯手工编写的PE可执行程序[文章作者]: Kinney[下载地址]: 自己搜索下载[使用工具]: C32[操作平台]: win 7[作者声明]: 只是感兴趣,没有其他目的.失误之处敬请 ...

随机推荐

  1. Android Studio 如何在TextView中设置图标并按需调整图标大小

    •任务 相信大家对这张图片都不陌生,没错,就是 QQ动态 向我们展示的界面. 如何实现呢? •添加文字并放入图标 新建一个 Activity,取名为 QQ,Android Studio 自动为我们生成 ...

  2. [源码解析] 分布式任务队列 Celery 之启动 Consumer

    [源码解析] 分布式任务队列 Celery 之启动 Consumer 目录 [源码解析] 分布式任务队列 Celery 之启动 Consumer 0x00 摘要 0x01 综述 1.1 kombu.c ...

  3. Spring Cloud 升级之路 - 2020.0.x - 2. 使用 Undertow 作为我们的 Web 服务容器

    本项目代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford 在我们的项目中,我 ...

  4. 全网最详细的Linux命令系列-ls命令

    Linux开始必须要会的命令当属ls,在日常工作中用到ls命令时的频率是很多的,作为一个初学者,可能我只会或者顶多ls -l两种用法.但是ls其实是一个非常实用的指令,ls命令就是list的缩写,ls ...

  5. 梳理一下最近准备蓝桥杯时学习DP问题的想法

    学习时间不长,记录的只是学习过程的思路和想法,不能保证正确,代码可以在acwing上AC. 01背包问题: 1.首先是简单的01背包问题 2.先确定状态,f[i][j]表示有第i件物品,时间为j的最大 ...

  6. 201871030114-蒋鑫 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客链接☛ 班级博客 这个作业要求链接☛ 作业要求 我的课程学习目标☛ 1. 体验软件项目开发中的两人合作,练习结对编程(Pair programming).2. 掌握Github ...

  7. 201871030115-康旭 实验二 软件工程个人项目—《D{0-1} KP》项目报告

    项目 内容 课程班级博客连接 课程班级 这个作业要求连接 作业链接 我的课程学习目标 (1)详细阅读<构建之法>第1章.第2章,掌握PSP流程:(2)设计实际程序掌握动态规划算法.回溯算法 ...

  8. Dynamics CRM开发参考资料

    Developer Guide for Dynamics 365 Customer Engagement https://docs.microsoft.com/en-us/dynamics365/cu ...

  9. wap视频广告遇到的问题

    最近在做一个wap端的视频广告,耗了很多心力在上面,仍旧做不好.没想到wap浏览器对video标签这么不友好.广告需要在原编辑视频播完后插入并自动播放. ios浏览器点击播放按钮后喜欢自动全屏播放,希 ...

  10. CTF导引(一)

    ctf预备知识: 视频:https://www.bilibili.com/video/av62214776?from=search&seid=1436604431801225989 CTF比赛 ...