OpenGL三维小球碰撞实现方法(glm、glfw)

萌新刚开始学OpenGL,想做一个三维小球碰撞模拟。一开始试了好多写法,但都有问题,不断改进,终于完成了,感觉有必要记录一下。
摘要由CSDN通过智能技术生成

小萌新刚开始学OpenGL,想做一个三维小球碰撞模拟。一开始试了好多写法,但都有问题,不断改进,终于完成了,感觉有必要记录一下。

首先,为了能够无限添加小球,我采用链表结构,并定义了小球结构体,其中包含小球的各个物理属性。

struct ball {
    glm::vec3 position; //球心坐标
    glm::vec3 speed; //速度矢量
    glm::vec3 color;//可有可无
    float r; //小球半径
    float m; //小球质量
    struct ball* next;
};

在渲染循环里面加上p->position += p->speed * deltaTime;实现小球移动。deltatime为渲染的时间间隔。

然后就是简单的循环,用来筛选发生碰撞的小球。

struct ball* p = head;
struct ball* q;
    while (p != NULL) {      
        q = p->next;
        while ((q != NULL)) {
                if ((veclength(p->position - q->position) <= (p->r + q->r))) {

                }
            q = q->next;
        }
        p = p->next;
    }

接着最关键的就是发生碰撞的两个小球的代码了。

一开始,我尝试先在草稿纸上,把碰撞后的速度算出来。然后if他们之间的距离小于半径之和ÿ

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现三维场景漫游,需要以下步骤: 1. 初始化OpenGL环境,包括窗口和渲染上下文等。 2. 创建3D场景,包括模型、光源、相机等。 3. 实现相机的漫游,可以使用鼠标和键盘控制相机的位置、方向和视角。 4. 渲染3D场景,将场景中的模型、光源和相机等元素绘制到屏幕上。 具体实现步骤如下: 1. 初始化OpenGL环境,包括窗口和渲染上下文等。 ``` //初始化OpenGL环境 glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //创建窗口 GLFWwindow* window = glfwCreateWindow(800, 600, "3D Scene", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); //初始化GLEW glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cout << "Failed to initialize GLEW" << std::endl; return -1; } ``` 2. 创建3D场景,包括模型、光源、相机等。 ``` //创建模型 Model model("cube.obj"); //创建光源 glm::vec3 lightPos(1.2f, 1.0f, 2.0f); //创建相机 Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); ``` 3. 实现相机的漫游,可以使用鼠标和键盘控制相机的位置、方向和视角。 ``` //处理鼠标移动事件 void mouse_callback(GLFWwindow* window, double xpos, double ypos) { static bool firstMouse = true; static float lastX = 400.0f; static float lastY = 300.0f; if (firstMouse) { lastX = xpos; lastY = ypos; firstMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; lastX = xpos; lastY = ypos; camera.ProcessMouseMovement(xoffset, yoffset); } //处理键盘事件 void processInput(GLFWwindow* window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera.ProcessKeyboard(FORWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) camera.ProcessKeyboard(BACKWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) camera.ProcessKeyboard(LEFT, deltaTime); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera.ProcessKeyboard(RIGHT, deltaTime); } //主循环 while (!glfwWindowShouldClose(window)) { //计算帧间隔 float currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; //处理输入事件 processInput(window); //清空颜色缓冲区和深度缓冲区 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //设置模型矩阵、观察矩阵和投影矩阵 glm::mat4 modelMatrix = glm::mat4(1.0f); glm::mat4 viewMatrix = camera.GetViewMatrix(); glm::mat4 projectionMatrix = glm::perspective(glm::radians(camera.Zoom), 800.0f / 600.0f, 0.1f, 100.0f); //绘制模型 model.Draw(shaderProgram, modelMatrix, viewMatrix, projectionMatrix, lightPos); //交换缓冲区和轮询事件 glfwSwapBuffers(window); glfwPollEvents(); } ``` 4. 渲染3D场景,将场景中的模型、光源和相机等元素绘制到屏幕上。 在绘制模型时,需要将模型矩阵、观察矩阵和投影矩阵传递给着色器程序,以计算出最终的顶点位置和颜色。同时,还需要将光源位置和材质属性传递给着色器程序,以计算出最终的颜色。 ``` //绘制模型 void Model::Draw(Shader shader, glm::mat4 modelMatrix, glm::mat4 viewMatrix, glm::mat4 projectionMatrix, glm::vec3 lightPos) { //绑定VAO glBindVertexArray(VAO); //激活着色器程序 shader.Use(); //设置模型矩阵、观察矩阵和投影矩阵 shader.SetMat4("model", modelMatrix); shader.SetMat4("view", viewMatrix); shader.SetMat4("projection", projectionMatrix); //设置光源位置和材质属性 shader.SetVec3("lightPos", lightPos); shader.SetFloat("material.shininess", 32.0f); //绘制模型 for (unsigned int i = 0; i < meshes.size(); i++) { meshes[i].Draw(shader); } //解绑VAO glBindVertexArray(0); } ``` 完整代码示例:https://github.com/JoeyDeVries/LearnOpenGL/blob/master/src/3.model_loading/3.3.model_loading_assimp.cpp

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值