如何在OpenGL中设置特定比例?

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

我使用C++和OpenGL。但我需要对象缩放到一定的比例。对于一个游戏引擎。我的目标只是为了比例设置而不是改变。

  1. #define GLFW_INCLUDE_NONE
  2. #include <glm/glm.hpp>
  3. #include <glm/gtc/type_ptr.hpp>
  4. #include <GLFW/glfw3.h>
  5. #include <Glad/glad.h>
  6. #include "vendor/ImGui/imgui.h"
  7. #include "vendor/ImGui/backends/imgui_impl_glfw.h"
  8. #include "vendor/ImGui/backends/imgui_impl_opengl3.h"
  9. #include <stdio.h>
  10. #define WINDOW_WIDTH 640
  11. #define WINDOW_HEIGHT 480
  12. void error_callback(int error, const char* description)
  13. {
  14. fprintf(stderr, "Error: %s\n", description);
  15. }
  16. const char* vertexShaderSource = "#version 330 core\n"
  17. "layout(location = 0) in vec3 aPos;\n"
  18. "uniform mat4 projection;\n"
  19. "void main()\n"
  20. "{\n"
  21. " gl_Position = projection * vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
  22. "}\0";
  23. const char* fragmentShaderSource =
  24. "#version 330 core\n"
  25. "out vec4 FragColor;\n"
  26. "uniform vec2 wsize;\n"
  27. "void main()\n"
  28. "{\n"
  29. " vec2 position = gl_FragCoord.xy;\n"
  30. " FragColor = vec4(position.x/wsize.x, position.x/position.y/wsize.x,position.y/wsize.y, 1.0f);\n"
  31. "}\n\0";
  32. float aspectRatio;
  33. glm::mat4 projection;
  34. void framebuffer_size_callback(GLFWwindow* window, int width, int height)
  35. {
  36. glViewport(0, 0, width, height);
  37. aspectRatio = (float)width / (float)height;
  38. projection = glm::ortho(-aspectRatio, aspectRatio, -1.0f, 1.0f, -1.0f, 1.0f);
  39. }
  40. int main()
  41. {
  42. if (!glfwInit())
  43. {
  44. // Initialization failed
  45. }
  46. glfwSetErrorCallback(error_callback);
  47. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  48. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  49. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  50. GLFWwindow* window = glfwCreateWindow(640, 480, "GL YA!", NULL, NULL);
  51. if (!window)
  52. {
  53. // Window or context creation failed
  54. }
  55. glfwMakeContextCurrent(window);
  56. gladLoadGL();
  57. glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
  58. float vertices[9 * 2] = {
  59. -0.5f, -0.5f, 0.0f,
  60. 0.5f, -0.5f, 0.0f,
  61. 0.5f, 0.5f, 0.0f,
  62. 0.5f, 0.5f, 0.0f,
  63. -0.5f, 0.5f, 0.0f,
  64. -0.5f, -0.5f, 0.0f,
  65. };
  66. glfwSwapInterval(1);
  67. GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
  68. glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
  69. glCompileShader(vertexShader);
  70. GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  71. glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
  72. glCompileShader(fragmentShader);
  73. GLuint shaderProgram = glCreateProgram();
  74. glAttachShader(shaderProgram, vertexShader);
  75. glAttachShader(shaderProgram, fragmentShader);
  76. glLinkProgram(shaderProgram);
  77. glDeleteShader(vertexShader);
  78. glDeleteShader(fragmentShader);
  79. GLuint VBO;
  80. glGenBuffers(1, &VBO);
  81. glBindBuffer(GL_ARRAY_BUFFER, VBO);
  82. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  83. GLuint VAO;
  84. glGenVertexArrays(1, &VAO);
  85. glBindVertexArray(VAO);
  86. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
  87. glEnableVertexAttribArray(0);
  88. IMGUI_CHECKVERSION();
  89. ImGui::CreateContext();
  90. ImGuiIO& io = ImGui::GetIO(); (void)io;
  91. io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
  92. io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
  93. io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
  94. io.ConfigDockingWithShift = false;
  95. ImGui::StyleColorsDark();
  96. const char* glsl_version = "#version 100";
  97. ImGui_ImplGlfw_InitForOpenGL(window, true);
  98. ImGui_ImplOpenGL3_Init(glsl_version);
  99. float x = 0;
  100. float y = 0;
  101. float z = 0;
  102. while (!glfwWindowShouldClose(window))
  103. {
  104. int width, height;
  105. glfwGetFramebufferSize(window, &width, &height);
  106. framebuffer_size_callback(window, width, height);
  107. ImGui_ImplOpenGL3_NewFrame();
  108. ImGui_ImplGlfw_NewFrame();
  109. ImGui::NewFrame();
  110. ImGui::DockSpaceOverViewport(ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
  111. ImGui::Begin("Hello OpenGL!");
  112. ImGui::InputFloat("X", &x);
  113. ImGui::InputFloat("Y", &y);
  114. ImGui::InputFloat("Z", &z);
  115. ImGui::End();
  116. ImGui::Render();
  117. glViewport(0, 0, width, height);
  118. glClear(GL_COLOR_BUFFER_BIT);
  119. //Square
  120. glUseProgram(shaderProgram);
  121. GLint wsize = glGetUniformLocation(shaderProgram, "wsize");
  122. glUniform2f(wsize, width, height);
  123. /*
  124. glm::mat4 transform = glm::mat4(1.0f); // Start with an identity matrix
  125. transform = glm::translate(transform, glm::vec3(x, y, z)); // Move the triangle along the x and y axes
  126. for (int i = 0; i < 9 * 2; i += 3) {
  127. glm::vec4 vertex = transform * glm::vec4(vertices[i], vertices[i + 1], vertices[i + 2], 1.0f);
  128. vertices[i] = vertex.x;
  129. vertices[i + 1] = vertex.y;
  130. vertices[i + 2] = vertex.z;
  131. }
  132. */
  133. float currentX = 0.0f;
  134. float currentY = 0.0f;
  135. float currentZ = 0.0f;
  136. for (int i = 0; i < 9 * 2; i += 3) {
  137. currentX += vertices[i];
  138. currentY += vertices[i + 1];
  139. currentZ += vertices[i + 2];
  140. }
  141. currentX /= 9;
  142. currentY /= 9;
  143. currentZ /= 9;
  144. float tx = x - currentX;
  145. float ty = y - currentY;
  146. float tz = z - currentZ;
  147. for (int i = 0; i < 9 * 2; i += 3) {
  148. vertices[i] += tx;
  149. vertices[i + 1] += ty;
  150. vertices[i + 2] += tz;
  151. }
  152. for (int i = 0; i < 9 * 2; i += 3) {
  153. vertices[i] += x;
  154. vertices[i + 1] += y;
  155. vertices[i + 2] += z;
  156. }
  157. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  158. glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
  159. glBindVertexArray(VAO);
  160. glDrawArrays(GL_TRIANGLES, 0, 6);
  161. //ImGui
  162. ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
  163. glfwSwapBuffers(window);
  164. glfwPollEvents();
  165. }
  166. glfwDestroyWindow(window);
  167. glfwTerminate();
  168. }

字符串
我不知道该怎么做。我想有一个确切的变量设置,而不是改变大小。我正在寻找一个解决方案,使用glm,我会把一切都在以后的类。

kmpatx3s

kmpatx3s1#

如果你有一个网格的顶点数据,并且想缩放对象而不迭代网格数据,那么一个解决方案就是让着色器为你做。
为此,我们只需要在顶点着色器中引入一个统一变量。
在应用变换之前,我们首先必须缩放顶点位置,例如。

  1. //vertex shader
  2. in vec3 aPos; //position coords
  3. uniform vec3 uScale; //scale factor
  4. uniform mat4 uProjection; //projection matrix
  5. int main()
  6. {
  7. gl_Position = uProjection * vec4(aPos * uScale, 1.0);
  8. }

字符串
通常,这是通过一个变换矩阵来完成的,该矩阵是投影、视图和模型矩阵(因此是mvp矩阵)的结果。

***投影:**透视、正交或截头体
*视图::例如lookAt,基于摄像机的位置、目标和向上矢量
模型:对象位置、 比例 * 和/或旋转

然后在顶点着色器中,有一个称为uMVP的统一体或两个统一体,一个用于投影和视图(修改频率较低,至少不是针对每个对象),一个模型矩阵对于每个对象可能不同(不同的位置,缩放和/或旋转)。
例如

  1. //vertex shader
  2. in vec3 aPos;
  3. uniform mat4 uProjection;
  4. uniform mat4 uView;
  5. uniform mat4 uModel;
  6. void main()
  7. {
  8. gl_Position = uProjection * uView * uModel * vec4(aPos, 1.0);
  9. }

展开查看全部

相关问题