我使用C++和OpenGL。但我需要对象缩放到一定的比例。对于一个游戏引擎。我的目标只是为了比例设置而不是改变。
#define GLFW_INCLUDE_NONE
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <GLFW/glfw3.h>
#include <Glad/glad.h>
#include "vendor/ImGui/imgui.h"
#include "vendor/ImGui/backends/imgui_impl_glfw.h"
#include "vendor/ImGui/backends/imgui_impl_opengl3.h"
#include <stdio.h>
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
void error_callback(int error, const char* description)
{
fprintf(stderr, "Error: %s\n", description);
}
const char* vertexShaderSource = "#version 330 core\n"
"layout(location = 0) in vec3 aPos;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{\n"
" gl_Position = projection * vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char* fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"uniform vec2 wsize;\n"
"void main()\n"
"{\n"
" vec2 position = gl_FragCoord.xy;\n"
" FragColor = vec4(position.x/wsize.x, position.x/position.y/wsize.x,position.y/wsize.y, 1.0f);\n"
"}\n\0";
float aspectRatio;
glm::mat4 projection;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
aspectRatio = (float)width / (float)height;
projection = glm::ortho(-aspectRatio, aspectRatio, -1.0f, 1.0f, -1.0f, 1.0f);
}
int main()
{
if (!glfwInit())
{
// Initialization failed
}
glfwSetErrorCallback(error_callback);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(640, 480, "GL YA!", NULL, NULL);
if (!window)
{
// Window or context creation failed
}
glfwMakeContextCurrent(window);
gladLoadGL();
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
float vertices[9 * 2] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
};
glfwSwapInterval(1);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
io.ConfigDockingWithShift = false;
ImGui::StyleColorsDark();
const char* glsl_version = "#version 100";
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init(glsl_version);
float x = 0;
float y = 0;
float z = 0;
while (!glfwWindowShouldClose(window))
{
int width, height;
glfwGetFramebufferSize(window, &width, &height);
framebuffer_size_callback(window, width, height);
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
ImGui::Begin("Hello OpenGL!");
ImGui::InputFloat("X", &x);
ImGui::InputFloat("Y", &y);
ImGui::InputFloat("Z", &z);
ImGui::End();
ImGui::Render();
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT);
//Square
glUseProgram(shaderProgram);
GLint wsize = glGetUniformLocation(shaderProgram, "wsize");
glUniform2f(wsize, width, height);
/*
glm::mat4 transform = glm::mat4(1.0f); // Start with an identity matrix
transform = glm::translate(transform, glm::vec3(x, y, z)); // Move the triangle along the x and y axes
for (int i = 0; i < 9 * 2; i += 3) {
glm::vec4 vertex = transform * glm::vec4(vertices[i], vertices[i + 1], vertices[i + 2], 1.0f);
vertices[i] = vertex.x;
vertices[i + 1] = vertex.y;
vertices[i + 2] = vertex.z;
}
*/
float currentX = 0.0f;
float currentY = 0.0f;
float currentZ = 0.0f;
for (int i = 0; i < 9 * 2; i += 3) {
currentX += vertices[i];
currentY += vertices[i + 1];
currentZ += vertices[i + 2];
}
currentX /= 9;
currentY /= 9;
currentZ /= 9;
float tx = x - currentX;
float ty = y - currentY;
float tz = z - currentZ;
for (int i = 0; i < 9 * 2; i += 3) {
vertices[i] += tx;
vertices[i + 1] += ty;
vertices[i + 2] += tz;
}
for (int i = 0; i < 9 * 2; i += 3) {
vertices[i] += x;
vertices[i + 1] += y;
vertices[i + 2] += z;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
//ImGui
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
}
字符串
我不知道该怎么做。我想有一个确切的变量设置,而不是改变大小。我正在寻找一个解决方案,使用glm,我会把一切都在以后的类。
1条答案
按热度按时间kmpatx3s1#
如果你有一个网格的顶点数据,并且想缩放对象而不迭代网格数据,那么一个解决方案就是让着色器为你做。
为此,我们只需要在顶点着色器中引入一个统一变量。
在应用变换之前,我们首先必须缩放顶点位置,例如。
字符串
通常,这是通过一个变换矩阵来完成的,该矩阵是投影、视图和模型矩阵(因此是mvp矩阵)的结果。
***投影:**透视、正交或截头体
*视图::例如lookAt,基于摄像机的位置、目标和向上矢量
模型:对象位置、 比例 * 和/或旋转
然后在顶点着色器中,有一个称为
uMVP
的统一体或两个统一体,一个用于投影和视图(修改频率较低,至少不是针对每个对象),一个模型矩阵对于每个对象可能不同(不同的位置,缩放和/或旋转)。例如
型