具有不同纹理uv的矩形实例
Rectangle instances with different texture UVs
我是现代OpenGL VBO/VAO的新手,我与一件事作斗争:我基于本教程编写了一个RectangleAsset,但我不确定如何将纹理uv的信息移动到RactangleAssetInstance(我的矩形可以有不同的纹理)。
我是否必须为它创建新的VAO,或者我可以通过其他方式传递uv ?或者为uv添加第二个VBO ?最重要的是:解决这个问题的最佳实践是什么?
struct RectangleAsset {
GLuint VBO;
GLuint VAO;
};
struct RectangleAssetInstance { //this is actually more complex class in my code
RectangleAsset rect; //but tried to extract the most imporatant code
glm::mat4 transform;
Texture * texture;
void UpdateTransform(int,int,int,int);
private:
int x,y,width,height;
};
和加载RectangleAsset的函数:
void GUIRenderer::init()
{
image = new Program ("vs.glsl", "fs.glsl");
glGenVertexArrays(1, &rect.VAO);
glBindVertexArray(rect.VAO);
glGenBuffers(1, &rect.VBO);
glBindBuffer(GL_ARRAY_BUFFER, rect.VAO);
GLfloat vertexData[] = {
// X Y Z U V
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
};
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(image->attrib("vert"));
glVertexAttribPointer(image->attrib("vert"), 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), NULL);
glEnableVertexAttribArray(image->attrib("vertTexCoord"));
glVertexAttribPointer(image->attrib("vertTexCoord"), 2, GL_FLOAT, GL_TRUE, 5*sizeof(GLfloat), (const GLvoid*)(3 * sizeof(GLfloat)));
glBindVertexArray(0);
}
注意:我计划只在一个地方使用RectangleAssetInstances,在一个std::vector中用于GUI渲染(非静态GUI)。将所有矩形合并到一个VBO和VAO中(并在添加/删除UIElement时重新创建它)可能是个好主意吗?
任何关于学习OpenGL最佳实践的建议都是受欢迎的。
vao存储输入数据的格式和该输入数据的来源位置。这实际上是两个独立的概念。如果你想改变uv来自哪里,你必须再次调用glVertexAttribPointer。这个调用看起来像glVertexAttribPointer(uvLoc, GL_FLOAT, false, sizeof(float) * 5, (const GLvoid*)(sizeof(float) * 3))
注意,这不会改变你的位置信息来自的VBO。
现在你提到你想这样做,因为你的矩形实例可能有不同的纹理。你不需要改变紫外线来实现这一点。在一般位置,uv和法线都是网格的一部分,你只需要一个副本。要改变纹理,只需调用glActiveTexture(GL_TEXTURE0 + i)
,然后调用glBindTexture(GL_TEXTURE_2D, tex)
,然后在着色器中设置采样器均匀,使用正确的图像单元glUniform1i(samplerLoc, i)
还有ARB_vertex_attrib_binding扩展,它在OpenGL 4.3中成为核心。这允许您将属性布局与数据位置分开。OpenGL wiki上的文章提供了如何做到这一点的信息,但同样,使用相同的uv为给定网格编写所有纹理可能更好。
关于您关于将所有内容合并为一个VAO和VBO的问题:如果您只想要矩形,那么这是不必要的,因为您可以获得任何类型的矩形,您希望使用具有非均匀缩放分量的仿射变换。因此,您总共只需要一个VAO和一个VBO,并且不需要合并任何东西。
- 从C++实例化QML
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 无法创建抽象类的实例
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 我收到以下错误:抛出'std::bad_alloc'实例后终止调用
- 建议在运行时将带有类实例的列表从c++导入qml
- 约束和显式模板实例化
- 通过实例理解std::move及其目的
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 有没有一种"cleaner"的方法可以在指向基的指针向量中找到派生类的第一个实例?
- 正在生成未知类实例
- 从DLL中删除类的实例
- 在std::vector上存储带有模板的类实例
- 具有不同纹理uv的矩形实例