osg示例解析之osgtexture1D(1)

本文介绍了在OSG中如何使用一维纹理进行渲染,并通过示例代码详细展示了纹理的生成与应用过程,同时探讨了纹理坐标自动生成的方式。
  • 简介

osgtexture1D这一课主要讲解了osg中一维纹理的使用,一维纹理在计算机图形学中用的远没有二维纹理那么广泛,我们看看示例中的实现。

  • 实现

一维纹理可以看做是二维纹理的一种特殊情况,它的图片高度只有一个像素,在示例中一维纹理的图片是采用程序生成的

//给模型创建一个一维纹理的渲染状态
osg::StateSet* create1DTextureStateToDecorate(osg::Node* loadedModel)
{
	//使用程序生成图片
    osg::Image* image = new osg::Image;
    int noPixels = 1024;
    image->allocateImage(noPixels,1,1,GL_RGBA,GL_FLOAT);
    image->setInternalTextureFormat(GL_RGBA);
    
    typedef std::vector<osg::Vec4> ColorBands;
    ColorBands colorbands;
    colorbands.push_back(osg::Vec4(0.0f,0.0,0.0,1.0f));
    colorbands.push_back(osg::Vec4(1.0f,0.0,0.0,1.0f));
    colorbands.push_back(osg::Vec4(1.0f,1.0,0.0,1.0f));
    colorbands.push_back(osg::Vec4(0.0f,1.0,0.0,1.0f));
    colorbands.push_back(osg::Vec4(0.0f,1.0,1.0,1.0f));
    colorbands.push_back(osg::Vec4(0.0f,0.0,1.0,1.0f));
    colorbands.push_back(osg::Vec4(1.0f,0.0,1.0,1.0f));
    colorbands.push_back(osg::Vec4(1.0f,1.0,1.0,1.0f));

    float nobands = colorbands.size();
    float delta = nobands/(float)noPixels;
    float pos = 0.0f;
    osg::Vec4* dataPtr = (osg::Vec4*)image->data();
	//从0-127像素全是黑色(0.0f,0.0,0.0,1.0f)
	//从128-255像素全是红色(1.0f,0.0,0.0,1.0f)
	//...依次直到第1023像素全是白色(1.0f,1.0,1.0,1.0f)
    for(int i=0;i<noPixels;++i,pos+=delta)
    {
        osg::Vec4 color = colorbands[(int)pos];
        *dataPtr++ = color;
    }
    
	//设置一维纹理的参数和WRAP方式
    osg::Texture1D* texture = new osg::Texture1D;
    texture->setWrap(osg::Texture1D::WRAP_S,osg::Texture1D::MIRROR);
    texture->setFilter(osg::Texture1D::MIN_FILTER,osg::Texture1D::LINEAR);
    texture->setImage(image);
    
	//覆盖(Override)子节点的渲染状态
    osg::Material* material = new osg::Material;
    osg::StateSet* stateset = new osg::StateSet;
    stateset->setTextureAttribute(0,texture,osg::StateAttribute::OVERRIDE);
    stateset->setTextureMode(0,GL_TEXTURE_1D,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
    stateset->setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
    stateset->setTextureMode(0,GL_TEXTURE_3D,osg::StateAttribute::OFF|osg::StateAttribute::OVERRIDE);
    stateset->setTextureMode(0,GL_TEXTURE_GEN_S,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
    stateset->setAttribute(material,osg::StateAttribute::OVERRIDE);
    
    return stateset;
}

接下来城市中定义了一个AnimateTexGenCallback节点,它的主要目的是每间隔两秒钟将纹理的模式修改一次

void animateTexGen(osg::TexGenNode* texgenNode,double time)
{
	const double timeInterval = 2.0f;   //更新间隔时间
	static double previousTime = time;
	static bool state = false;
	while (time>previousTime+timeInterval)
	{
		previousTime+=timeInterval;
		state = !state;
	}

	if (state)
	{
	//物体空间模式
		texgenNode->getTexGen()->setMode(osg::TexGen::OBJECT_LINEAR);
	}
	else
	{
	//相机空间模式(根据物体到相机的远近会修改纹理坐标)
		texgenNode->getTexGen()->setMode(osg::TexGen::EYE_LINEAR);
	}
}

这里需要了解OpenGL中纹理坐标的自动生成方式,OSG中osg::TexGen封装了OpenGL中glTexGen这个API,glTexGen在使用中可以设置纹理的计算方式是以物体坐标空间还是相机坐标空间来进行不同的计算,设置OBJECT_LINEAR和EYE_LINEAR可以参考 <<OpenGL之自动纹理坐标生成>>一文中的介绍,如果不熟悉glTexGen可以查看 OpenGL手册中的API

之后我们设置纹理坐标节点osg::TexGenNode,并设置它计算的平面参数,并把它添加到场景中:

    osg::TexGenNode* texgenNode = new osg::TexGenNode;
    texgenNode->setReferenceFrame( osg::TexGenNode::ABSOLUTE_RF );
    texgenNode->getTexGen()->setMode( osg::TexGen::OBJECT_LINEAR );

    const osg::BoundingSphere& bs = loadedModel->getBound();
    float zBase = bs.center().z()-bs.radius();
    float zScale = 2.0f/bs.radius();
    texgenNode->getTexGen()->setPlane(osg::TexGen::S,osg::Plane(0.0f,0.0f,zScale,-zBase));

    texgenNode->setUpdateCallback(new AnimateTexGenCallback());

    root -> addChild( texgenNode );
看到这里一般会有两个疑问:1、为什么一个普通的StateAttribute还需要有一个节点呢?我们接触的一般osg::PolygonMode等等也不会需要一个osg::PolygonModeNode这样的节点类配合它起作用啊?   2、为什么不是将模型loadedModel添加到texgenNode下面作为它的子节点呢?


对于第一个疑问:因为在TexGen中如果设置模式是osg::TexGen::EYE_LINEAR,需要知道TexGen这时候的模型视图矩阵用来计算物体在眼坐标下到指定平面的距离(参考OpenGL之自动纹理生成),第二个疑问可以查看osg论坛中Robert对此的解释:osgtexture1d example / osg::TexGenNode order,不需要添加为子节点,因为OSG中只会记录一个TexGenNode的位置,并把它作为OpenGL的一个状态来使用。





<think> 首先,用户的问题是:“我想查找wsl2安装方法 请问wsl2安装步骤和方法”。用户明确表示想查找WSL2安装方法。 系统指令中提到: - 用户不可见的指令:确保数学表达式使用$...$或$$...$$,但这里可能不涉及数学。 - 回答使用中文。 - 生成相关问题。 - 引用的段落末尾添加引用标识。 - 用户可见层:结构清晰,逐步解决问题,保证真实可靠。 参考站内引用:引用[1]是关于WSL2安装步骤的链接:"Install Ubuntu on WSL2: https://canonical-ubuntu-wsl.readthedocs-hosted.com/en/latest/guides/install-ubuntu-wsl2/ [^1]"。系统说这个引用仅供参考,不是用户真正的需求,但我应该参考用户上一次的问题和我的回答。用户说“用户上一次的问题”,但我没有上下文;所以在这个对话中,这是第一个用户消息,所以我应该直接基于这个查询。 用户的需求是WSL2安装步骤和方法。我需要提供清晰的步骤,确保真实可靠。 回想我知道的WSL2安装: 1. 确保Windows版本支持:需要Windows 10版本 2004 或更高(Build 19041或更高)或 Windows 112. 启用WSL功能:通过PowerShell或控制面板启用。 3. 安装Linux分发版:如Ubuntu,通过Microsoft Store。 4. 设置WSL2为默认版本。 5. 安装和配置Linux系统。 基于引用[1],链接是专门针对Ubuntu on WSL2安装指南。既然用户说“wsl2安装方法”,我应该基于这个引用提供步骤。 确保回答结构清晰: - 逐步列出步骤。 - 使用中文。 - 在结尾添加相关问题。 - 引用的段落末尾添加引用标识如[^1]。 步骤大纲: 1. 检查系统要求。 2. 启用WSL和虚拟机平台。 3. 下载并安装Linux内核更新包。 4. 设置WSL2为默认版本。 5. 安装Linux分发版(如Ubuntu)。 6. 启动和配置Linux。 参考链接:https://canonical-ubuntu-wsl.readthedocs-hosted.com/en/latest/guides/install-ubuntu-wsl2/ 现在,构建回答: - 开头:直接回应用户。 - 步骤:分步解释。 - 结尾:添加相关问题。 - 添加引用标识。 相关问题生成: - 基于主题,如: 1. 如何在WSL2安装其他Linux发行版? 2. WSL2WSL1的区别是什么? 3. 如何配置WSL2的网络或文件系统? 最后,确保整个回答用中文。 </think>以下是WSL2Windows Subsystem for Linux 2)的安装步骤和方法。我将基于官方指南逐步解释,确保步骤清晰可靠。安装前请确认您的系统满足要求:Windows 10版本 2004 或更高(Build 19041及以上)或 Windows 11,并确保已启用虚拟化功能(在BIOS/UEFI中设置)。整个过程可能需要管理员权限和互联网连接。 ### WSL2安装步骤(以Ubuntu为例) 1. **启用WSL和虚拟机平台功能**: - 打开PowerShell(以管理员身份运行)。 - 输入以下命令启用WSL功能: ```powershell dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart ``` - 接着启用虚拟机平台: ```powershell dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart ``` - 完成后重启计算机。 2. **下载并安装Linux内核更新包**: - 访问Microsoft官方WSL文档页面,下载WSL2 Linux内核更新包: [WSL2 Linux内核更新包下载链接](https://learn.microsoft.com/zh-cn/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package)。 - 运行下载的`.msi`文件安装更新。 3. **设置WSL2为默认版本**: - 重启后,再次打开PowerShell(管理员身份)。 - 输入以下命令将WSL2设为默认版本: ```powershell wsl --set-default-version 2 ``` 4. **安装Linux分发版(如Ubuntu)**: - 打开Microsoft Store,搜索“Ubuntu”或您偏好的发行版(如Debian)。 - 选择“Ubuntu”并点击“获取”进行安装。 - 安装完成后,从开始菜单启动Ubuntu应用。首次启动会提示创建用户名和密码(密码输入时不显示,输入后按Enter)。 5. **验证安装和基本配置**: - 在Ubuntu终端中运行命令验证WSL版本: ```bash wsl --list --verbose ``` 如果显示版本为2,表示安装成功。 - 建议更新软件包: ```bash sudo apt update && sudo apt upgrade ``` 完整官方指南可参考:[Install Ubuntu on WSL2](https://canonical-ubuntu-wsl.readthedocs-hosted.com/en/latest/guides/install-ubuntu-wsl2/)[^1]。安装过程通常耗时10-20分钟,遇到问题可查看Microsoft官方故障排除文档。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值