OpenGL ES glDrawElements 函数

ChatGPT 3.5 国内中文镜像站免费使用啦

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录  >> OpenGL ES 特效

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录  >> OpenGL ES 转场

零基础 OpenGL ES 学习路线推荐 :  OpenGL ES 学习目录 >> OpenGL ES 函数

零基础 OpenGL ES 学习路线推荐 :  OpenGL ES 学习目录 >> OpenGL ES GPUImage 使用

零基础 OpenGL ES 学习路线推荐 :  OpenGL ES 学习目录 >> OpenGL ES GLSL 编程


一.glDrawElements 函数简介

glDrawElements 函数是 OpenGL ES 中用于绘制三角形和其他几何图形的函数之一,它使用一个索引数组来绘制三角形和其他几何图形,以下是 glDrawElements 函数的参数和返回值的解释:



/*******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:OpenGL ES glDrawElements 函数
//@Time:2023/03/11 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/*******************************************************************************************/

/*
*描述:用于根据指定的顶点数组绘制图形
*
*参数讲解:
* mode:指定渲染模式,接受的参数有:GL_TRIANGLES(三角形)、GL_TRIANGLE_STRIP(三角形带)、GL_TRIANGLE_FAN(三角形扇形)等。
* count:表示要从索引缓冲区中读取多少个元素来进行绘制(指定绘制的顶点个数)。
* type:表示索引缓冲区中元素的数据类型,例如GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT或者GL_UNSIGNED_INT。
* indices:表示指向存储在显存中的索引缓冲区对象(IBO)数据起始位置的指针
*
*返回值:无
*/


void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);

在使用 glDrawElements 函数时,需要先创建并绑定一个索引缓冲区对象,将索引数组的数据存储在该缓冲区对象中,然后使用 glVertexAttribPointer 函数指定顶点属性,使用 glEnableVertexAttribArray 函数启用顶点属性,最后调用 glDrawElements 函数进行绘制。需要注意的是,在使用 glDrawElements 函数时,索引数组中的值表示的是顶点数组中的位置信息,而不是实际的顶点值。


二.glDrawElements 函数注意事项

1.索引缓冲区对象需要创建并绑定

使用 glDrawElements 函数时,需要先创建一个索引缓冲区对象,并使用 glBindBuffer 函数将其绑定到GL_ELEMENT_ARRAY_BUFFER 目标上。然后使用 glBufferData 函数将索引数组的数据存储在该缓冲区对象中。


2.索引数据类型需要正确设置

使用 glDrawElements 函数时,需要根据实际的索引数据类型来正确设置 type 参数。OpenGL ES 支持三种索引数据类型:GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT、GL_UNSIGNED_INT。如果 type 参数设置的不正确,将导致图形渲染出错。


3.绘制的顶点个数需要正确设置

使用 glDrawElements 函数时,需要正确设置 count 参数,以指定需要绘制的顶点的个数。如果 count 参数设置的不正确,将导致图形渲染出错。


4.顶点属性需要正确指定

使用 glDrawElements 函数时,需要使用 glVertexAttribPointer 函数指定顶点属性,例如位置、颜色和纹理坐标等。需要注意的是,顶点属性需要正确指定,否则将导致图形渲染出错。


5.顶点属性需要启用

使用 glDrawElements 函数时,需要使用 glEnableVertexAttribArray 函数启用顶点属性,以开启顶点属性的使用。如果顶点属性未启用,将导致图形渲染出错。


6.索引数组的值需要正确设置

使用 glDrawElements 函数时,索引数组中的值表示的是顶点数组中的位置信息,而不是实际的顶点值。需要确保索引数组中的值正确匹配顶点数组中的值,否则将导致图形渲染出错。

综上所述,在使用glDrawElements函数时,需要仔细考虑以上注意事项,以确保图形渲染正确。


OpenGL ES 中,glDrawArrays 和 glDrawElements 都是用于绘制图形的函数。它们之间的主要区别在于如何指定顶点数据。

  1. 1.glDrawArrays:使用连续的一组顶点来定义几何图形。
  2. 2.glDrawElements:使用索引数组来定义几何图形。

三.glDrawElements 函数完整案例代码

下面是使用 C 语言 OpenGL ES 2.0 创建 VBO 和 IBO ,然后使用 glDrawElements 函数绘制一个正方形的完整代码:




/*******************************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): www.codersrc.com
//@File:OpenGL ES glDrawElements 函数
//@Time:2023/03/11 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/*******************************************************************************************/


#include <GLES2/gl2.h>
#include <stdio.h>

#define VERTEX_POS_SIZE 3 // 顶点坐标大小
#define VERTEX_NORMAL_SIZE 3 // 顶点法线大小
#define VERTEX_TEXCOORD0_SIZE 2 // 纹理坐标大小
#define VERTEX_POS_INDX 0 // 顶点坐标索引
#define VERTEX_NORMAL_INDX 1 // 顶点法线索引
#define VERTEX_TEXCOORD0_INDX 2 // 纹理坐标索引

GLfloat vertices[] = {
    // 顶点坐标,顶点法线,纹理坐标
    -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, // 左下角
    1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0, // 右下角
    -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, // 左上角
    1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0 // 右上角
};

GLushort indices[] = {
    0, 1, 2, // 第一个三角形
    1, 3, 2 // 第二个三角形
};

GLuint program;
GLint positionLoc;
GLint normalLoc;
GLint texCoordLoc;
GLint mvpMatrixLoc;
GLuint vbo;
GLuint ibo;

void init() {
    program = glCreateProgram();

    // 注意:着色器代码这里省略

    glLinkProgram(program);
    glUseProgram(program);

    positionLoc = glGetAttribLocation(program, "a_Position");
    normalLoc = glGetAttribLocation(program, "a_Normal");
    texCoordLoc = glGetAttribLocation(program, "a_TexCoord0");
    mvpMatrixLoc = glGetUniformLocation(program, "u_MvpMatrix");

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(positionLoc);
    glVertexAttribPointer(positionLoc, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE, 28, (const GLvoid*)0);

    glEnableVertexAttribArray(normalLoc);
    glVertexAttribPointer(normalLoc, VERTEX_NORMAL_SIZE, GL_FLOAT, GL_FALSE, 28, (const GLvoid*)12);

    glEnableVertexAttribArray(texCoordLoc);
    glVertexAttribPointer(texCoordLoc, VERTEX_TEXCOORD0_SIZE, GL_FLOAT, GL_FALSE, 28, (const GLvoid*)24);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

void render() {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_DEPTH_TEST);

    glUseProgram(program);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glDisable(GL_DEPTH_TEST);
}

void cleanup() {
    glDeleteProgram(program);
    glDeleteBuffers(1, &vbo);
    glDeleteBuffers(1, &ibo);
}

int main() {
    init();

    render();

    cleanup();

    return 0;
}

在这个例子中,我们首先创建了一个 VBO 和一个 IBO,将顶点数据和索引数据存储在缓冲区对象中,然后使用 glVertexAttribPointer 函数指定顶点属性,使用 glEnableVertexAttribArray 函数启用顶点属性,并调用 glDrawElements 函数绘制正方形。需要注意的是,在使用 glDrawElements 函数时,需要先使用 glBindBuffer 函数将索引缓冲区对象绑定到 GL_ELEMENT_ARRAY_BUFFER 目标上,以便 glDrawElements 函数可以正确地使用索引缓冲区对象中的数据。


ChatGPT 3.5 国内中文镜像站免费使用啦
© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容