gpt4 book ai didi

opengl-es - 在 OpenGL ES 2.0 中独立变换对象

转载 作者:行者123 更新时间:2023-12-02 23:11:28 24 4
gpt4 key购买 nike

我见过的所有教程始终使用单个对象,例如三角形或立方体。但我不清楚如何独立操作单独的对象。我看过一些引用固定功能管道并使用pushmatrix和popmatrix的教程,但是对于可编程管道,这些功能都消失了。下面是一个 init 函数和一个绘制函数,它们在屏幕上绘制一个三角形并绕 Z 轴旋转。有人可以向我展示代码,甚至是添加第二个三角形并独立于其他三角形旋转它的伪代码吗?是说围绕不同的轴还是相反的方向?

它们在这里:

int Init(ESContext* esContext)
{
UserData* userData = (UserData *)esContext->userData;
const char *vShaderStr =
"attribute vec4 vPosition; \n"
"uniform mat4 MVPMatrix;"
"void main() \n"
"{ \n"
" gl_Position = MVPMatrix * vPosition;\n"
"} \n";

const char *fShaderStr =
"precision mediump float; \n"
"void main() \n"
"{ \n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n"
"} \n";

GLuint vertexShader;
GLuint fragmentShader;
GLuint programObject;
GLint linked;
GLfloat ratio = 320.0f/240.0f;

vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr);
fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr);

programObject = glCreateProgram();

if (programObject == 0)
return 0;

glAttachShader(programObject, vertexShader);
glAttachShader(programObject, fragmentShader);

glBindAttribLocation(programObject, 0, "vPosition");
glLinkProgram(programObject);
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &linked);

if (!linked)
{
GLint infoLen = 0;
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);

if (infoLen > 1)
{
char* infoLog = (char *)malloc(sizeof(char) * infoLen);
glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);

free(infoLog);
}

glDeleteProgram(programObject);
return FALSE;
}

userData->programObject = programObject;

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

glViewport(0, 0, esContext->width, esContext->height);
glClear(GL_COLOR_BUFFER_BIT);


glUseProgram(userData->programObject);

userData->angle = 0.0f;
userData->start = time(NULL);
userData->ProjMatrix = PVRTMat4::Perspective(ratio*2.0f, 2.0f, 3.0f, 7.0f, PVRTMat4::eClipspace::OGL, false, false);
userData->ViewMatrix = PVRTMat4::LookAtLH(PVRTVec3(0.0f, 0.0f, -3.0f), PVRTVec3(0.0f, 0.0f, 0.0f), PVRTVec3(0.0f, 1.0f, 0.0f));
return TRUE;
}



void Draw(ESContext *esContext)
{
GLfloat vVertices[] = {0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f};

GLint MVPHandle;
double timelapse;

PVRTMat4 MVPMatrix = PVRTMat4::Identity();
UserData* userData = (UserData *)esContext->userData;

timelapse = difftime(time(NULL), userData->start) * 1000;
if(timelapse > 16.0f) //Maintain approx 60FPS
{
if (userData->angle > 360.0f)
{
userData->angle = 0.0f;
}
else
{
userData->angle += 0.1f;
}
}

userData->ModelMatrix = PVRTMat4::RotationZ(userData->angle);

MVPMatrix = userData->ViewMatrix * userData->ModelMatrix;
MVPMatrix = userData->ProjMatrix * MVPMatrix;

MVPHandle = glGetUniformLocation(userData->programObject, "MVPMatrix");
glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr());

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
glEnableVertexAttribArray(0);

glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
}

最佳答案

绘制第一个三角形后,使用新的所需旋转/位置生成一个新的 MVP 矩阵,上传它,然后第二次绘制三角形。您可以在场景中多次更换制服。

这与push和pop所做的类似,它们只是在绘制给定对象之前更改事件矩阵。

示例伪代码:

MMatrix = identity;
MVPMatrix = VPMatrix * MMatrix;
glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr());
glDrawArrays(GL_TRIANGLES, 0, 3); //draw triangle at 0,0,0

MMatrix.translate(1,0,0);
MVPMatrix = VPMatrix * MMatrix;
glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr());
glDrawArrays(GL_TRIANGLES, 0, 3); //draw triangle at 1,0,0

MMatrix.translate(1,0,0);
MVPMatrix = VPMatrix * MMatrix;
glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr());
glDrawArrays(GL_TRIANGLES, 0, 3); //draw triangle at 2,0,0

..repeat for as many objects as you want..

这将留下三个三角形,分别位于 (0,0,0)、(1,0,0) 和 (2,0,0)。

关于opengl-es - 在 OpenGL ES 2.0 中独立变换对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10112996/

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