(第一次写,有错误恳请指正XD)

(希望能帮助到感兴趣的小伙伴)

(看客别看到这么多代码就想走!! 后面有生成示例:3)

先放张图介绍一下各个类的基本功能

首先进入程序入口

int main(int argc, char* argv[])

{

// create the application instance if (LAppDelegate::GetInstance()->Initialize() == GL_FALSE) //分配器初始化 {

return 1;

}

LAppDelegate::GetInstance()->Run(); //运行 return 0;

}

一、先看bool LAppDelegate::Initialize()

//首先是gl窗口的生成(具体请看https://learnopengl-cn.github.io/)//注册回调函数 glfwSetMouseButtonCallback(_window, EventHandler::OnMouseCallBack);

glfwSetCursorPosCallback(_window, EventHandler::OnMouseCallBack);

//然后是一系列初始化 _view->Initialize(); //范围初始化

InitializeCubism(); //Cubism初始化

SetRootDirectory(); //路径设置

LAppLive2DManager::GetInstance(); //模型管理类初始化

_view->InitializeSprite(); //背景及其控件初始化

范围设定 有需求可以更改..

Cubism初始化无脑CtrlCV

背景和控件的话最终可能需要去掉 自己调用所使用的接口 所以..有需要再说吧(其实是没研究到)

(一)模型管理类LAppLive2DManager

static LAppLive2DManager* GetInstance(); //指针获取

static void ReleaseInstance(); //指针释放

LAppModel* GetModel(Csm::csmUint32 no) const; //根据下标获取模型

void ReleaseAllModel(); //释放所有模型

void OnDrag(Csm::csmFloat32 x, Csm::csmFloat32 y) const; //模型跟随鼠标

void OnTap(Csm::csmFloat32 x, Csm::csmFloat32 y); //表情触发

void OnUpdate() const; //模型参数更新

void NextScene(); //切换下一个模型

void ChangeScene(Csm::csmInt32 index); //根据坐标切换模型

Csm::csmUint32 GetModelNum() const; //获取模型数

1.LAppLive2DManager初始化

LAppLive2DManager::LAppLive2DManager()

: _viewMatrix(NULL) //背景矩阵? , _sceneIndex(0) //当前模型下标{

ChangeScene(_sceneIndex); //切换到第一个模型}

2.ChangeScene //根据坐标切换模型

获取文件到加载模型的主要代码

std::string model = ModelDir[index]; //模型名称数组 //路径获取 std::string modelPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath + model + "/";

std::string modelJsonName = ModelDir[index];

modelJsonName += ".model3.json";

ReleaseAllModel(); //释放所有模型 //_models是一个官方的简易Vector //声明: Csm::csmVector _models; _models.PushBack(new LAppModel()); //压一个新模型 _models[0]->LoadAssets(modelPath.c_str(), modelJsonName.c_str()); //加载模型资源

比较奇葩的就是 明明每次只加载一个模型 但是却会获取所有的模型并进行更新(

3.voidOnDrag(Csm::csmFloat32 x, Csm::csmFloat32 y)const;//模型跟随鼠标

//通过这个接口改变朝向值参数model->SetDragging(x, y);

4.voidOnTap(Csm::csmFloat32 x, Csm::csmFloat32 y);//表情触发

for (csmUint32 i = 0; i < _models.GetSize(); i++) //走一遍所有模型 {

if (_models[i]->HitTest(HitAreaNameHead, x, y)) //判断点击是否有效 {

_models[i]->SetRandomExpression(); //随机表情 }

else if (_models[i]->HitTest(HitAreaNameBody, x, y))

{

//随机动作 第一个参数身体触摸动作组 第二个优先级 第三个打印信息 _models[i]->StartRandomMotion(MotionGroupTapBody, PriorityNormal, FinishedMotion);

}

}

5.voidNextScene();//切换下一个模型

//这个就不说了(csmInt32 no = (_sceneIndex + 1) % ModelDirSize; //_sceneIndex当前模型下标 ModelDirSize模型数 ChangeScene(no);

(二)然后进入到LAppModel类(因为有很多内容 只挑选可能会使用到的接口函数)

void Update(); //模型更新

void Draw(Csm::CubismMatrix44& matrix); //通过模型矩阵绘制模型

//判断触摸点(比较尴尬的一个功能 很多模型没有触摸点)virtual Csm::csmBool HitTest(const Csm::csmChar* hitAreaName, Csm::csmFloat32 x, Csm::csmFloat32 y);

1.void Update();

//首先是获取刷新间隔时间const csmFloat32 deltaTimeSeconds = LAppPal::GetDeltaTime();

_userTimeSeconds += deltaTimeSeconds; //累加

//模型跟随鼠标动作 _dragManager->Update(deltaTimeSeconds);

//获取鼠标对应的live2d坐标下的x, y值//也就是已经被转换之后的坐标 _dragX = _dragManager->GetX();

_dragY = _dragManager->GetY();

//相关的是这一组函数 _model->AddParameterValue(_idParamAngleX, _dragX * 30); // -30から30の値を加える _model->AddParameterValue(_idParamAngleY, _dragY * 30);

_model->AddParameterValue(_idParamAngleZ, _dragX * _dragY * -30);

//ドラッグによる体の向きの調整 _model->AddParameterValue(_idParamBodyAngleX, _dragX * 10); // -10から10の値を加える //ドラッグによる目の向きの調整 _model->AddParameterValue(_idParamEyeBallX, _dragX); // -1から1の値を加える _model->AddParameterValue(_idParamEyeBallY, _dragY);

//模型动作更新if (_motionManager->IsFinished()) //判断动作是否完成 {

//开始随机动作,第一个参数是模型闲置时的动作组,第二个参数是动作优先度 StartRandomMotion(MotionGroupIdle, PriorityIdle);

}

else

{

//动作未完成则继续更新动作 motionUpdated = _motionManager->UpdateMotion(_model, deltaTimeSeconds);

}

//以下

2.voidDraw(Csm::CubismMatrix44& matrix);这个主要是通过传入的矩阵matrix进行改变模型的位置、大小等参数

3.virtual Csm::csmBool HitTest(const Csm::csmChar* hitAreaName, Csm::csmFloat32 x, Csm::csmFloat32 y);

if (_opacity < 1){return false;} //透明度判定 const csmInt32 count = _modelSetting->GetHitAreasCount(); //模型触摸点数 for (csmInt32 i = 0; i < count; i++)

{

if (strcmp(_modelSetting->GetHitAreaName(i), hitAreaName) == 0) //匹配触摸点名称 {

const CubismIdHandle drawID = _modelSetting->GetHitAreaId(i); //获取触摸点id return IsHit(drawID, x, y); //判定是否被点击到 }

}

return false; //不存在返回false

现在初始化已经完成 转到

二、void LAppDelegate::Run()

//首先这个应该是获取窗口大小然后调整渲染范围 自适应窗口glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);

if((_windowWidth!=width || _windowHeight!=height) && width>0 && height>0)

{

_view->Initialize();

_view->ResizeSprite();

_windowWidth = width;

_windowHeight = height;

}

// 時間更新 LAppPal::UpdateTime();

//opengl清屏 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glClearDepth(1.0);

//渲染背景及模型 _view->Render();

//以下

函数包含一个while循环

while (glfwWindowShouldClose(_window) == GL_FALSE && !_isEnd)

{

}

//通过两个函数改变和获取程序开关信号 bool GetIsEnd() { return _isEnd; }

void AppEnd() { _isEnd = true; }

(一)_view->Render();视窗渲染 LAppView类实现

_back->Render(); //背景 _gear->Render(); //齿轮 也就是切换模型按钮 _power->Render(); //关闭程序

//然后就是通过模型管理类更新模型 LAppLive2DManager* Live2DManager = LAppLive2DManager::GetInstance();

Live2DManager->OnUpdate();

//然后是背景的渲染更新就不说了(

1.void LAppLive2DManager::OnUpdate() const 模型管理类的更新

//这个就是上面所说的模型矩阵 CubismMatrix44 projection;

int width, height;

glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height); //获取窗口大小//通过这个函数可以改变模型大小 projection.Scale(1.0f, static_cast(width) / static_cast(height));

const CubismMatrix44 saveProjection = projection;

csmUint32 modelCount = _models.GetSize(); //获取模型数量 for (csmUint32 i = 0; i < modelCount; ++i)

{

LAppModel* model = GetModel(i); //通过下标获取模型 projection = saveProjection;

LAppDelegate::GetInstance()->GetView()->PreModelDraw(*model); //背景渲染相关 可以不用管

model->Update(); //模型参数更新 model->Draw(projection); //通过模型矩阵设置来绘制模型

LAppDelegate::GetInstance()->GetView()->PostModelDraw(*model); //同上 }

(二)然后是两个回调函数 一个获取鼠标点击和释放事件 一个获取移动事件 在LAppDelegate类中实现

void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify);

void OnMouseCallBack(GLFWwindow* window, double x, double y);

//两个回调函数中主要有三个接口//首先是点击和释放 通过_captured判断是否被pressed_view->OnTouchesBegan(_mouseX, _mouseY);//点击事件_view->OnTouchesEnded(_mouseX, _mouseY);//释放事件//然后通过是否被pressed来判定移动事件_view->OnTouchesMoved(_mouseX, _mouseY);//移动事件

//同样是通过LAppView类实现void LAppView::OnTouchesBegan(float px, float py) const

{

_touchManager->TouchesBegan(px, py); //大概是记录起始位置}

void LAppView::OnTouchesMoved(float px, float py) const

{

//坐标转换 float viewX = this->TransformViewX(_touchManager->GetX());

float viewY = this->TransformViewY(_touchManager->GetY());

//改变所储存的移动中的鼠标位置 _touchManager->TouchesMoved(px, py);

//模型跟随鼠标 LAppLive2DManager* Live2DManager = LAppLive2DManager::GetInstance(); //获取模型管理类指针//模型跟随鼠标接口 Live2DManager->OnDrag(viewX, viewY);

}

void LAppView::OnTouchesEnded(float px, float py) const

{

LAppLive2DManager* live2DManager = LAppLive2DManager::GetInstance(); //获取模型管理类指针 live2DManager->OnDrag(0.0f, 0.0f); //模型朝向还原为初始状态 {

//坐标变换 float x = _deviceToScreen->TransformX(_touchManager->GetX()); // 論理座標変換した座標を取得。 float y = _deviceToScreen->TransformY(_touchManager->GetY()); // 論理座標変換した座標を取得。

//根据结束点击的鼠标位置触发相应功能 //模型动作触发 live2DManager->OnTap(x, y);

//点击到齿轮就切换下一个模型 if (_gear->IsHit(px, py))

{

live2DManager->NextScene();

}

//关闭程序 if (_power->IsHit(px, py))

{

LAppDelegate::GetInstance()->AppEnd();

}

}

}

最后是生成可执行程序的步骤 也是 @w2014 大大的方法(

2.然后在CubismSdkForNative-4-r.1\Samples\OpenGL\thirdParty\scripts中执行setup_glew_glfw.bat 等待执行完成(很可能会失败 如果实在不行就自己手动下载 速度也快)下载好的应该有两个文件glew和glfw 放入CubismSdkForNative-4-r.1\Samples\OpenGL\thirdParty中

3.找到CubismSdkForNative-4-r.1\Samples\OpenGL\Demo\proj.win.cmake中的CMakeLists.txt (63-65行)

修改后

4.找到Visual Studio 2019\Visual Studio Tools\VC 或者开始菜单

根据自己计算机使用不同的命令符窗口(x64是64位 x86是32位)

运行后先用d:移动到d盘 然后通过cd指令 到cmake的文件夹 打开cmake-gui.exe

5.打开cmake后可以看到两个地址框

第一个填写自己live2dsdk所在的位置加上CubismSdkForNative-4-r.1\Samples\OpenGL\Demo\proj.win.cmake(比如我的地址D:\file\live2dsdk\CubismSdkForNative-4-r.1\Samples\OpenGL\Demo\proj.win.cmake)

第二个填写可执行文件输出的位置

输入完毕后点击Configure

选择NMake Makefiles 然后其他默认Finish

之后就会生成配置

建议修改这个配置

然后其他默认 继续Configure 最后Generate

6.然后我们再运行刚才的命令符窗口

cd到我们刚刚填写的第二个地址框的可执行程序(比如我填写的是D:\file\live2dsdk\CubismSdkForNative-4-r.1\Samples\OpenGL\Demo\proj.win.cmake\build4)

执行namke指令

等待执行完成

终于!!! 我们完成了

找到可执行文件目录中的\bin\Demo

(最终效果展示)

(有背景)

(持续更新中.....)

(死亡排版 尽请吐槽X3)

live2dmesh渲染优先级_live2dsdk的opengl示例详解相关推荐

  1. rcs开机启动mysql_linux添加开机自启动脚本示例详解-阿里云开发者社区

    linux添加开机自启动脚本示例详解 double2li 2017-04-14 1652浏览量 简介: linux下(以RedHat为范本)添加开机自启动脚本有两种方法,先来简单的;一.在/etc/r ...

  2. OpenGL纹理详解

    OpenGL纹理详解 现实生活中,纹理最通常的作用是装饰我们的物体模型,它就像是贴纸一样贴在物体表面,使得物体表面拥有图案.但实际上在OpenGL中,纹理的作用不仅限于此,它可以用来存储大量的数据,一 ...

  3. Android openGl开发详解(二)

    https://zhuanlan.zhihu.com/p/35192609 Android openGl开发详解(二)--通过SurfaceView,TextureView,GlSurfaceView ...

  4. Android openGl开发详解(二)——通过SurfaceView,TextureView,GlSurfaceView显示相机预览(附Demo)

    最近公司在做自定义相机这一块,之前使用的是第三方,后来需求变更,第三方不支持添加动态贴纸,所以只能自己扩展.当然网上有很多例子,但是关于添加动态贴纸的例子几乎找不到,反正我是没找到(欲哭无泪).当然, ...

  5. 微信小程序 php毛玻璃,微信小程序 CSS filter(滤镜)的使用示例详解

    之前在看七月老师的视频的时候,看到了有一个样式是 -webkit-filter ,不知道是什么(我没咋学过CSS,嘿嘿,所以不知道是啥),于是查了一下,原来是滤镜吖.但是在微信小程序里使用的时候,下面 ...

  6. 史上最易懂——ReactNative分组列表SectionList使用详情及示例详解

    React Native系列 <逻辑性最强的React Native环境搭建与调试> <ReactNative开发工具有这一篇足矣> <解决React Native un ...

  7. python中3or5什么意思_示例详解Python3 or Python2 两者之间的差异

    每门编程语言在发布更新之后,主要版本之间都会发生很大的变化. 在本文中,Vinodh Kumar 通过示例解释了 Python 2 和 Python 3 之间的一些重大差异,以帮助说明语言的变化. 本 ...

  8. php reactphp wss_workerman的基本用法(示例详解)

    workerman是什么? Workerman是一个异步事件驱动的PHP框架,具有高性能,可轻松构建快速,可扩展的网络应用程序.支持HTTP,Websocket,SSL和其他自定义协议.支持libev ...

  9. python的用途实例-python assert的用处示例详解

    使用assert断言是学习python一个非常好的习惯,python assert 断言句语格式及用法很简单.在没完善一个程序之前,我们不知道程序在哪里会出错,与其让它在运行最崩溃,不如在出现错误条件 ...

最新文章

  1. java_2018_Day7_静态static
  2. HDU 1271整数对
  3. 第二十三模板 18标准模板库
  4. dao接口有什么好处_Java后端精选技术:我们为什么要使用AOP?
  5. not in SQL语句转化为 not exists
  6. [C#]获得线程池中活动的线程数
  7. SpringMVC执行流程源码分析
  8. vs debug 调试 快捷键
  9. 通过pyenv在Mac OS X 10.12.3下安装Python-3.6.0及“*** [install] Error 1”错误的解决方法
  10. Android 4.0平板,Android4.0.3系统_平板电脑_平板电脑评测-中关村在线
  11. vue web在线聊天功能实现
  12. 彻底搞懂虚拟地址翻译为物理地址的过程
  13. Java整合FFmpeg截取视频某一帧为图片
  14. HinM_COMPILER_cale计划和实现
  15. linux无法解析域名
  16. 解决高度塌陷的几种方法
  17. 项目【QT5.13频谱分析软件】(三)——线程获取Excel表格数据
  18. 课程设计:公交线路管理系统
  19. 在计算机中c语言是属于什么作用,C语言属于下列哪一类计算机语言( )
  20. 如何设置主机电脑静态IP地址

热门文章

  1. 遍历——PowerShell三分钟(十)
  2. 部署Exchange Server 2007 SCC
  3. Centos 6.x/7.x yum安装php5.6.X
  4. 防火墙 之 iptables 匹配条件讲解
  5. Fortinet“安立方”架构获得NSS Labs BDS 组测试多攻击维度100%检出率佳绩
  6. form 表单提交,防止重复提交,加token
  7. Fork 一个仓库并同步
  8. Android Toast自己定义Toast例子
  9. #define 的换行问题
  10. 复解析蕴含不可延拓性