【发布时间】:2020-10-28 22:00:32
【问题描述】:
当我使用 glm::scale 更新顶点着色器中的模型矩阵时,无论我做什么,它总是会缩小它。有人知道我在做什么错吗?图片有时也会上下翻转。
尽管代码不同,但 key == 'w' 和 key == 's' 做的事情完全相同,目标是按 W 使模型变大,按 S 使模型变小。但现在它两按都会变小。
用于根据按键进行缩放的相关代码为:
if (key == 'w') {
model = glm::scale(model, glm::vec3(0.5, 0.5, 0.5));
int loc = glGetUniformLocation(prog, "model");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model));
}
if (key == 's') {
model = glm::scale(model, glm::vec3(-0.5, -0.5, -0.5));
int loc = glGetUniformLocation(prog, "model");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model));
}
整个代码是:
#include <Windows.h>
#include <GL\glew.h>
#include <GL\freeglut.h>
#include <iostream>
#include <SOIL.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "OBJ.h"
const char* vs = "#version 330 core\n"
"layout (location = 0) in vec3 pos;\n"
"layout (location = 1) in vec2 texpos;\n"
"out vec2 texCoords;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{\n"
"gl_Position = projection * view * model * vec4(pos, 1);\n"
"texCoords = texpos;\n"
"}\0";
const char* fs = "#version 330 core\n"
"in vec2 texCoords;\n"
"out vec4 fragColor;\n"
"uniform sampler2D tex;\n"
"void main()\n"
"{\n"
"fragColor = texture(tex, texCoords);"
"}\0";
float verts[] = {
0, 1, 0, 0.5, 1,
-1, -1, 0, 0, 0,
1, -1, 0, 1, 0
};
unsigned short indices[] = {
0, 1, 2
};
unsigned int vao, vbo, ebo, prog, vert, frag, texid;
glm::mat4 model, view, projection;
void changeViewPort(int w, int h)
{
glViewport(0, 0, w, h);
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(vao);
glBindTexture(GL_TEXTURE_2D, texid);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);
glutSwapBuffers();
}
void initGL() {
//Context stuff
glViewport(0, 0, 800, 600);
glClearColor(0.5, 0.5, 0.5, 1);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//Shader stuff
int success;
prog = glCreateProgram();
vert = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vert, 1, &vs, NULL);
glCompileShader(vert);
glGetShaderiv(vert, GL_COMPILE_STATUS, &success);
std::cout << "Vertex shader " << (success ? "compiled" : "not compiled") << std::endl;
frag = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(frag, 1, &fs, NULL);
glCompileShader(frag);
glGetShaderiv(frag, GL_COMPILE_STATUS, &success);
std::cout << "Fragment shader " << (success ? "compiled" : "not compiled") << std::endl;
glAttachShader(prog, vert);
glAttachShader(prog, frag);
glLinkProgram(prog);
glUseProgram(prog);
glGetShaderiv(prog, GL_LINK_STATUS, &success);
std::cout << "Program " << (success ? "linked" : "not linked") << std::endl;
glDeleteShader(vert);
glDeleteShader(frag);
//Vertex stuff
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), &verts, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GL_FLOAT), 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GL_FLOAT), (void*)(3 * sizeof(GL_FLOAT)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
//Texture stuff
int width, height;
unsigned char* texData = SOIL_load_image("brick.png", &width, &height, NULL, SOIL_LOAD_RGBA);
glGenTextures(1, &texid);
glBindTexture(GL_TEXTURE_2D, texid);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
if (texData) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
glGenerateMipmap(GL_TEXTURE_2D);
} else {
std::cout << "Texture not loaded." << std::endl;
}
glBindTexture(GL_TEXTURE_2D, 0);
SOIL_free_image_data(texData);
//Matrix stuff
//Model matrix
model = glm::mat4(1.0f);
model = glm::scale(model, glm::vec3(0.5, 0.5, 0.5));
int modelMatrix = glGetUniformLocation(prog, "model");
glUniformMatrix4fv(modelMatrix, 1, GL_FALSE, glm::value_ptr(model));
//View matrix
view = glm::mat4(1.0f);
view = glm::translate(view, glm::vec3(0, 0, -3));
int viewMatrix = glGetUniformLocation(prog, "view");
glUniformMatrix4fv(viewMatrix, 1, GL_FALSE, glm::value_ptr(view));
//Projection matrix, something is messing up here
projection = glm::mat4(1.0f);
projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);
int projectionMatrix = glGetUniformLocation(prog, "projection");
glUniformMatrix4fv(projectionMatrix, 1, GL_FALSE, glm::value_ptr(projection));
}
void input(unsigned char key, int x, int y) {
if (key == 'a') {
model = glm::translate(model, glm::vec3(-0.5, 0, 0));
int loc = glGetUniformLocation(prog, "model");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model));
}
if (key == 'd') {
model = glm::translate(model, glm::vec3(0.5, 0, 0));
int loc = glGetUniformLocation(prog, "model");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model));
}
if (key == 'w') {
model = glm::scale(model, glm::vec3(0.5, 0.5, 0.5));
int loc = glGetUniformLocation(prog, "model");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model));
}
if (key == 's') {
model = glm::scale(model, glm::vec3(-0.5, -0.5, -0.5));
int loc = glGetUniformLocation(prog, "model");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model));
}
if (key == 'q') {
model = glm::rotate(model, glm::radians(45.0f), glm::vec3(0, 0, 1));
int loc = glGetUniformLocation(prog, "model");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model));
}
if (key == 'e') {
model = glm::rotate(model, glm::radians(-45.0f), glm::vec3(0, 0, 1));
int loc = glGetUniformLocation(prog, "model");
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(model));
}
glutPostRedisplay();
}
int main(int argc, char* argv[]) {
// Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("OBJ Viewer");
glutReshapeFunc(changeViewPort);
glutDisplayFunc(render);
glutKeyboardFunc(input);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW error");
return 1;
}
initGL();
glutMainLoop();
return 0;
}
【问题讨论】:
-
x*0.5和x*-0.5都是按比例缩小的,不是吗? -
否,因为如果 x 为 1,则 1 * 0.5 = 0.5 和 1 * -0.5 = -0.5 所以前者应该按比例放大 0.5,而后者应该按比例缩小 0.5
-
不,那样不行,我问你
(x*0.5)*0.5是什么,(x*-0.5)*-0.5是什么 -
哦,我明白你在说什么。但是如何在我的代码中解决这个问题?我应该在我的代码中进行哪些更改以使其放大半个坐标并正确缩小半个坐标?
-
如果你想扩大规模,那么扩大规模 > 1。顺便说一句。使用负值缩放可能会导致镜像。
标签: c++ opengl matrix glm-math