【发布时间】:2018-07-12 11:54:04
【问题描述】:
我的任务是展示几张图片。我将它实现为一个类来创建几个实例。每个实例代表一张图片。它编译着色器,设置两个三角形并在构造函数中加载图片数据。主程序创建实例,然后循环切换prigramid并为每个实例调用render()方法。
while(true)
for (uint g = 0; g < pictures.size(); g++){
glUseProgram(pictures[g]->ProgramId);
pictures[g]->render();
}
它运作良好并显示图片,但我不喜欢它。它可以做得更好。
这是类的部分代码
Picture::Picture(picPosition* pPosition, const char * fileName)
:BasePicture(pPosition)
{
pos = glGetAttribLocation(ProgramId, "position");
uv = glGetAttribLocation(ProgramId, "texture_vert");
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
int n;
textureData = stbi_load(fileName, &picWidth, &picHeight, &n, STBI_rgb_alpha);
TextureID = glGetUniformLocation(ProgramId, "myTextureSampler");
glBindTexture(GL_TEXTURE_2D, TextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glActiveTexture(GL_TEXTURE0);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
//calculating the vertex matrix using MVP calculated in parent class
for (int i = 0; i < 6; i++)
ModeledVerts.push_back(MVP * verts[i]);
v = glm::value_ptr(ModeledVerts[0]);
}
Picture::~Picture()
{
stbi_image_free(textureData);
glDeleteBuffers(1, &vbo);
glDeleteBuffers(1, &uvbuffer);
}
void Picture::render()
{
glBufferData(GL_ARRAY_BUFFER, 96, v, GL_STATIC_DRAW);
glVertexAttribPointer(pos, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*) 0);
glEnableVertexAttribArray(pos);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesUV), verticesUV, GL_STATIC_DRAW);
glVertexAttribPointer(uv, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*) 0);
glEnableVertexAttribArray(uv);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
我在代码上玩了很多,以使 render() 函数尽可能轻,但我不能让它像现在这样轻。
最大的问题是每次都发送textureData(glTexImage2D)。数据永远不会改变。我试图将其移至构造函数,但在这种情况下,所有图片对象都显示最新加载的相同图片。看起来一个实例覆盖了之前上传的纹理数据。我正在寻找一种方法来在构造函数中加载一次图片数据,而不是每次渲染时。看起来 OpenGL API 中有一些东西,但我还不知道。
另一个改进可能是从 render() 中获取顶点数据。该数据永远不会改变。但这并不像 render() 中的 glTexImage2D 调用那么重要。
您能否指点我使用 OpenGL API 来分离着色器的数据?或者告诉我我做错了什么......
【问题讨论】:
-
glTexImage2D 覆盖当前绑定的纹理。您应该尝试制作不同的纹理来保存每个图像,然后您可以依次绑定每个图像并进行渲染。查找 glGenTextures 和 glBindTexture。
标签: c++ optimization opengl-es textures