我正在使用/目标OpenGL 4.20,GSLSL 4.20,核心.使用C.
我正在使用OpenGL探索图形,并决定制作基于图块的游戏.我正在想要实际绘制一堆瓷砖,我正在尝试使用glDrawElements绘制单个三角形.
相关代码:
const float vertexPositions[] = {
-1.0f, -0.8f, //0
-0.8f, -0.8f, //1
-0.6f, -0.8f, //2
-0.4f, -0.8f, //3
-0.2f, -0.8f, //4
0.0f, -0.8f, //5
-1.0f, -1.0f, //6
-0.8f, -1.0f, //7
-0.6f, -1.0f, //8
-0.4f, -1.0f, //9
-0.2f, -1.0f, //10
0.0f, -1.0f, //11
//The following are the texture coordinates.
0.00f, 1.00f,
1.00f, 1.00f,
0.00f, 1.00f,
1.00f, 1.00f,
0.00f, 1.00f,
1.00f, 1.00f,
0.00f, 0.00f,
1.00f, 0.00f,
0.00f, 0.00f,
1.00f, 0.00f,
0.00f, 0.00f,
1.00f, 0.00f,
};
const GLubyte indices[] …Run Code Online (Sandbox Code Playgroud) 我有一个顶点着色器,它接受以下属性:
a_posCoord:顶点位置a_texCoord:纹理坐标(传递给片段着色器)a_alpha:透明度因子(传递给片段着色器)我正在渲染的对象都是"广告牌"(一对直角三角形来制作一个矩形).
我正在使用单个调用来glDrawArrays渲染许多广告牌,每个广告牌都可能具有唯一的alpha值.单个广告牌有6个顶点.这里有一些伪代码来说明我如何为单个广告牌组织顶点属性缓冲区:
vertexAttributes = [
px1,py1,pz1, // vertex 1: a_posCoord
tx1,ty1, // vertex 1: a_texCoord
alpha, // vertex 1: a_alpha
px2,py2,pz2, // vertex 2: a_posCoord
tx2,ty2, // vertex 2: a_texCoord
alpha, // vertex 2: a_alpha
px3,py3,pz3, // vertex 3: a_posCoord
tx3,ty3, // vertex 3: a_texCoord
alpha, // vertex 3: a_alpha
px4,py4,pz4, // vertex 4: a_posCoord
tx4,ty4, // vertex 4: a_texCoord
alpha, // vertex 4: a_alpha
px5,py5,pz5, // vertex 5: …Run Code Online (Sandbox Code Playgroud) 我知道glVertexAttribDivisor可以用来修改通用顶点属性在实例渲染过程中前进的速率,但我想知道是否有任何方法可以在没有实例化的情况下以特定速率推进属性.
这是我的意思的一个例子:
假设您正在定义构成一系列线的顶点位置列表,并且您希望将每条线与一个ID相关联.因此,您创建两个vbos,每个vbos包含与其中一个属性相关的数据(所有顶点位置或所有顶点ID).传统上,这意味着每个vbo必须是行数X 2的大小(在元素中)(因为每个点包含两行).这当然意味着我为一行中的每个点复制相同的ID值.
我想要做的是指定ID为顶点位置缓冲区前进的每2个元素提前1个元素.我知道这要求我的顶点位置缓冲区首先被声明(所以我可以引用它来告诉OpenGL多长时间推进ID缓冲区),但它似乎仍然可能.但是,我在OpenGL规范中找不到允许这种操作的任何功能.
我想知道在 OpenGL 中(通过扩展或其他方式)是否有可能有一个由glVertexAttribPointer类型函数指定的属性数组,它为每个基元(或 N 个顶点)前进一个而不是每个顶点一个?
例如,如果我有一个三角形数组,它们目前具有纯色,我必须为每个顶点重复相同的颜色数据,我想要的是沿着这些线的东西:
struct pos {
uint8_t x, y;
} positions[NUM_VERTICES];
struct col {
uint8_t r, g, b;
} colors[NUM_VERTICES / 3];
Run Code Online (Sandbox Code Playgroud)
其中的一个元件colors阵列被用于每3个连续的重复使用positions时两个阵列被提交给OpenGL的与元件glVertexAttribPointer和呈示具有单个glDrawArrays(GL_TRIANGLES, ...);
我找到了ARB_instanced_arrays扩展,它提供了glVertexAttribDivisorARB起初看起来很有希望的功能,但我认为它不像我描述的那样工作。
为什么OpenGL不支持顶点属性的多个索引缓冲区?
对我而言似乎非常有用,因为您可以重用属性,并且您可以更好地控制几何体的渲染.
有没有理由为什么所有属性数组都必须使用相同的索引,或者在不久的将来可以使用此功能?
我正在尝试为OpenGL项目创建一个Wavefront(.obj)文件加载器.我正在使用的方法是逐行进行并分离矢量(std :: vectors)中的顶点位置,纹理位置和正常位置,并且我将它们的索引(顶点,纹理和法线索引)存储在三个单独的中向量(来自文件的'f'行,每个面).
我无法根据纹理索引对完整的纹理坐标进行排序.我能够将顶点渲染到正确的位置,因为我的'loader'类需要索引,但我无法弄清楚如何以任何方式对纹理坐标进行排序,因此纹理在某些三角形上看起来像是一个偏移结果.
偏移纹理的多维数据集的图像:

纹理(.png)的图像,它应该如何在每张脸上:

编辑:这是.obj文件和.mtl文件的链接. Google云端硬盘.
这是我的OBJLoader.cpp文件:
rawObj.open(filePath); // Open file
while (!rawObj.eof()) {
getline(rawObj, line); // Read line
// Read values from each line
// starting with a 'v' for
// the vertex positions with
// a custom function (gets the word in a line
// at position i)
if (strWord(line, 1) == "v") {
for (int i = 2; i <= 4; i++) {
std::string temp;
temp = strWord(line, i);
vertexStrings.push_back(temp);
}
// Same for texture …Run Code Online (Sandbox Code Playgroud) 我现在的情况是想使用VAO/VBO来回收相同的顶点并使用索引来加速渲染。
一切都很好,除了我的纹理模型使用 UV 坐标,并且对于相同的顶点(大约 >80%),我最终可能会根据我期望渲染的三角形获得不同的 UV 坐标(事实上,我正在使用md2 模型和纹理)。
对于老式的即时模式来说,这种渲染方式非常不错。现在,解决这个问题并通过 VAO/VBO 渲染的最佳方法是什么?
我想到的是分解三角形并创建具有重复顶点的非常大的 VBO,以便我可以将正确的 UV 坐标链接到每个“相同”。
我不得不说我不喜欢这个...有什么想法吗?
诗。对于不了解格式的人:如果您想使用纹理映射,我相信您必须使用基于要渲染的三角形的自定义 UV 坐标。否则纹理颜色都乱了!
我发现渲染数据时很难理解顶点和纹理坐标之间的相关性。我有一个使用从 obj 解析的 drawElements 表单数据绘制的立方体。我在某个接近于使用简单平面的地方得到了纹理,其中位置和纹理坐标的顶点数,但是一旦我使用更复杂的模型,甚至只是更复杂的 uv 展开,我最终会得到纹理全部错误。
从我读到的内容来看,没有看到像使用顶点位置一样使用纹理坐标索引的方法,这是不幸的,因为 obj 具有该信息。我让它接近工作的方法是通过 obj.txt 中的索引数据构建一个纹理坐标数组。但由于顶点和纹理坐标数组的长度不同(例如,在立方体的 obj 中,有 8 个顶点和最多 36 个纹理坐标,具体取决于网格是否展开),因此它们不相关。
使用drawElements 并将顶点映射到正确的纹理坐标的正确工作流程是什么?