I. Introduction
In OpenGL development, will certainly come into contact with the vertex shader (vertex shader) and fragment shaders (fragment shader), the shader language syntax is not too much description herein, the following are some examples shader:
OpenGL ES 2.0 vertex shader Example:
uniform mat4 u_Matrix; // 统一变量
attribute vec4 a_Position; // 属性(输入)
void main() {
gl_Position = u_Matrix * a_Position;
}
OpenGL ES 3.0 vertex shader Example:
#version 300 es
uniform mat4 u_Matrix; // 统一变量
layout(location = 0) in vec4 v_Position; // 属性(输入)
void main() {
gl_Position = u_Matrix * v_Position;
}
In OpenGL ES 2.0 using attribute
and varying
representing input and output variables; in OpenGL ES 3.0 is used directly in
, out
representing input and output variables. Although there is a difference, but the interfaces pass parameters and values are the same.
So, in the application, it is how to pass data to unify these variables and attributes it?
statement:
The latter interfaces are provided by the interface c ++, java interface function with the same name and parameters are, native only made a call.
Second, a unified variable
1. Concept
Unified variable (Uniform) is passed to the application program stored in the shader by API readonly constant value of the variable. For example in the previous example u_Matrix
.
If the variables are declared in a unified vertex shader and fragment shader, the declaration must be the same type, and the values are the same as required.
2. Obtain
We want to give a variable assignment, we need to get to it in order to operate it. We can get into a unified variable by following this interface.
GLint glGetUniformLocation(GLuint program, const GLchar *name);
Parameters explanation:
- program: shader programs you create the return of id.
- name: shader language name of the variable, for example
u_Matrix
.
It is noteworthy that, in OpenGL ES 3.0, we can be layout(location = 0)
in the form of direct variable specified location.
3. by value
We can get through these functions into a unified variable location
, followed by the location we can give it a value of.
Unified variable assignment to have a lot of functions, different consolidated variable types correspond to different functions, as follows:
void glUniform1f(GLint location, GLfloat v0);
void glUniform1fv(GLint location, GLsizei count, const GLfloat *value);
void glUniform1i(GLint location, GLint v0);
void glUniform1iv(GLint location, GLsizei count, const GLint *value);
void glUniform2f(GLint location, GLfloat v0, GLfloat v1);
void glUniform2fv(GLint location, GLsizei count, const GLfloat *value);
void glUniform2i(GLint location, GLint v0, GLint v1);
void glUniform2iv(GLint location, GLsizei count, const GLint *value);
void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
void glUniform3fv(GLint location, GLsizei count, const GLfloat *value);
void glUniform3i(GLint location, GLint v0, GLint v1, GLint v2);
void glUniform3iv(GLint location, GLsizei count, const GLint *value);
void glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
void glUniform4fv(GLint location, GLsizei count, const GLfloat *value);
void glUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
void glUniform4iv(GLint location, GLsizei count, const GLint *value);
void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
Parameters explanation:
- location: unified variable positions, i.e., acquired in the above step value.
- count: number of elements to be loaded, type for vector and matrix types. For example, we define
uniform mat4 u_matrix
then the number is 1, if it isuniform vec3 u_Position[3]
then the number is 3. - transpose: For matrix type, priority column using the specified matrix (
GL_FALSE
) or line-sequential priority (GL_TRUE
). - Unified variable value input: v0, v1, v2, v3.
- value: a unified array pointer variable input.
Third, property
1. Concept
Attribute herein refers only to the vertex shader input variables, because the input is the output of the fragment shader is a vertex shader.
In the OpenGL ES 2.0, by attribute
a modified variable in OpenGL ES 3.0, then by in
or inout
modified variables.
2. Obtain
Similarly, we need to get to it, in order to operate it. We can get into a unified variable by following this interface.
GLint glGetAttribLocation(GLuint program, const GLchar *name);
Parameters explanation:
- program: shader programs you create the return of id.
- name: shader language name of the variable, for example
a_Position
.
It is noteworthy that, in OpenGL ES 3.0, we can be layout(location = 0)
in the form of direct variable specified location.
3. by value
We can get the properties by the above-mentioned functions location
, followed by the location we can give it a value of.
Constant vertex attributes
Constant vertex attributes are the same for all the vertices of a primitive, so only specify a value for all the vertices of a primitive using the function by value as follows:
void glVertexAttrib1f(GLuint index, GLfloat x);
void glVertexAttrib1fv(GLuint index, const GLfloat *v);
void glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
void glVertexAttrib2fv(GLuint index, const GLfloat *v);
void glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
void glVertexAttrib3fv(GLuint index, const GLfloat *v);
void glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void glVertexAttrib4fv(GLuint index, const GLfloat *v);
Wherein the default value of the vertices (0.0, 0.0, 0.0, 1.0)
, the above-described functions are covered with the specified value.
Vertex array
Array of vertices each vertex of the specified properties, using the function by value as follows:
void glVertexAttribPointer(GLuint index,
GLint size,
GLenum type,
GLboolean normalized,
GLsizei stride,
const void *pointer);
void glVertexAttribIPointer(GLuint index,
GLint size,
GLenum type,
GLsizei stride,
const void *pointer);
Parameters explanation:
- index: the index attribute, with LOCATION, i.e., acquired in the above step value.
- size: the number of components of vertex attributes, the effective value of 1 to 4.
- type: data formats, including
GL_BYTE
,GL_UNSIGNED_BYTE
,GL_SHORT
,GL_UNSIGNED_SHORT
,GL_INT
,GL_UNSIGNED_INT
,GL_FLOAT
,GL_HALF_FLOAT
,GL_FIXED
and the like. - normalized: represents the conversion of non-floating-point data format to a floating point value, should it be standardized.
- stride: the span of data between adjacent indexes. If 0, the vertex data of each sequence, jostling stored.
- pointer: a pointer vertex attribute data.
Fourth, examples
1. The vertex shader
There were a unified variables u_Matrix
and attributes a_Position
.
uniform mat4 u_Matrix;
attribute vec4 a_Position;
void main() {
gl_Position = u_Matrix * a_Position;
}
2. Fragment
#include <GLES3/gl3.h>
#include "ShaderUtils.h"
const char* vertexShaderSource =
"uniform mat4 u_Matrix;\n"
"attribute vec4 a_Position;\n"
"\n"
"void main() {\n"
" gl_Position = u_Matrix * a_Position;\n"
"}";
const char* fragmentShaderSource =
"precision mediump float;\n"
"\n"
"uniform vec4 u_Color;\n"
"\n"
"void main() {\n"
" gl_FragColor = u_Color;\n"
"}";
GLuint g_program; // program id
void demo() {
// 1. 创建着色器程序
g_program = CreateProgram(vertexShaderSource, fragmentShaderSource);
glUseProgram(g_program);
// 2. 获取统一变量和属性
GLint matrix_location = glGetUniformLocation(g_program, "u_Matrix");
GLint position_location = glGetAttribLocation(g_program, "a_Position");
// 3. 传值
const GLfloat matrix[] = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
glUniformMatrix4fv(matrix_location, 1, GL_FALSE, matrix);
const GLint vertex_size = 3; // 我们的顶点数组只有x, y, z三个分量
const GLfloat vertices[] = {
0.0f, 0.5f, 0.0f, // 第一个点(x, y, z)
-0.5f, -0.5f, 0.0f, // 第二个点(x, y, z)
0.5f, -0.5f, 0.0f // 第三个点(x, y, z)
};
glVertexAttribPointer(position_location, vertex_size, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(position_location); // 需要使用enable使其生效
// 4. 绘制
glDrawArrays(GL_TRIANGLES, 0, vertex_size);
glDisableVertexAttribArray(position_location);
}
The above code may not be able to run, mainly to show how the basic use. Of course, the content is the basis of the basis described above, to help beginners on the line.