用OpenSceneGraph实现的NeHe OpenGL教程 - 第三十八课

WS2812和homeassistant握手 本文学习了WS2812和homeassistant握手,后期会分享更多有趣物联网的操作从而实现对外部世界进行感知,充分认识这个有机与无机的环境,科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。... 阅读详情
  • 简介

这节课NeHe教我们怎样把图片作为资源嵌入到exe可执行文件中,这样当我们发布程序的时候就可以不需要附带上图片文件了。由于这部分的内容和OSG并没有关系,主要是使用Windows编程中资源的概念,我对这部分并不是很熟悉,因此本课只实现最后的效果。图片并未处理成NeHe中的这种方式。

  • 实现

首先创建我们需要的50只蝴蝶的模型,并且加载需要的纹理

void initialize()
{
	for (int loop=0; loop<50; loop++)
	{
		setObject(loop);
	}

	g_Tex1 = new osg::Texture2D;
	g_Tex1->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex1->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex1->setImage(osgDB::readImageFile("Data/Butterfly1.bmp"));

	g_Tex2 = new osg::Texture2D;
	g_Tex2->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex2->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex2->setImage(osgDB::readImageFile("Data/Butterfly2.bmp"));

	g_Tex3 = new osg::Texture2D;
	g_Tex3->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex3->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex3->setImage(osgDB::readImageFile("Data/Butterfly3.bmp"));
}
接下来把蝴蝶添加到组节点中,并设置每只蝴蝶的位置回调函数,更新它们的位置

osg::Group*		createButterflyGroup()
在回调中写下蝴蝶的位置变化以及旋转变化等:

class ButterFlyGroupCallback : public osg::NodeCallback
class TranslateUpdateCallback : public osg::NodeCallback
这些内容前面的课程中已经重复很多次了,相信不难理解,具体代码参见后面的附录部分:

将所有这些部分添加到场景根节点下,编译运行程序:


附:本课源码(源码中可能存在错误和不足,仅供参考)

#include "../osgNeHe.h"

#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QtGui/QVBoxLayout>

#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgQt/GraphicsWindowQt>

#include <osg/MatrixTransform>
#include <osg/PolygonMode>
#include <osg/Texture2D>
#include <osg/BlendFunc>

osg::Texture2D *g_Tex1, *g_Tex2, *g_Tex3;

struct object
{
	int   tex;
	float x;
	float y;
	float z;
	float yi;
	float spinz;
	float spinzi;
	float flap;
	float fi;
};

object obj[50];

void setObject(int loop)
{
	obj[loop].tex=rand()%3;
	obj[loop].x=rand()%34-17.0f;
	obj[loop].y=18.0f;
	obj[loop].z=-((rand()%30000/1000.0f)+10.0f);
	obj[loop].spinzi=(rand()%10000)/5000.0f-1.0f;
	obj[loop].flap=0.0f;	
	obj[loop].fi=0.05f+(rand()%100)/1000.0f;	
	obj[loop].yi=0.001f+(rand()%1000)/10000.0f;
}


void initialize()
{
	for (int loop=0; loop<50; loop++)
	{
		setObject(loop);
	}

	g_Tex1 = new osg::Texture2D;
	g_Tex1->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex1->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex1->setImage(osgDB::readImageFile("Data/Butterfly1.bmp"));

	g_Tex2 = new osg::Texture2D;
	g_Tex2->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex2->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex2->setImage(osgDB::readImageFile("Data/Butterfly2.bmp"));

	g_Tex3 = new osg::Texture2D;
	g_Tex3->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex3->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
	g_Tex3->setImage(osgDB::readImageFile("Data/Butterfly3.bmp"));
}


class ButterflyUpdateCallback : public osg::Drawable::UpdateCallback
{
public:
	ButterflyUpdateCallback(int index, int texIndex) : _index(index), _texIndex(texIndex)
	{
		//NOP
	}

	virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)
	{
		osg::Geometry *geometry = dynamic_cast<osg::Geometry*>(drawable);
		if(!geometry)
			return;

		osg::Vec3Array *vertexArray = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
		if (!vertexArray)
			return;

		vertexArray->clear();
		vertexArray->push_back(osg::Vec3(1.0f, 1.0f, 0.0f));
		vertexArray->push_back(osg::Vec3(-1.0f, 1.0f, obj[_index].flap));
		vertexArray->push_back(osg::Vec3(-1.0f,-1.0f, 0.0f));
		vertexArray->push_back(osg::Vec3(1.0f, 1.0f, 0.0f));
		vertexArray->push_back(osg::Vec3(-1.0f,-1.0f, 0.0f));
		vertexArray->push_back(osg::Vec3(1.0f,-1.0f, obj[_index].flap));
		vertexArray->dirty();
		geometry->setVertexArray(vertexArray);

		if (!geometry->getOrCreateStateSet()->getTextureAttribute(0, osg::StateAttribute::TEXTURE))
		{
			if (_texIndex == 0 )
			{
				geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Tex1);
			}
			if (_texIndex == 1)
			{
				geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Tex2);
			}
			if (_texIndex == 2)
			{
				geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Tex3);
			}
		}
	}

	int _index;
	int _texIndex;
};


class RotateUpdateCallback : public osg::NodeCallback
{
public:
	RotateUpdateCallback(int index) : _index(index){ }

	virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
	{
		osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(node);
		if (!mt)
			return;
		mt->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(obj[_index].spinz), osg::Z_AXIS));

		traverse(node, nv);
	}

	int _index;
};


class TranslateUpdateCallback : public osg::NodeCallback
{
public:
	TranslateUpdateCallback(int index) : _index(index){}

	virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
	{
		osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(node);
		if (!mt)
			return;
		mt->setMatrix(osg::Matrix::translate(obj[_index].x,obj[_index].y,obj[_index].z));

		traverse(node, nv);
	}

	int _index;
};


class ButterFlyGroupCallback : public osg::NodeCallback
{
public:
	ButterFlyGroupCallback(){}

	virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
	{
		for (int loop = 0; loop < 50; ++loop)
		{
			obj[loop].y-=obj[loop].yi;
			obj[loop].spinz+=obj[loop].spinzi;
			obj[loop].flap+=obj[loop].fi;

			if (obj[loop].y<-18.0f)
			{
				setObject(loop);
			}

			if ((obj[loop].flap>1.0f) || (obj[loop].flap<-1.0f))
			{
				obj[loop].fi=-obj[loop].fi;
			}
		}
		traverse(node, nv);
	}
};



osg::Group*		createButterflyGroup()
{
	osg::Group *butterflyGroup = new osg::Group;
	butterflyGroup->addUpdateCallback(new ButterFlyGroupCallback);

	for (int loop = 0; loop < 50; ++loop)
	{
		osg::MatrixTransform *zoomMT = new osg::MatrixTransform;
		zoomMT->setMatrix(osg::Matrix::translate(obj[loop].x,obj[loop].y,obj[loop].z));
		zoomMT->addUpdateCallback(new TranslateUpdateCallback(loop));
		osg::MatrixTransform *rotateX = new osg::MatrixTransform;
		rotateX->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(45.0), osg::X_AXIS));
		osg::MatrixTransform *rotateZ = new osg::MatrixTransform;
		rotateZ->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(obj[loop].spinz), osg::Z_AXIS));
		rotateZ->addUpdateCallback(new RotateUpdateCallback(loop));

		osg::Geode *butterflyGeode = new osg::Geode;
		osg::Geometry *butterGeometry = new osg::Geometry;
		butterGeometry->setUpdateCallback(new ButterflyUpdateCallback(loop, obj[loop].tex));
		osg::Vec3Array *vertexArray = new osg::Vec3Array;
		osg::Vec2Array *texArray = new osg::Vec2Array;

		vertexArray->push_back(osg::Vec3(1.0f, 1.0f, 0.0f));
		vertexArray->push_back(osg::Vec3(-1.0f, 1.0f, obj[loop].flap));
		vertexArray->push_back(osg::Vec3(-1.0f,-1.0f, 0.0f));
		vertexArray->push_back(osg::Vec3(1.0f, 1.0f, 0.0f));
		vertexArray->push_back(osg::Vec3(-1.0f,-1.0f, 0.0f));
		vertexArray->push_back(osg::Vec3(1.0f,-1.0f, obj[loop].flap));

		texArray->push_back(osg::Vec2(1.0f,1.0f));
		texArray->push_back(osg::Vec2(0.0f,1.0f));
		texArray->push_back(osg::Vec2(0.0f,0.0f));
		texArray->push_back(osg::Vec2(1.0f,1.0f));
		texArray->push_back(osg::Vec2(0.0f, 0.0f));
		texArray->push_back(osg::Vec2(1.0f,0.0f));

		butterGeometry->setVertexArray(vertexArray);
		butterGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertexArray->size()));
		butterGeometry->setTexCoordArray(0, texArray, osg::Array::BIND_PER_VERTEX);
		butterGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, false);
		osg::BlendFunc *blendFunc = new osg::BlendFunc(osg::BlendFunc::ONE, osg::BlendFunc::SRC_ALPHA);
		butterGeometry->getOrCreateStateSet()->setAttributeAndModes(blendFunc);
		butterGeometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, false);

		butterflyGeode->addDrawable(butterGeometry);
		butterflyGroup->addChild(zoomMT);
		zoomMT->addChild(rotateX);
		rotateX->addChild(rotateZ);
		rotateZ->addChild(butterflyGeode);
	}
	
	return butterflyGroup;
}



class ViewerWidget : public QWidget, public osgViewer::Viewer
{
public:
	ViewerWidget(osg::Node *scene = NULL)
	{
		QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,640,480), scene);

		QVBoxLayout* layout = new QVBoxLayout;
		layout->addWidget(renderWidget);
		layout->setContentsMargins(0, 0, 0, 1);
		setLayout( layout );

		connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );
		_timer.start( 10 );
	}

	QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )
	{
		osg::Camera* camera = this->getCamera();
		camera->setGraphicsContext( gw );

		const osg::GraphicsContext::Traits* traits = gw->getTraits();

		camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 0.5) );
		camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );
		camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );		
		camera->setViewMatrixAsLookAt(osg::Vec3d(0.0f, 25.0f, -45.0f), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));

		this->setSceneData( scene );

		return gw->getGLWidget();
	}

	osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name="", bool windowDecoration=false )
	{
		osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
		osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
		traits->windowName = name;
		traits->windowDecoration = windowDecoration;
		traits->x = x;
		traits->y = y;
		traits->width = w;
		traits->height = h;
		traits->doubleBuffer = true;
		traits->alpha = ds->getMinimumNumAlphaBits();
		traits->stencil = ds->getMinimumNumStencilBits();
		traits->sampleBuffers = ds->getMultiSamples();
		traits->samples = ds->getNumMultiSamples();

		return new osgQt::GraphicsWindowQt(traits.get());
	}

	virtual void paintEvent( QPaintEvent* event )
	{ 
		frame(); 
	}

protected:

	QTimer _timer;
};



osg::Node*	buildScene()
{
	initialize();

	osg::Group *root = new osg::Group;
	root->addChild(createButterflyGroup());
	return root;
}



int main( int argc, char** argv )
{
	QApplication app(argc, argv);
	ViewerWidget* viewWidget = new ViewerWidget(buildScene());
	viewWidget->setGeometry( 100, 100, 640, 480 );
	viewWidget->show();
	return app.exec();
}

Python爬虫selenium验证-中文识别点选+图片验证码案例 环境对模型进行训练,参考:https://github.com/sml2h3/dddd_trainer。能识别,但是发现默认识别率有点低,想要提升识别率,可以搭建。截图每个字符,并基于ddddocr识别。根据坐标,在验证码上进行点击。 阅读详情

相关推荐

动态知识图谱构建:从本体论到工程实践

知识图谱作为语义网和人工智能领域的核心技术,旨在通过结构化的方式表示和组织知识。其核心原理在于将实体、概念及其关系建模为图结构,从而支持复杂的语义推理和关联查询。这一技术为机器理解数据间的深层联系提供了基础,在智能推荐、企业知识管理和学术研究等领域具有重要价值。通过结合自然语言处理(NLP)和图数据库技术,系统能够从非结构化数据中自动抽取知识,并构建动态演化的认知网络。本文以“本体论章鱼”项目为例,探讨了如何实现从静态本体到动态知识网络的范式转变,并详细解析了其分布式感知、适应性学习的架构设计,为构建灵活可

weixin_30731305的博客 662

OpenSceneGraph 教程

  Open Scene Graph教程1——使用Open Scene Graph几何原文出处:http://www.nps.navy.mil/cs/sullivan/osgtutorials/osgGeometry.htm摘要     本节涵盖了生成基本几何形状的一些方法。生成几何物体的方法有这么几种:在最底层对OpenGL基本几何进行松散的包装,中级是使用Open Sc

doing5552的专栏 1万+

AMCL代码详解(六)amcl中的重采样

每次都从w1左边的竖线开始转,显而易见,转到w1的概率为0-w1之间的随机数,转到w2的概率为w1到w1+w2之间的随机数,转到w3的概率为w1+w2到w1+w2+w3之间的随机数,后面的依次类推。当某个粒子的权值较大的时候,产生的随机数落在相应区间的概率就会增大,从而实现了对权值大粒子的多次复制,权值小的粒子的剔除。可以看出,在整个重采样的过程中,粒子进行了两次种情况的刷新,一种是随机生成的新的粒子,一种是对原来的粒子的复制。得到的值越大,说明粒子的权重越小,当前粒子的可信度比较小,需要重采样粒子。

YiYeZhiNian的博客 1580

osg::ref_ptr<osg::Image> image = osgDB::readImageFile(fileName); image指针为空

前言 使用《OpenSceneGraph Quick Start Guide》中文版及源码,里面的一个例子TextureMapping,在我本机上运行没有问题,但拷贝到公司电脑,发现总是运行异常,无法读取纹理图片, 调试到136行 image创建出来总是为空,纹理文件是有的, #include "osgDB/ReadFile" #include "osg/Geode" #include "osg/Geometry" #include "osg/StateSet" #include "osg/StateAt

aoxuestudy的专栏 1752

IQA图像质量评价 数据集介绍(LIVE、TID2013、CSIQ、LIVEC、KonIQ-10K)

LIVE、TID2013、CSIQ、LIVEC、KonIQ-10K 数据集介绍

qq_37925923的博客 1万+

嵌入式系统中的轻量级压缩实践——miniLZO在STM32上的性能优化

本文深入探讨了miniLZO轻量级压缩算法在STM32嵌入式系统中的性能优化实践。通过对比无损压缩算法的性能特点,详细解析了miniLZO在内存占用、压缩速度方面的优势,并提供了STM32移植、参数调优及创新应用案例,帮助开发者在资源受限环境中实现高效数据压缩。

weixin_30776273的博客 84

osg osgDB::readImageFile 返回空指针 已解决

osg osgDB::readImageFile 返回空指针

PHP代码的博客 1055

自制JS某课脚本

根据实际需求自制网页讯网刷题脚本,绕过人脸,弹窗,答题,实现自动化运行

2301_81243054的博客 3460

OpenSceneGraph几何基础教程【OSG】

默认情况下,OSG 使用顶点数组法和显示列表法来渲染几何体。但是,渲染策略可能会发生变化,具体取决于几何数据的呈现方式。在本文中,我们将了解在 OSG 中处理几何体的基本技术。OpenSceneGraph 后端的 OpenGL 使用几何图元(例如点、线、三角形和多边形面)来构建三维世界中的所有对象。这些图元由它们的顶点指定,包括顶点坐标、法线分量、颜色数据和纹理坐标。此数据存储在特殊数组中。例如,可以通过为描述它们的对象指定顶点索引列表来形成图元。这种方法称为顶点数组法;

新缸中之脑 3765

OpenClaw实战系列10(完结篇):企业级应用实战案例——从0到1搭建智能客服系统

本文以一家跨境电商公司为例,从需求分析、系统设计、分步搭建到上线运营,完整呈现智能客服系统的落地全过程。所有配置命令和截图均来自实测环境,你可以直接复制使用。

PeterPan的博客 1306

Power Switch与Tap Cell关系

tap cell可以选用一般类型的tap cell,无须secondary pg pin,因为此时switch cell的阱电位接到输入power net上了,switch cell可以正常上电,也可以给core内正常供电,tap cell的阱电位接switch cell输出的power,需要注意的是此时switch cell与core内其他cell的阱电位是不同的,所以为了避免drc问题,需要在switch上盖hard blockage或者keepout margin。2)自带阱偏置的switch。

m0_61544122的博客 2338

Windows10编译安装OpenSceneGraph(OSG)教程

Windows10编译安装OpenSceneGraph(OSG)教程 保存记录一下

sinat_29890433的博客 2806

43_AI短片实战第十六弹:AIGC补充特写镜头——首尾帧衔接与多图抽卡技巧

本文介绍了使用Templa AI平台生成"怪兽爬车"特写镜头并衔接"甩尾摔下"动作的完整流程。首先通过AI生成4张怪兽趴在车顶的特写画面,重点选择展示怪兽与车顶关系的构图(16:9比例)。然后将选定的首帧图与已有尾帧图输入AI,生成7秒左右的过渡视频,实现从"稳定趴车"到"开始摔落"的自然衔接。整个过程展示了单图抽卡策略、首尾帧选择标准,以及如何利用AI生成时间进行其他剪辑任务的并行处理方法。最终产出包括特写首帧图、过渡视频文件和更新后的剪辑项目。

Open 79

OpenSceneGraph实现的NeHe OpenGL教程 - 第三十八课

简介 这节课NeHe教我们怎样把图片作为资源嵌入到exe可执行文件中,这样当我们发布程序的时候就可以不需要附带上图片文件了。由于这部分的内容和OSG并没有关系,主要是使用Windows编程中资源的概念,我对这部分并不是很熟悉,因此本课只实现最后的效果。图片并未处理成NeHe中的这种方式。 实现 首先创建我们需要的50只蝴蝶的模型,并且加载需要的纹理

ALLENJIAO的专栏 676

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

用OpenSceneGraph实现的NeHe OpenGL教程 - 第一课

简介 OpenSceneGraph是一个开放源码,跨平台的图形开发包,它为诸如飞行器仿真,游戏,虚拟现实,科学计算可视化这样的高性能图形应用程序开发而设计。它基于场景图的概念,它提供一个在OpenGL之上的面向对象的框架,从而能把开发者从实现和优化底层图形的调用中解脱出来,并且它为图形应用程序的快速开发提供很多附加的实用工具。 NeHe教程是目前针对初学者来说最

Frank的专栏 1万+

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

用OpenSceneGraph实现的NeHe OpenGL教程 - 第二十四课

简介 NeHe教程在这节课中向我们介绍了如何读取显卡支持的OpenGL的扩展,如何使用Targa(TGA)图像文件作为纹理,以及如何利用OpenGL的剪裁区域来滚动屏幕文字。 在OpenInventor中没有相关的函数来获取OpenGL的扩展信息,我们只能通过直接调用OpenGL来获得这些信息。OpenInventor的纹理节点自动支持使用Targa(TGA)图像文件作为纹理,所以我们

Frank的专栏 2317

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

用OpenSceneGraph实现的NeHe OpenGL教程 - 第十一课

简介 这节课我们将创建一个以正弦波方式飘动的旗帜。本课所用到的知识在前面的课程中都有讲解,并没有什么新的内容 实现 首先创建我们的场景,关于旗帜的顶点坐标在NeHe教程中已经有非常详细的介绍,本文就不在赘述了。 float points[45][45][3]; for(int x=0; x<45; x++) { for(int y=0; y<45; y++

Frank的专栏 1579

OpenSceneGraph实现的NeHe OpenGL教程 - 第二十四课

简介 NeHe教程在这节课中向我们介绍了如何读取显卡支持的OpenGL的扩展,如何使用Targa(TGA)图像文件作为纹理,以及如何利用OpenGL的剪裁区域来滚动屏幕文字。osg支持tga格式的文件读取,因此不需要像NeHe课程那样解析TGA格式,有兴趣的读者可以查看osgPlugins库中的ReaderWriterTGA.cpp文件了解osg是如何读取TGA图片格式的。

ALLENJIAO的专栏 1110

用OpenSceneGraph实现的NeHe OpenGL教程 - 第二十五课

简介 NeHe教程在这节课中向我们介绍了如何从文件加载3D模型,并且平滑的从一个模型变换为另一个模型。两个模型之间平滑过渡的算法其实是很简单的,首先我们要保证两个模型要有相同数目的顶点,然后我们分别计算每个点从一个模型移动到另外一个模型时,中间的位置数据。我们将这个过程显示出来就会产生模型平滑过渡的效果。

Frank的专栏 1747

OpenSceneGraph实现的NeHe OpenGL教程 - 第十一课

简介 这节课我们将创建一个以正弦波方式飘动的旗帜。本课所用到的知识在前面的课程中都有讲解,并没有什么新的内容 实现 首先创建我们的场景,关于旗帜的顶点坐标在NeHe教程中已经有非常详细的介绍,本文就不在赘述了。 [cpp] view plain copy   float points[45][45][3];

ALLENJIAO的专栏 717

用OpenSceneGraph实现的NeHe OpenGL教程 - 第十二课

简介 本课NeHe教程主要是使用了OpenGL中的显示列表。OpenGL的显示列表是加速OpenGL性能的一种重要的手段。OpenGl的几何体绘制方法主要包括立即模式、顶点数组、显示列表和VBO。在OSG中显示列表是大部分OSG程序所使用的默认绘制优化行为,因此不需要我们去像OpenGL那样进行设置。 实现 首先创建整个场景,本课中我使用了OSG中预定义的几种基本形体,(os

Frank的专栏 7883

OpenSceneGraph实现的NeHe OpenGL教程 - 第一课

目录(?)[-] 简介创建一个osg窗口 简介 OpenSceneGraph是一个开放源码,跨平台的图形开发包,它为诸如飞行器仿真,游戏,虚拟现实,科学计算可视化这样的高性能图形应用程序开发而设计。它基于场景图的概念,它提供一个在OpenGL之上的面向对象的框架,从而能把开发者从实现和优化底层图形的调用中解脱出来,并且它为图形应用程序的快速

ALLENJIAO的专栏 1201

OpenSceneGraph实现的NeHe OpenGL教程 - 第三十二课

简介 本节课NeHe课程主要想我们介绍了OpenGL中的拾取(Selection)的方式来和场景中的物体进行交换,在OSG中并没有封装OpenGL中的拾取方式,而是用了更高效的一种方式来实现与场景中的模型进行求交的操作,对于OSG这样处理的原因可以参考OSG中的这个MailList: New to OSG, some questions (selection buffer, para

ALLENJIAO的专栏 541

用OpenSceneGraph实现的NeHe OpenGL教程 - 第十五课

简介 NeHe这节课主要讨论OpenGL怎样给文字赋予纹理贴图。OpenGL使用glTexGen函数给文字自动生成纹理坐标。在OSG中,使用osg::TexGen这个继承自StateAttribute的类来实现相同的效果 实现 首先将创建3D的字体,代码如下: osg::Geode *fontGeode = new osg::Geode;     osg::I

Frank的专栏 1780

OpenSceneGraph实现的NeHe OpenGL教程 - 第三十课

简介 这节课NeHe课程实现了在场景中进行碰撞检测以及简单的物理作用(碰撞之后的反弹),碰撞检测三维图形学中一个比较高级的主题,本课只涉及了简单的规则几何体之间的碰撞检测,更复杂的实例需要读者去更深入的学习。 实现 本课中碰撞检测的算法包括线与平面的求交检测、线与圆柱体的求交、以及球体之间的碰撞检测,这些碰撞检测的原理可以参考NeHe中的介绍。 具体实现在如下几

ALLENJIAO的专栏 722

用OpenSceneGraph实现的NeHe OpenGL教程 - 第二十九课

简介 这节课NeHe

Frank的专栏 1753
上一篇: 用OpenSceneGraph实现的NeHe OpenGL教程 - 第三十七课
下一篇: 用OpenSceneGraph实现的NeHe OpenGL教程 - 第三十九课
csxiaoshui
博客等级 码龄16年 873粉丝 158原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值