gpt4 book ai didi

opengl - 对对象应用变换

转载 作者:行者123 更新时间:2023-12-05 01:20:14 25 4
gpt4 key购买 nike

我正在创建基本的 OpenGL 场景,但在操作我的对象时遇到了问题。每个都有不同的变换矩阵,还有整个场景的模型 View /平移/缩放矩阵。

在从顶点着色器执行计算之前,如何将此数据绑定(bind)到我的对象?我读过有关 gl(Push|Pop)Matrix() 的信息,但根据我的理解,这些函数已被弃用。

我的一些代码。来自顶点着色器的位置:

gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;

和显示对象的C++函数:

// Clear etc...

mat4 lookAt = glm::lookAt();
glLoadMatrixf(&lookAt[0][0]);
mat4 combined = lookAt * (mat4) sceneTranslation * (mat4) sceneScale;
glLoadMatrixf(&combined[0][0]);

mat4 objectTransform(1.0);
// Transformations...

// No idea if it works, but objects are affected by camera position but not individually scaled, moved etc.
GLuint gl_ModelViewMatrix = glGetUniformLocation(shaderprogram, "gl_ModelViewMatrix");
glUniformMatrix4fv(gl_ModelViewMatrix, 1, GL_FALSE, &objectTransform[0][0]);

// For example
glutSolidCube(1.0);

glutSwapBuffers();

最佳答案

好吧,您不必使用 glLoadMatrix 和其他内置矩阵函数,因为它可能比处理您自己的矩阵更困难。

一个没有控制它的简单相机示例,它是一个静态相机:

glm::mat4x4 view_matrix = glm::lookAt(
cameraPosition,
cameraPosition+directionVector, //or the focus point the camera is pointing to
upVector);

它返回一个 4x4 矩阵,这是 View 矩阵。

glm::mat4x4 projection_matrix = 
glm::perspective(60.0f, float(screenWidth)/float(screenHeight), 1.0f, 1000.0f);

这是投影矩阵

现在你有了 View 和投影矩阵,你可以将它发送到着色器:

gShader->bindShader();
gShader->sendUniform4x4("view_matrix",glm::value_ptr(view_matrix));
gShader->sendUniform4x4("projection_matrix",glm::value_ptr(projection_matrix));

绑定(bind)着色器是简单的 glUseProgram(shaderprog);统一程序是

void sendUniform4x4(const string& name, const float* matrix, bool transpose=false)
{
GLuint location = getUniformLocation(name);
glUniformMatrix4fv(location, 1, transpose, matrix);
}

您的模型矩阵对于您的每个对象都是独立的:

glm::mat4x4 model_matrix= glm::mat4(1); //this is the identity matrix, so its static
model_matrix= glm::rotate(model_matrix,
rotationdegree,
vec3(axis)); //same as opengl function.

这创建了一个模型矩阵,您也可以将它发送到您的着色器

 gShader->bindShader();
gShader->sendUniform4x4("model_matrix",glm::value_ptr(model_matrix));

glm::value_ptr(...) 创建矩阵的二维数组。

在你的着色器代码中不要使用 glModelViewMatrix 和 gl_ProjectionMatrix,矩阵通过制服发送。

uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;

void main(){
gl_Position = projection_matrix*view_matrix*model_matrix*gl_Vertex;
//i wrote gl_Vertex because of the glutSolidTeapot.
}

我从来没有使用过这个内置的网格函数,所以我不知道它是如何工作的,假设它使用 gl_Vertex 立即模式将顶点发送到着色器。如果您创建自己的网格,请使用 VBO vertexattribpointer 和 drawarrays/elements。

在发送制服之前不要忘记绑定(bind)着色器。

所以用一个完整的例子:

glm::mat4x4 view_matrix = glm::lookAt(2,4,2,-1,-1,-1,0,1,0);

glm::mat4x4 projection_matrix =
glm::perspective(60.0f, float(screenWidth)/float(screenHeight), 1.0f, 10.0f);

glm::mat4x4 model_matrix= glm::mat4(1); //this remains unchanged
glm::mat4x4 teapot_model_matrix= glm::rotate(model_matrix, //this is the teapots model matrix, apply transformations to this
45,
glm::vec3(1,1,1));
teapot_model_matrix = glm::scale(teapot_model_matrix,vec3(2,2,2);


gShader->bindShader();
gShader->sendUniform4x4("model_matrix",glm::value_ptr(model_matrix));
gShader->sendUniform4x4("view_matrix",glm::value_ptr(view_matrix));
gShader->sendUniform4x4("projection_matrix",glm::value_ptr(projection_matrix));

glutSolidCube(0.0); //i don't know what the (0.0) stands for :/
glutSwapBuffers();

/////////////////////////////////

在你的着色器中:

uniform mat4 projection_matrix; //these are the matrixes you've sent
uniform mat4 view_matrix;
uniform mat4 model_matrix;

void main(){
gl_Position = projection_matrix*view_matrix*model_matrix*vec4(gl_Vertex.xyz,1);
}

现在你应该有一个位于 2,4,2 的相机,聚焦在 -1,-1,-1,并且向上矢量指向上方:)

茶壶围绕 (1,1,1) 向量旋转 45 度,并在每个方向缩放 2。

改变模型矩阵后,将它发送到着色器,所以如果你有更多的对象要渲染如果您想对每个网格应用不同的变换,请在每个之后发送它。伪代码如下所示:

camera.lookat(camerapostion,focuspoint,updirection); //sets the view
camera.project(fov,aspect ratio,near plane, far plane) //and projection matrix
camera.sendviewmatrixtoshader;
camera.sendprojectionmatrixtoshader;

obj1.rotate(45 degrees, 1,1,1); //these functions should transform the model matrix of the object. Make sure each one has its own.
obj1.sendmodelmatrixtoshader;
obj2.scale(2,1,1);
obj2.sendmodelmatrixtoshader;

如果它不起作用,请尝试使用 vertexBuffer 和您自己创建的简单三角形或立方体。

关于opengl - 对对象应用变换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19740892/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com