OpenGL ES drawing primitives: glDrawArrays and introduced glDrawElements

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/afei__/article/details/89203369

I. Introduction

In OpenGL ES 2.0, a glDrawArraysand glDrawElementstwo interfaces drawing primitives.
In the OpenGL ES 3.0, and added glDrawRangeElements, glDrawElementsInstancedand glDrawArraysInstancedthree interfaces for drawing primitives.

Second, the function introduction

1. glDrawArrays

/**
 * @param mode 渲染的图元模式,有:GL_POINTS、GL_LINES、GL_LINE_LOOP、GL_LINE_STRIP、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN
 * @param first 起始位置
 * @param count 顶点数量
 */
void glDrawArrays(GLenum mode, GLint first, GLsizei count);

2. glDrawElements

/**
 * @param mode 渲染的图元模式,有:GL_POINTS、GL_LINES、GL_LINE_LOOP、GL_LINE_STRIP、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN
 * @param count 顶点数量
 * @param type 元素类型,有:GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT、GL_UNSIGNED_INT
 * @param indices 元素索引数组
 */
void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);

3. difference

First, the role of these two functions are to extract data from a data array and then rendering the primitive.

Except that: glDrawArraysthe direct draw real vertex data, and glDrawElementsis taken out real data in the specified index order redrawn.

Thus for the presence of vertices shared scene, using glDrawElementsonly one data transfer to the duplicate vertex data, acquired by repeated drawing when the index value, and ultimately reduce memory usage and memory bandwidth requirements.

Third, the primitive presentation

We know above, you need to specify when rendering a primitive mode rendering, here we explain in detail these primitives and primitive mode.

1. point sprite

Corresponding mode , GL_POINTS, , a point is plotted at each vertex position. OpenGL ES point plotted is a block actually, the vertex position is the center point of the block, in a side by built vertex shader variables gl_PointSizespecified.

It may range in size from the point of the following ways:

GLfloat pointSizeRange[2];
glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange);

If we want to customize the appearance definition point, you can usually use textures. A texture of the fragment shader examples are as follows:

#version 300 es
precision mediump float;

uniform sampler2D u_TextureUnit;
layout(location = 0) out vec4 outColor;

void main() {
    outColor = texture2D(u_TextureUnit, gl_PointCoord);
}

In this way we give out u_TextureUnitid can be specified texture, texture on the use of relevant follow-up article will introduce.

We also used the example built into a variable gl_PointCoord, it can only be used when drawing point sprite, we describe the inside of the space coordinates, which is the upper left corner (0, 0), the lower right corner is (1, 1) .

2. straight

Mode corresponding to GL_LINES, , GL_LINE_LOOP , GL_LINE_STRIP , draw a line segment corresponding with the specified vertices.
Here Insert Picture Description
As shown, assuming that the vertex coordinates specified (v0, v1, v2, v3 ), then

  • GL_LINES mode, the drawing (v0, v1) and (v2, v3) the two segments
  • GL_LINE_STRIP mode, the drawing (v0, v1), (v1 , v2) and (v2, v3) three line segments
  • GL_LINE_LOOP mode, the drawing (v0, v1), (v1 , v2), (v2, v3) and (v3, v0) four line segments

Line width specified using the following API:

/**
 * @param width 线宽,以像素数表示,默认的宽度为 1.0
 */
void glLineWidth(GLFloat width);

OpenGL specified width will be remembered until the update by the application.

Supported width range can be obtained by:

GLfloat lineWidthRange[2];
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, lineWidthRange);

3. Triangle

Mode corresponding to GL_TRIANGLES , square using GL_TRIANGLE_STRIP , GL_TRIANGLE_FAN . Triangle primitives can be described as the most commonly used.
Here Insert Picture Description
As shown, the vertex coordinates is assumed that the specified figure, then

  • GL_TRIANGLES mode, the drawing (v0, v1, v2) and (v3, v4, v5) two triangles.
  • GL_TRIANGLE_STRIP mode, the drawing (v0, v1, v2), (v2, v1, v3) ( note the order) and (v2, v3, v4) three triangles.
  • GL_TRIANGLE_FAN mode, the drawing (v0, v1, v2), (v0, v2, v3) and (v0, v3, v4) three triangles.

Fourth, the new drawing interface 3.0 Introduction

Speaking of the beginning of several new drawing primitives in OpenGL ES 3.0 interface, the next it simple to find out.

1. glDrawRangeElements

/**
 * @param mode 渲染的图元模式,有:GL_POINTS、GL_LINES、GL_LINE_LOOP、GL_LINE_STRIP、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN
 * @param start 起始索引位置
 * @param end 结束索引位置
 * @param count 顶点数量
 * @param type 元素类型,有:GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT、GL_UNSIGNED_INT
 * @param indices 元素索引数组
 */
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices);

Compared to glDrawElementsthe interface, it is added start, endtwo parameters, is used to specify start and end positions of the data array used. The rest are not very different.

2. glDrawElementsInstanced and glDrawArraysInstanced

When you need to draw a large number of similar objects (such as color, there is a different size), in the past we can only send many API calls to OpenGL ES engine. However, the use of geometry instance, one API call can be used to render the same object multiple times with different properties, greatly reduce the CPU processing overhead API calls.

Simply put, if we want to do a batch rendering, you can use glDrawElementsInstancedor glDrawArraysInstanced.

Function definition:

/**
 * @param mode 渲染的图元模式,有:GL_POINTS、GL_LINES、GL_LINE_LOOP、GL_LINE_STRIP、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN
 * @param first 起始位置
 * @param count 顶点数量
 * @param instancecount 绘制的图元实例数量
 */
void glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);

/**
 * @param mode 渲染的图元模式,有:GL_POINTS、GL_LINES、GL_LINE_LOOP、GL_LINE_STRIP、GL_TRIANGLES、GL_TRIANGLE_STRIP、GL_TRIANGLE_FAN
 * @param count 顶点数量
 * @param type 元素类型,有:GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT、GL_UNSIGNED_INT
 * @param indices 元素索引的指针
 * @param instancecount 绘制的图元实例数量
 */
void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount);

Compared to glDrawArraysand glDrawElements, it more of a instancecountparameter that indicates the number of elements that we need to draw. For example, we want to draw the first batch of 100 similar primitives, this value corresponds to 100 to pass.

Drawing on multi-instance want to learn more about, you can refer to other blog:

Blog link:

https://www.jianshu.com/p/71b7149d9dc1
https://www.cnblogs.com/xin-lover/p/9147905.html

Guess you like

Origin blog.csdn.net/afei__/article/details/89203369