当前位置: 首页 > news >正文

实用指南:复原大唐3d项目测试版

一个可以完美复原大唐风土人情的VR计划!!!!!就是这

这里只是最初的测试版本,得下载多个库,以后会有更多方法

:

// TangDynastyVR_Complete.h
#pragma once

#include <openvr.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <vector>
#include <memory>
#include <string>
#include <map>
#include <random>

// 情感状态枚举
enum class EmotionalState {
NEUTRAL, JOYFUL, ANGRY, SAD, POETIC, NOSTALGIC, PROUD
};

// 对话消息结构
struct DialogueMessage {
std::string speakerName;
std::string content;
float displayTime;
glm::vec3 speakerPosition;
bool isHistoricalFigure;
};

// 基础场景对象
class SceneObject {
public:
virtual ~SceneObject() = default;
virtual void render(const glm::mat4& view, const glm::mat4& projection) = 0;
virtual void update(float deltaTime) = 0;
};

// 唐朝人物基类
class TangCharacter : public SceneObject {
protected:
glm::vec3 position;
glm::mat4 modelMatrix;
GLuint VAO, VBO;
float animationTime = 0.0f;

public:
TangCharacter(const glm::vec3& pos) : position(pos) {}
virtual ~TangCharacter() = default;

void update(float deltaTime) override {
animationTime += deltaTime;
// 基础动画逻辑
}

void render(const glm::mat4& view, const glm::mat4& projection) override {
// 基础渲染逻辑
}
};

// 人物性格系统
class HistoricalPersonality {
private:
std::map<EmotionalState, std::vector<std::string>> dialogues;
EmotionalState currentState = EmotionalState::NEUTRAL;

public:
void setDialogues(EmotionalState state, const std::vector<std::string>& lines) {
dialogues[state] = lines;
}

std::string speak(EmotionalState state) {
currentState = state;
auto& stateDialogues = dialogues[state];
if (stateDialogues.empty()) return "";

std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, stateDialogues.size() - 1);
return stateDialogues[dis(gen)];
}

EmotionalState getCurrentState() const { return currentState; }
};

// 增强的唐朝人物类
class EnhancedTangCharacter : public TangCharacter {
private:
std::string characterName;
std::string characterType;
HistoricalPersonality personality;
EmotionalState currentEmotion;
float emotionChangeTimer = 0;
float speakCooldown = 0;
bool canSpeak = true;

public:
EnhancedTangCharacter(const std::string& name, const std::string& type, const glm::vec3& pos)
: TangCharacter(pos), characterName(name), characterType(type),
currentEmotion(EmotionalState::NEUTRAL) {
initializePersonality();
}

void initializePersonality() {
if (characterType == "libai") {
personality.setDialogues(EmotionalState::POETIC, {
"李白:(举杯邀月)人生得意须尽欢,莫使金樽空对月!这月色如此美好,当浮一大白!",
"李白:我本楚狂人,凤歌笑孔丘。手持绿玉杖,朝别黄鹤楼。哈哈哈!痛快!"
});
personality.setDialogues(EmotionalState::JOYFUL, {
"李白:今日得见知己,当痛饮三百杯!店家,再上酒来!",
"李白:这长安繁华,盛唐气象,能生于此世,实乃我辈之幸!"
});
personality.setDialogues(EmotionalState::SAD, {
"李白:(叹息)大道如青天,我独不得出...这满腹才华,何时才能得遇明主?",
"李白:花间一壶酒,独酌无相亲。举杯邀明月,对影成三人...寂寞啊寂寞。"
});
} else if (characterType == "dufu") {
personality.setDialogues(EmotionalState::SAD, {
"杜甫:(忧心忡忡)朱门酒肉臭,路有冻死骨...这世道,百姓苦啊!",
"杜甫:国破山河在,城春草木深。感时花溅泪,恨别鸟惊心...大唐何时才能重振?"
});
personality.setDialogues(EmotionalState::ANGRY, {
"杜甫:(愤慨)官军收洛阳,家住洛阳里。夫婿与兄弟,目前见伤死!这战乱何时休!"
});
} else if (characterType == "merchant") {
personality.setDialogues(EmotionalState::NEUTRAL, {
上等货色!",就是"西域商人:(展示货物)来自波斯的琉璃,大食的香料,都
"西域商人:这丝绸之路真是黄金之路啊!从长安到罗马,处处是商机!"
});
}
}

void update(float deltaTime) override {
TangCharacter::update(deltaTime);

// 情绪状态变化
emotionChangeTimer -= deltaTime;
if (emotionChangeTimer <= 0) {
changeEmotionRandomly();
emotionChangeTimer = 10.0f + (rand() % 20);
}

// 说话冷却
if (!canSpeak) {
speakCooldown -= deltaTime;
if (speakCooldown <= 0) canSpeak = true;
}
}

void changeEmotionRandomly() {
if (characterType == "libai") {
std::vector<EmotionalState> emotions = {
EmotionalState::POETIC, EmotionalState::JOYFUL, EmotionalState::POETIC, EmotionalState::NOSTALGIC
};
currentEmotion = emotions[rand() % emotions.size()];
} else if (characterType == "dufu") {
std::vector<EmotionalState> emotions = {
EmotionalState::SAD, EmotionalState::ANGRY, EmotionalState::NOSTALGIC, EmotionalState::SAD
};
currentEmotion = emotions[rand() % emotions.size()];
}
}

void speak(class DialogueUIManager& dialogueManager) {
if (!canSpeak) return;

std::string dialogue = personality.speak(currentEmotion);
if (!dialogue.empty()) {
dialogueManager.addMessage(characterName, dialogue, position, true);
speakCooldown = 8.0f + (rand() % 7);
canSpeak = false;
}
}

const std::string& getName() const { return characterName; }
};

// 对话UI管理器
class DialogueUIManager {
private:
struct DialogueUI {
GLuint VAO, VBO, EBO;
GLuint texture;
glm::vec2 position = glm::vec2(0.1f, 0.1f);
glm::vec2 size = glm::vec2(0.8f, 0.2f);
bool isVisible = false;
};

DialogueUI dialogueUI;
std::vector<DialogueMessage> messageQueue;
DialogueMessage currentMessage;
float messageTimer = 0;
bool isShowingMessage = false;
GLuint shaderProgram;

public:
DialogueUIManager() = default;

bool initialize() {
createDialogueBackground();

const char* vs = R"(
#version 330 core
layout(location = 0) in vec2 aPos;
uniform vec2 uScreenSize;
void main() {
vec2 normalizedPos = aPos / uScreenSize;
gl_Position = vec4(normalizedPos * 2.0 - 1.0, 0.0, 1.0);
}
)";

const char* fs = R"(
#version 330 core
out vec4 FragColor;
uniform vec4 uColor;
void main() {
FragColor = uColor;
}
)";

// shaderProgram = ShaderManager::compileShaders(vs, fs);
return true; // shaderProgram != 0;
}

void createDialogueBackground() {
float x = dialogueUI.position.x, y = dialogueUI.position.y;
float w = dialogueUI.size.x, h = dialogueUI.size.y;

float vertices[] = { x, y, x+w, y, x+w, y+h, x, y+h };
unsigned int indices[] = { 0, 1, 2, 2, 3, 0 };

glGenVertexArrays(1, &dialogueUI.VAO);
glGenBuffers(1, &dialogueUI.VBO);
glGenBuffers(1, &dialogueUI.EBO);

glBindVertexArray(dialogueUI.VAO);
glBindBuffer(GL_ARRAY_BUFFER, dialogueUI.VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, dialogueUI.EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
}

void addMessage(const std::string& speaker, const std::string& content,
const glm::vec3& position = glm::vec3(0), bool isHistorical = false) {
DialogueMessage msg{speaker, content, 5.0f, position, isHistorical};
messageQueue.push_back(msg);
}

void update(float deltaTime) {
if (isShowingMessage) {
messageTimer -= deltaTime;
if (messageTimer <= 0) {
isShowingMessage = false;
dialogueUI.isVisible = false;
}
}

if (!isShowingMessage && !messageQueue.empty()) {
currentMessage = messageQueue.front();
messageQueue.erase(messageQueue.begin());

dialogueUI.isVisible = true;
isShowingMessage = true;
messageTimer = currentMessage.displayTime;
}
}

void render() {
if (!dialogueUI.isVisible) return;

glUseProgram(shaderProgram);
glBindVertexArray(dialogueUI.VAO);

// 设置uniform并渲染
GLint screenSizeLoc = glGetUniformLocation(shaderProgram, "uScreenSize");
glUniform2f(screenSizeLoc, 1920.0f, 1080.0f);
glUniform4f(glGetUniformLocation(shaderProgram, "uColor"), 0.0f, 0.0f, 0.0f, 0.7f);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

// 这里应该渲染文本
// renderText(currentMessage.speakerName + ":" + currentMessage.content, ...);
}
};

// 主VR应用类
class TangDynastyVRApp {
private:
GLFWwindow* window;
vr::IVRSystem* vrSystem;

// 渲染资源
GLuint leftEyeFramebuffer, rightEyeFramebuffer;
GLuint leftEyeTexture, rightEyeTexture;

// 场景管理
std::vector<std::shared_ptr<SceneObject>> sceneObjects;
std::vector<std::shared_ptr<EnhancedTangCharacter>> characters;
DialogueUIManager dialogueManager;

// 着色器
GLuint shaderProgram;

public:
TangDynastyVRApp() : window(nullptr), vrSystem(nullptr), shaderProgram(0) {}

bool initialize() {
if (!initializeOpenGL() || !initializeVR()) return false;

setupVRRenderTargets();
dialogueManager.initialize();
initializeScene();

return true;
}

bool initializeOpenGL() {
if (!glfwInit()) return false;

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
window = glfwCreateWindow(800, 600, "唐朝VR体验", nullptr, nullptr);

if (!window) {
glfwTerminate();
return false;
}

glfwMakeContextCurrent(window);
return glewInit() == GLEW_OK;
}

bool initializeVR() {
vr::EVRInitError error = vr::VRInitError_None;
vrSystem = vr::VR_Init(&error, vr::VRApplication_Scene);
return error == vr::VRInitError_None;
}

void initializeScene() {
// 创建历史人物
auto liBai = std::make_shared<EnhancedTangCharacter>("李白", "libai", glm::vec3(2, 0, -3));
auto duFu = std::make_shared<EnhancedTangCharacter>("杜甫", "dufu", glm::vec3(-2, 0, -3));
auto merchant = std::make_shared<EnhancedTangCharacter>("西域商人", "merchant", glm::vec3(0, 0, -4));

characters.push_back(liBai);
characters.push_back(duFu);
characters.push_back(merchant);

// 添加到场景对象
for (auto& character : characters) {
sceneObjects.push_back(character);
}
}

void setupVRRenderTargets() {
// 创建VR渲染目标
glGenFramebuffers(1, &leftEyeFramebuffer);
glGenFramebuffers(1, &rightEyeFramebuffer);
// ... 更多初始化代码
}

void run() {
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();

float deltaTime = 0.016f; // 假设60FPS

// 更新所有对象
for (auto& obj : sceneObjects) {
obj->update(deltaTime);
}

// 随机触发对话
for (auto& character : characters) {
if (rand() % 600 < 1) { // 约每秒有1/600几率触发
character->speak(dialogueManager);
}
}

dialogueManager.update(deltaTime);

// VR渲染
renderVRScene();

glfwSwapBuffers(window);
}
}

void renderVRScene() {
// 渲染左眼
glBindFramebuffer(GL_FRAMEBUFFER, leftEyeFramebuffer);
renderEye(vr::Eye_Left);

// 渲染右眼
glBindFramebuffer(GL_FRAMEBUFFER, rightEyeFramebuffer);
renderEye(vr::Eye_Right);

// 提交到VR合成器
// vr::VRCompositor()->Submit(...);
}

void renderEye(vr::Hmd_Eye eye) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// 设置视图和投影矩阵
glm::mat4 view = getEyeViewMatrix(eye);
glm::mat4 projection = getEyeProjectionMatrix(eye);

// 渲染场景对象
for (auto& obj : sceneObjects) {
obj->render(view, projection);
}

// 渲染UI
dialogueManager.render();
}

glm::mat4 getEyeViewMatrix(vr::Hmd_Eye eye) {
// 获取VR眼睛视图矩阵
return glm::mat4(1.0f);
}

glm::mat4 getEyeProjectionMatrix(vr::Hmd_Eye eye) {
// 获取VR眼睛投影矩阵
return glm::mat4(1.0f);
}

~TangDynastyVRApp() {
if (vrSystem) vr::VR_Shutdown();
if (window) glfwDestroyWindow(window);
glfwTerminate();
}
};

// 主函数
int main() {
TangDynastyVRApp app;

if (app.initialize()) {
std::cout << "启动唐朝VR体验..." << std::endl;
app.run();
}

return 0;
}

http://www.jsqmd.com/news/54154/

相关文章:

  • 2025年值得关注的纸杯机与纸碗机、纸盖机一体化解决方案提供商
  • 从纸杯到纸盘全覆盖!2025 全伺服 / 超声波纸杯机 + 纸碗机 / 纸盖机靠谱制杯机推荐
  • 2025年企业独栋招商哪家好?最新口碑测评揭晓,办公场地/企业独栋/园区企业独栋出售推荐排行榜
  • Codeforces Round 1063 (Div. 2) 补题记录
  • 2025最新宠物抓伤急救液品牌怎么选?葆爱堂专注宠物健康,宠物抓伤创面消毒液/宠物消杀,更专业,更安全
  • 从纸杯机到纸盘机!2025 全品类制杯机选购指南:全伺服 / 超声波款 + 纸碗机 / 纸盖机省本技巧
  • 2025最新宠物抓伤应急护理液品牌推荐!宠物抓伤消毒液/宠物消杀/宠物抓伤创面消毒液,专业宠物消杀品权威榜单发布及选择指南,守护爱宠与家人健康
  • 【IEEE出版 | EI检索】第七届国际科技创新学术交流大会暨新能源科学与电力工程国际学术会议(NESEE 2025)
  • DNNRegression(pytorch)
  • 大模型开发技巧记录(不定期更新)
  • 2025年字节跳动奖学金揭晓:20位获奖人才研究方向速览
  • 2025最新宠物抓伤应急护理液品牌推荐!宠物抓伤消毒液/宠物消杀品/宠物抓伤创面消毒液,专业宠物消杀品权威榜单发布,守护健康安全
  • CoaXPress 相机采集卡对比 - Hello
  • Python+Selenium+PO设计模式实战指南
  • 2025年PC砖批发厂家权威推荐榜单:地铺石/仿石材砖‌/石材‌源头厂家精选
  • 2025建材推荐榜:煌匠美缝剂_环氧地坪_彩砂自流平,装修选材必看!
  • 数据泄露已成为现实威胁,你的Salesforce安全做好了吗?
  • 【IEEE出版 | EI检索】第七届国际科技创新学术交流大会暨信息技术与计算机应用学术会议(ITCA 2025)
  • 实用指南:LSTM模型做二分类(PyTorch实现)
  • 河南煌匠建材:专注美缝剂、环氧地坪、彩砂自流平,15年匠心守护优质空间 (2)
  • 6款免费AI毕业论文工具推荐:一键生成+零成本降重,效率翻倍
  • 打开文件夹
  • 2025年11月SEM扫描电镜厂家推荐榜:进口/国产/日立/国仪/钨灯丝/FIB/日立冷场/电子/场发射/高分子/超高分辨率/扫描电镜品牌综合参考指南,上海富泰微——微观视界的硬核担当
  • 玩 Linux 随便记录点东西
  • 占有率最高的工业总线:PROFINET、Modbus 与 EtherCAT
  • 2025年11月深圳网站建设公司TOP榜:知名网站建售/外贸网站建设公司后保障双维度解析
  • 如何判断一个痛点是结构性痛点(值得做生意)还是噪音(不要理会)?
  • 2025年广东家装全屋定制推广权威推荐榜单:广东全屋家具定制/广东全屋整装家具定制/广东全屋定制柜子供货商精选
  • 一文通关天文物理顶刊
  • 企业智能ITR升级指南:客户服务体系的实践思考