在OpenGL中计算摄像机到立方体平面的距离

kninwzqo  于 2024-01-07  发布在  其他
关注(0)|答案(1)|浏览(188)

我试图让透明度混合在我的立方体上正常工作,但遇到了一点障碍。我已经通过简单地按正确的顺序绘制多个立方体来实现混合,但让它在立方体本身的表面上工作要困难得多。
我想解决这个问题的方法是重新排序EBO中的索引,以便它以正确的顺序绘制面。我已经让它重新排序索引,问题是它们没有被正确排序。
我这样做的方法是这样的:

  1. void GECCube::SortIndicies(glm::mat4 ModelMatrix)
  2. {
  3. glm::vec4 View = glm::vec4{0.0f, 0.0f, -3.0f, 0.f};
  4. unsigned int NewIndices[36];
  5. std::multimap<float, std::vector<unsigned int>> SortedMap;
  6. for (int i = 0; i < 12; i += 2)
  7. {
  8. glm::vec4 Tri1 = glm::vec4{
  9. (Vertices[Indices[i * 3] * 3] + Vertices[Indices[(i * 3) + 1] * 3] + Vertices[Indices[(i * 3) + 2] * 3]) / 3, //X
  10. (Vertices[Indices[i * 3] * 4] + Vertices[Indices[(i * 3) + 1] * 4] + Vertices[Indices[(i * 3) + 2] * 4]) / 3, //Y
  11. (Vertices[Indices[i * 3] * 5] + Vertices[Indices[(i * 3) + 1] * 5] + Vertices[Indices[(i * 3) + 2] * 5]) / 3, //Z
  12. 0.f
  13. };
  14. glm::vec4 Tri2 = glm::vec4{
  15. (Vertices[Indices[(i + 1) * 3] * 3] + Vertices[Indices[((i + 1) * 3) + 1] * 3] + Vertices[Indices[((i + 1) * 3) + 2] * 3]) / 3, //X
  16. (Vertices[Indices[(i + 1) * 3] * 4] + Vertices[Indices[((i + 1) * 3) + 1] * 4] + Vertices[Indices[((i + 1) * 3) + 2] * 4]) / 3, //Y
  17. (Vertices[Indices[(i + 1) * 3] * 5] + Vertices[Indices[((i + 1) * 3) + 1] * 5] + Vertices[Indices[((i + 1) * 3) + 2] * 5]) / 3, //Z
  18. 0.f
  19. };
  20. glm::vec4 PlaneMed = glm::vec4{(Tri1.x + Tri2.x) / 2, (Tri1.y + Tri2.y) / 2 , (Tri1.z + Tri2.z) / 2, 0 };
  21. float Distance = glm::length(View - (ModelMatrix * PlaneMed));
  22. std::vector<unsigned int> TransportVector = std::vector<unsigned int>{ Indices[i * 3] , Indices[(i * 3) + 1] , Indices[(i * 3) + 2],
  23. Indices[(i + 1) * 3] , Indices[((i + 1) * 3) + 1] , Indices[((i + 1) * 3) + 2] };
  24. SortedMap.insert(std::pair<float, std::vector<unsigned int>>(Distance, TransportVector));
  25. }
  26. auto MapIterator = SortedMap.begin();
  27. for (int i = 0; i < 12; i += 2)
  28. {
  29. NewIndices[i * 3] = MapIterator->second[0];
  30. NewIndices[(i * 3) + 1] = MapIterator->second[1];
  31. NewIndices[(i * 3) + 2] = MapIterator->second[2];
  32. NewIndices[(i + 1) * 3] = MapIterator->second[3];
  33. NewIndices[((i + 1) * 3) + 1] = MapIterator->second[4];
  34. NewIndices[((i + 1) * 3) + 2] = MapIterator->second[5];
  35. if (i != 10) { MapIterator++; }
  36. }
  37. std::copy(std::begin(NewIndices), std::end(NewIndices), std::begin(Indices));
  38. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
  39. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
  40. }

字符串
我还没有做一些更复杂的相机,所以现在它只是在位置0,0,-3.0
我认为我做错了的地方是当涉及到计算相机和飞机之间的距离。即:

  1. float Distance = glm::length(View - (ModelMatrix * Plane));


最初我只打算使用View - Plane,但我意识到这将为每个索引给予相同的值,因此我考虑如何将Model集成到距离中。我的理由是,既然着色器使用模型矩阵在正确的位置绘制,那么我应该能够使用它来找到模型空间中平面的正确位置。但我认为我错了。
所有这些都在draw函数中集合在一起(它绘制多个立方体):

  1. ...
  2. glm::mat4 model = glm::mat4(1.0f);
  3. model = glm::translate(model, it->second * 0.9f * std::clamp((float) sinf(( float )SDL_GetTicks() / 1000.f) + 1.5f, 0.f, 3.f));
  4. float angle = 20.0f * ((i + 1)/20) * ( float )SDL_GetTicks() / 200 * glm::radians(50.0f);
  5. model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
  6. OGLCMain->MainCube.SortIndicies(model);
  7. int modelLoc = glGetUniformLocation(OGLCMain->ShaderProgram, "model");
  8. glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
  9. glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
  10. ...

8fsztsew

8fsztsew1#

所以我通过改变距离代码来使系统工作,该距离代码将使用相机前向量上的向量的点积来计算

  1. Plane = ModelMatrix * Plane
  2. float Distance = glm::dot((CameraPos - Plane), CameraFront);

字符串
并且通过将平面med的计算方式改变为:

  1. glm::vec4 Plane = glm::vec4{
  2. (Vertices[(Indices[(i) * 3] * 5)] + Vertices[(Indices[((i) * 3) + 1] * 5)] + Vertices[(Indices[((i) * 3) + 2] * 5)] + Vertices[(Indices[((i + 1) * 3) + 1] * 5)]) / 4.f,
  3. (Vertices[(Indices[(i) * 3] * 5) + 1] + Vertices[(Indices[((i) * 3) + 1] * 5) + 1] + Vertices[(Indices[((i) * 3) + 2] * 5) + 1] + Vertices[(Indices[((i + 1) * 3) + 1] * 5) + 1]) / 4.f,
  4. (Vertices[(Indices[(i) * 3] * 5) + 2] + Vertices[(Indices[((i) * 3) + 1] * 5) + 2] + Vertices[(Indices[((i) * 3) + 2] * 5) + 2] + Vertices[(Indices[((i + 1) * 3) + 1] * 5) + 2]) / 4.f,
  5. 1.f };


我还颠倒了它放回去的顺序:

  1. auto MapIterator = SortedMap.begin();
  2. for (int i = 11; i > 0; i -= 2)
  3. {
  4. NewIndices[i * 3] = MapIterator->second[0];
  5. NewIndices[(i * 3) + 1] = MapIterator->second[1];
  6. NewIndices[(i * 3) + 2] = MapIterator->second[2];
  7. NewIndices[(i - 1) * 3] = MapIterator->second[3];
  8. NewIndices[((i - 1) * 3) + 1] = MapIterator->second[4];
  9. NewIndices[((i - 1) * 3) + 2] = MapIterator->second[5];
  10. MapIterator++;
  11. }


并将距离计算改为:

  1. float Distance = -glm::dot((CameraPos - Plane), CameraFront);

**但是!**这应该没关系,因为这两个都颠倒了顺序,因此净变化为0。

为了清楚起见,我在这个项目中使用的顶点和索引数组看起来像这样:

  1. GLfloat TempVertices[] = {
  2. -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // A 0
  3. 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, // B 1
  4. 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, // C 2
  5. -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, // D 3
  6. -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, // E 4
  7. 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, // F 5
  8. 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // G 6
  9. -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, // H 7
  10. -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, // D 8
  11. -0.5f, -0.5f, -0.5f, 1.0f, 0.0f, // A 9
  12. -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, // E 10
  13. -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, // H 11
  14. 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // B 12
  15. 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, // C 13
  16. 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // G 14
  17. 0.5f, -0.5f, 0.5f, 0.0f, 1.0f, // F 15
  18. -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, // A 16
  19. 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, // B 17
  20. 0.5f, -0.5f, 0.5f, 1.0f, 1.0f, // F 18
  21. -0.5f, -0.5f, 0.5f, 0.0f, 1.0f, // E 19
  22. 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, // C 20
  23. -0.5f, 0.5f, -0.5f, 1.0f, 0.0f, // D 21
  24. -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // H 22
  25. 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, // G 23
  26. };
  27. unsigned int TempIndices[] = {
  28. // front and back
  29. 0, 3, 2,
  30. 2, 1, 0,
  31. 4, 5, 6,
  32. 6, 7 ,4,
  33. // left and right
  34. 11, 8, 9,
  35. 9, 10, 11,
  36. 12, 13, 14,
  37. 14, 15, 12,
  38. // bottom and top
  39. 16, 17, 18,
  40. 18, 19, 16,
  41. 20, 21, 22,
  42. 22, 23, 20
  43. };

展开查看全部

相关问题