【问题标题】:Using glVertexAttribPointer to draw model in OpenGL 2.0 with shaders使用 glVertexAttribPointer 在 OpenGL 2.0 中使用着色器绘制模型
【发布时间】:2013-01-04 01:18:19
【问题描述】:

我已经根据使用 OpenGLES 2.0 并且还使用着色器的默认模板松散地构建了面向对象的 iOS 应用程序,但我正在尝试加载一个我曾经调用它的模型:

#import "./sphere_model.h"
glVertexPointer(3, GL_FLOAT, 0, sphere_modelVerts);
glNormalPointer(GL_FLOAT, 0, sphere_modelNormals);
glDrawArrays(GL_TRIANGLES, 0, sphere_modelNumVerts);

我之所以使用上面的代码是因为我将我的.obj 文件转换为一个可以包含我需要定义的所有数组的文件(参见obj2opengl)。现在,我不是 100%,但我在某处读到 glVertexPointer 已被弃用,我正在努力让它在我的演示应用程序中工作。目前我正在绘制这个简单的立方体:

我从中获取 OpenGL 着色器代码的模板使用了glVertexAttribPointer,而使用的顶点数组略有不同,因为它在同一个数组中包含法线:

GLfloat gCubeVertexData[216] =
{
    // Data layout for each line below is:
    // positionX, positionY, positionZ,     normalX, normalY, normalZ,
    0.5f, -0.5f, -0.5f,        1.0f, 0.0f, 0.0f,
    0.5f, 0.5f, -0.5f,         1.0f, 0.0f, 0.0f,
    0.5f, -0.5f, 0.5f,         1.0f, 0.0f, 0.0f,
    0.5f, -0.5f, 0.5f,         1.0f, 0.0f, 0.0f,
    0.5f, 0.5f, -0.5f,          1.0f, 0.0f, 0.0f,
    0.5f, 0.5f, 0.5f,         1.0f, 0.0f, 0.0f,
    ....
};

我使用这段代码来绘制立方体(加载着色器文件后):

glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

glUseProgram(GetProgram());

glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

glDrawArrays(GL_TRIANGLES, 0, 36);

glDisableVertexAttribArray(GLKVertexAttribNormal);
glDisableVertexAttribArray(GLKVertexAttribPosition);

glBindVertexArrayOES(0);

现在我的问题是,使用 Open GLES 2.0,是否可以在仍使用着色器的同时使用 glVertexAttribPointer 而不是 glVertexPointer 加载由 obj2opengl 定义的顶点?

以下是其中一个模型文件的一些示例:

unsigned int sphere_modelNumVerts = 864;

float sphere_modelVerts [] = {
    -1.93077099209747e-18, 0.49025, 0.098,
    0.098, 0.49025, -1.78225014655151e-18,
    -1.93077099209747e-18, 0.5, -1.78225014655151e-18,
    -1.93077099209747e-18, 0.44725, 0.2235,
    0.11775, 0.4715, 0.11775,
    -1.93077099209747e-18, 0.49025, 0.098,
    ...
}

float sphere_modelNormals [] = {
    0, 0.980579906452681, 0.196119981290155,
    0.196119981290155, 0.980579906452681, 0,
    0, 1, 0,
    0, 0.894429190989163, 0.447209595499104,
    ...
}

float sphere_modelTexCoords [] = {
    0.75000, 0.0628300000000001,
    1, 0.0628300000000001,
    0.87500, 0,
    0.75000, 0.14758,
    ...
}

【问题讨论】:

    标签: ios opengl-es-2.0 vertex-shader vertex-array


    【解决方案1】:

    使用数组结构。绘制立方体的代码示例使用交错的顶点数据。它也被称为结构数组。这是recommended layout

    要支持您的数据格式,只需为每个属性(sphere_modelVerts、sphere_modelNormals ...)创建单独的缓冲区并定义不带偏移的属性。

    【讨论】:

    • 太棒了!我以前应该更多地关注那个文档!我加载了我的模型!但是只是检查一下,通过调用glBuffer(..., sphere_modelVerts,...) 然后glBuffer(..., sphere_modelNormals, ...) 并在没有偏移量的情况下调用我是否没有使用推荐的交错顶点数据?这是一件特别糟糕的事情吗?
    • @ing0,这可能会由于缺乏内存局部性而降低性能(文章中也提到了:)
    • 嗨,是的,我就是这么想的,只是想确认一下!我可能不得不开始寻找一种不同的方式来加载对象!无论如何,感谢您的帮助,现在可以正常工作了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-03
    • 2011-10-15
    • 1970-01-01
    相关资源
    最近更新 更多