//实现基于颜色的材质映射,只有一个地球//调用dll,而不是使用自源程序
int Metr_ClassificationOnlyOneEarth()
{
osgViewer::Viewer *viewer = new osgViewer::Viewer;
ref_ptr<osgDB::Options> a = new osgDB::Options(std::string("noTriStripPolygons"));//读取一个模型数据
osg::ref_ptr<osg::Node> earthNode = osgDB::readNodeFile("G:/YCThirdParty/EarthData/demo.earth", a);//osg::ref_ptr<osg::Node> earthNode = osgDB::readNodeFile("D:/OSG/osgEarth_2.7.0/src/applications/osgearth_package_qt/data/base.earth");
if (!earthNode)
{
OE_NOTICE << "Unable to load earth model" << std::endl;
return 1;
}
//查询地图节点
osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode(earthNode);
if (!mapNode)
{
OE_NOTICE << "Could not find MapNode " << std::endl;
return 1;
}
MyDllClass md;
md.EarthShader(mapNode);
//addSky(mapNode);
osg::ref_ptr<osg::Group> root = new osg::Group();
root->addChild(mapNode);
//添加到场景
viewer->setSceneData(root.get());
viewer->getLight()->setAmbient(osg::Vec4f(0.0, 0.0, 0.0, 0.0));
viewer->getLight()->setDiffuse(osg::Vec4f(0.0, 0.0, 0.0, 0.0));
viewer->realize();
return viewer->run();
}
自己建的一个类:
#pragma once
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport )//注意decl前面是两个下划线
#else
#define MYDLL_API __declspec(dllimport)
#endif
namespace MyDllSpace
{
//导出类
class MyDllClass
{
private:
double a;
public:
//导出的函数
MYDLL_API MyDllClass();
MYDLL_API void VirtualProgram(osgEarth::VirtualProgram* vp);
MYDLL_API void EarthShader(osg::Group* root);
};
}
类的代码如下:
#include <iostream>
#define MYDLL_EXPORTS
#include "MyDll.h"
MyDllSpace::MyDllClass::MyDllClass()
{
}
MYDLL_API void MyDllSpace::MyDllClass::VirtualProgram(osgEarth::VirtualProgram* vp)
{
{
std::string haze_vertex = "varying vec3 v_pos; \n"
"varying vec3 oe_Normal; \n"
"varying vec3 osg_Normal; \n"
"void setup_haze(inout vec4 vertex) \n"
"{ \n"
" //v_pos = osg_Normal.xyz; \n"
" //v_pos = normalize(gl_NormalMatrix * gl_Normal); \n"
" v_pos = normalize(gl_NormalMatrix * gl_Normal); \n"
" //v_pos = oe_Normal; \n"
"}";
//使用shader写rgb转lab空间
std::string haze_fragment = "varying vec3 v_pos; \n"
"uniform vec3 direction_color; \n"
"void apply_haze(inout vec4 color) \n"
"{ \n"
" float Metr_Color; \n"
" float RR = 255.0*(color.x); \n"
" float GG = 255.0*(color.y); \n"
" float BB = 255.0*(color.z); \n"
"if (RR>130 && BB<110) \n"//湿土地
"{ \n"
"Metr_Color = 0.85f; \n"
"color = vec4(Metr_Color, Metr_Color, Metr_Color, 1.0f); \n"
"} \n"
"else \n"
"{ \n"
" if (RR>110 && GG>110 && BB>110 && GG<150 && RR<150 && BB<150) \n"//城市沥青水泥
" { \n"
" Metr_Color = 0.9f; \n"
" color = vec4(Metr_Color, Metr_Color, Metr_Color, 1.0f); \n"
" } \n"
" else \n"
" { \n"
" if (RR <157.0&& GG>52.0& GG < 98.0&BB>31.0&BB<78.0) \n"//绿色植被
" { \n"
" Metr_Color = 0.95f; \n"
" color = vec4(Metr_Color, Metr_Color, Metr_Color, 1.0f); \n"
" } \n"
" else \n"
" { \n"
" if (RR >180.0&& GG>180.0&BB>180.0) \n"//冰川雪山————暂时未知
" { \n"
" Metr_Color = 0.555555f; \n"
" color = vec4(Metr_Color, Metr_Color, Metr_Color, 1.0f); \n"
" } \n"
" else \n"
" { \n"
" if ((BB <197.0&&BB >27.0&&RR>21 && RR<98 && GG>22.0&&GG < 148.0 && (!(RR <157.0&& GG>52.0& GG < 98.0&BB>31.0&BB<78.0)))) \n"//海洋水面
" { \n"
" Metr_Color = 0.98f; \n"
" color = vec4(Metr_Color, Metr_Color, Metr_Color, 1.0f); \n"
" } \n"
" else \n"
" { \n"
" if (RR>101 && GG>100 && BB>120 && (GG - BB>10) && (RR - GG>10)) \n"//干燥裸土
" { \n"
" Metr_Color = 0.80f; \n"
" color = vec4(Metr_Color, Metr_Color, Metr_Color, 1.0f); \n"
" } \n"
" else \n"
" { \n"
" Metr_Color = 0.930f; \n"
" color = vec4(Metr_Color, Metr_Color, Metr_Color, 1.0f); \n"//其他未知
" } \n"
" } \n"
" \n"
" } \n"
" \n"
" } \n"
" \n"
" } \n"
" } \n"
"} ";
//森林:RR <157.0&& GG>52.0& GG < 98.0&BB>31.0&BB<78.0
//雪山:RR >180.0&& GG>180.0&BB>180.0
//海洋:(BB <197.0&&BB >27.0&&RR>21&&RR<98&& GG>22.0&&GG < 148.0&&(!(RR <157.0&& GG>52.0& GG < 98.0&BB>31.0&BB<78.0)))
//沙漠:( RR>121 &&GG>100&&BB>120&&(GG-BB>10)&&(RR-GG>10))(澳大利亚有一部分没有分进,可能是起步点设置太大)
//城市:( RR>110 &&GG>110&&BB>110&&GG<150&&RR<150&&BB<150)
//发射率表:{干燥裸土:0.8/0.4(发射率/反射率),低植覆盖:0.95/0.8,混凝土沥青:0.9/0.25,海面:0.98,湿土地:0.85/0.2}
//参数1:被调用的函数名字,参数2:函数的字符串索引(也可能功能是文件的路径中的内容——待定),参数3:函数被加入的位置
vp->setFunction("setup_haze", haze_vertex, osgEarth::ShaderComp::LOCATION_VERTEX_CLIP);//将自定义着色器函数setup_haze(),放在系统默认main函数中LOCATION_VERTEX_CLIP下面。
vp->setFunction("apply_haze", haze_fragment, osgEarth::ShaderComp::LOCATION_FRAGMENT_COLORING);
}
}
MYDLL_API void MyDllSpace::MyDllClass::EarthShader(osg::Group* root)
{
{
#if 1
{//自己写太阳法线着色2020年7月3日10:29:49,参考:可以实现从制动角度输入光源,和法相作用,在地球上产生光照效果,问题是:鼠标操作时,物体会移动,光源不移动,感觉是光源没有挂到这个地球的node上。而是和相机还是viewer还是视口跟着走了,需要进一步研究2020年7月6日17:02:34
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
stateset = root->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON); // 启用光照
stateset->setMode(GL_LIGHT0, osg::StateAttribute::ON); // 启用指定光源
stateset->addUniform(new osg::Uniform("direction_color", osg::Vec3f(0.583867f, 0.714617f, 0.385256f))); //0.583867 0.714617 0.385256
osgEarth::VirtualProgram* vp = osgEarth::VirtualProgram::getOrCreate(stateset);
VirtualProgram(vp);
}
#endif
}
}