opengl ES传入指定位置坐标在传入坐标的位置进行马赛克处理其他位置不进行马赛克处理完整代码例子
时间: 2023-09-16 19:10:24 浏览: 138
Android OpenGL ES 简明开发教程四:3D 坐标变换
4星 · 用户满意度95%
以下是一个简单的OpenGL ES马赛克处理的例子代码:
```c
#include <GLES2/gl2.h>
// 马赛克处理的像素数
#define MOSAIC_SIZE 10
// 顶点着色器代码
const char* vertexShaderCode =
"attribute vec4 a_Position;\n"
"void main() {\n"
" gl_Position = a_Position;\n"
"}\n";
// 片段着色器代码
const char* fragmentShaderCode =
"precision mediump float;\n"
"uniform sampler2D u_Texture;\n"
"uniform vec2 u_MosaicSize;\n"
"varying vec2 v_TexCoord;\n"
"void main() {\n"
" vec2 mosaicCoord = vec2(floor(v_TexCoord.x / u_MosaicSize.x), floor(v_TexCoord.y / u_MosaicSize.y));\n"
" vec2 mosaicTexCoord = vec2(mosaicCoord.x * u_MosaicSize.x, mosaicCoord.y * u_MosaicSize.y);\n"
" gl_FragColor = texture2D(u_Texture, mosaicTexCoord);\n"
"}\n";
// 顶点坐标数据
GLfloat vertices[] = {
-1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, -1.0f,
1.0f, 1.0f,
};
// 纹理坐标数据
GLfloat texCoords[] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
};
// 坐标索引数据
GLushort indices[] = {0, 1, 2, 0, 2, 3};
// 纹理ID
GLuint textureId;
// 着色器程序ID
GLuint programId;
void initTexture() {
// 创建纹理
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
// 设置纹理参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 加载图片并设置纹理数据
int width, height, channels;
unsigned char* image = stbi_load("image.png", &width, &height, &channels, STBI_rgb_alpha);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
stbi_image_free(image);
}
void initShader() {
// 创建顶点着色器对象
GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderId, 1, &vertexShaderCode, nullptr);
glCompileShader(vertexShaderId);
// 创建片段着色器对象
GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderId, 1, &fragmentShaderCode, nullptr);
glCompileShader(fragmentShaderId);
// 创建着色器程序对象
programId = glCreateProgram();
glAttachShader(programId, vertexShaderId);
glAttachShader(programId, fragmentShaderId);
glBindAttribLocation(programId, 0, "a_Position");
glBindAttribLocation(programId, 1, "a_TexCoord");
glLinkProgram(programId);
// 获取uniform变量的位置
GLint mosaicSizeLocation = glGetUniformLocation(programId, "u_MosaicSize");
// 设置uniform变量的值
glUniform2f(mosaicSizeLocation, MOSAIC_SIZE, MOSAIC_SIZE);
}
void initVertexBuffer() {
// 创建顶点缓冲区对象
GLuint vertexBufferId;
glGenBuffers(1, &vertexBufferId);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 创建纹理坐标缓冲区对象
GLuint texCoordBufferId;
glGenBuffers(1, &texCoordBufferId);
glBindBuffer(GL_ARRAY_BUFFER, texCoordBufferId);
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW);
// 创建索引缓冲区对象
GLuint indexBufferId;
glGenBuffers(1, &indexBufferId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 设置顶点属性指针
GLuint positionLocation = glGetAttribLocation(programId, "a_Position");
glEnableVertexAttribArray(positionLocation);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
// 设置纹理坐标属性指针
GLuint texCoordLocation = glGetAttribLocation(programId, "a_TexCoord");
glEnableVertexAttribArray(texCoordLocation);
glBindBuffer(GL_ARRAY_BUFFER, texCoordBufferId);
glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
}
void render() {
// 清空颜色缓冲区
glClear(GL_COLOR_BUFFER_BIT);
// 绑定纹理
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
// 绘制矩形
glUseProgram(programId);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
}
int main() {
// 初始化OpenGL ES上下文
// 初始化纹理
initTexture();
// 初始化着色器程序
initShader();
// 初始化顶点缓冲区
initVertexBuffer();
// 渲染场景
render();
return 0;
}
```
在片段着色器中,我们使用了一个uniform变量`u_MosaicSize`来表示马赛克处理的像素数,计算出当前像素所在的马赛克块的坐标,然后再根据马赛克块的坐标计算出当前像素在马赛克块中的坐标,最后使用该坐标取纹理颜色,从而实现马赛克处理。在初始化着色器程序时,我们使用`glUniform2f`函数将`u_MosaicSize`的值设置为`MOSAIC_SIZE`。
阅读全文