标签:输入 char 单点 简单 img http def 备忘 需要
2D纹理是一个图像数据的二维数组,一个纹理的单独数据元素称作纹理像素(texture pixels)。
// 设置数据传输模式
// void glPixelStorei (GLenum pname, GLint param);
// UNPACK:将图像数据从内存传输到GPU内存中
// PACK:将图像数据从GPU内存传输到内存中
// OpenGL ES默认是按4字节4字节的形式传输到GPU内存中的,但是GL_RGB格式只有3个字节,所以这里就改为按1个字节1个字节的形式将图像数据传输到GPU内存中
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// 1. 创建一个纹理对象
// void glGenTextures (GLsizei n, GLuint *textures);
// n表示要生成的纹理对象数量;textures表示保存n个纹理对象ID的无符号整数数组
glGenTextures(1, &textureId);
// 2. 绑定纹理对象
// void glBindTexture (GLenum target, GLuint texture);
//target表示要绑定的纹理的类型;OpenGL ES中纹理有:2D纹理(GL_TEXTURE_2D),2D纹理数组(GL_TEXTURE_2D_ARRAY),3D纹理(GL_TEXTURE_3D)和立方图纹理(GL_TEXTURE_CUBE_MAP)
// texture为前面生成的纹理ID
glBindTexture(GL_TEXTURE_2D, textureId);
// 3. 加载图像数据
// void glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
// target就是2D纹理类型;level表示mip级别;internalformat表示纹理存储的内部格式,这里为GL_RGB格式
// width表示图像像素宽度;height表示高度;border为了兼容OpenGL桌面API,传0即可
// format表示输入的纹理数据格式,这里为GL_RGB;type表示输入像素数据的类型,这里为GL_UNSIGNED_BYTE;pixels表示图像的实际像素数据
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 3, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
// 4. 设置采样器的参数
// void glTexParameteri (GLenum target, GLenum pname, GLint param);
// target表示要绑定的纹理的类型;pname表示设置参数;param表示参数值
// GL_TEXTURE_MIN_FILTER表示缩小过滤,就是屏幕上投影的多边形小于纹理尺寸的时候,图片分辨率过高;
// GL_TEXTURE_MAG_FILTER表示放大过滤,屏幕上投影的多边形大于纹理尺寸的时候,图片分辨率过低;
// GL_NEAREST从最靠近纹理坐标的纹理中取得单点样本
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// 1. 绑定纹理单元
// void glActiveTexture (GLenum texture);
// texture表示需要激活的纹理单元:GL_TEXTURE0、GL_TEXTURE1 。。。 GL_TEXTURE31
glActiveTexture(GL_TEXTURE0);
// 2. 绑定纹理对象
glBindTexture(GL_TEXTURE_2D, userData->textureId);
// 3. 传递统一变量的值;0代表的是采样纹理单元0:GL_TEXTURE0
glUniform1i(userData->samplerLoc, 0);
// 4. 片段着色器中进行采样操作
// void texture(sampler2D sampler, vec2 coord[,float bias])
// sampler表示绑定到纹理单元的采样器,就是纹理数据
// coord表示纹理坐标;bias为可选参数
// texture函数返回一个代表从纹理贴图中读取颜色的vec4,代表颜色值
outColor = texture(s_texture, v_texCoord);
输入数据样式:
GLubyte pixels[6*3] = {
255, 0, 0, // 红
0, 0, 0, // 黑
0,255,0, // 绿
0,255,255, // 青
0, 0, 255, // 蓝
255, 255, 0 // 黄
};
这是一个2x3的图片:
纹理数据的第一个数据对应坐标(0,0);然后第二个坐标横过去,对应坐标(1,0)
第三个数据向上,对应坐标(0,1);第四个数据横过来,对应坐标(1,1);以此类推。。。
首先把贴纹理,想象成贴照片到墙上就可以了。纹理坐标和顶点坐标之间要一一对应,不可以交叉
GLfloat vVertices[] = {
-0.5f, 0.5f, 0.0f,
0.0f, 1.0f,
-0.5f, -0.5f, 0.0f,
0.0f, 0.0f,
0.5f, -0.5f, 0.0f,
1.0f, 0.0f,
0.5f, 0.5f, 0.0f,
1.0f, 1.0f
};
(0,1)V0 -> (0,0)V1 -> (1,0)V2 -> (1,1)V3
这个顶点坐标和纹理坐标的效果图如上图所示
上面顶点的坐标在坐标系的位置,如下图所示:
把纹理横过来贴:
GLfloat vVertices[] = {
-0.5f, 0.5f, 0.0f,
0.0f, 0.0f,
-0.5f, -0.5f, 0.0f,
1.0f, 0.0f,
0.5f, -0.5f, 0.0f,
1.0f, 1.0f,
0.5f, 0.5f, 0.0f,
0.0f, 1.0f
};
(0,0)V0 -> (1,0)V1 -> (1,1)V2 -> (0,1)V3
交叉贴图的情况:(1,1)本来在(0,0)对角位置的,现在把它贴到(0,0)旁边的顶点上,就会出现对角交叉情况
GLfloat vVertices[] = {
-0.5f, 0.5f, 0.0f,
0.0f, 0.0f,
-0.5f, -0.5f, 0.0f,
1.0f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 1.0f,
0.5f, 0.5f, 0.0f,
1.0f, 1.0f
};
(0,0)V0 -> (1,0)V1 -> (0,1)V2 -> (1,1)V3
#include <stdlib.h>
#include "esUtil.h"
typedef struct
{
GLuint programObject;
GLint samplerLoc;
GLuint textureId;
} myUserData;
GLuint CreateSimpleTexture2D()
{
GLuint textureId;
// 图片数据,6个像素
GLubyte pixels[6*3] = {
255, 0, 0, // 红
0, 0, 0, // 黑
0,255,0, // 绿
0,255,255, // 青
0, 0, 255, // 蓝
255, 255, 0 // 黄
};
// 设置数据传输模式
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// 1. 创建一个纹理对象
glGenTextures(1, &textureId);
// 2. 绑定纹理对象
glBindTexture(GL_TEXTURE_2D, textureId);
// 3. 加载图像数据
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 3, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
// 4. 设置采样器的参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
return textureId;
}
int Init(MYESContext *myesContext)
{
myUserData *userData = (myUserData *)myesContext->userData;
char vShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec4 a_position; \n"
"layout(location = 1) in vec2 a_texCoord; \n"
"out vec2 v_texCoord; \n"
"void main() \n"
"{ \n"
" gl_Position = a_position; \n"
" v_texCoord = a_texCoord; \n"
"} \n";
char fShaderStr[] =
"#version 300 es \n"
"precision mediump float; \n"
"in vec2 v_texCoord; \n"
"layout(location = 0) out vec4 outColor; \n"
"uniform sampler2D s_texture; \n" // 采样器类型统一变量
"void main() \n"
"{ \n"
" outColor = texture(s_texture, v_texCoord); \n" // 4. 片段着色器中进行采样操作
"} \n";
userData->programObject = myesLoadProgram(vShaderStr, fShaderStr);
userData->samplerLoc = glGetUniformLocation(userData->programObject, "s_texture");
userData->textureId = CreateSimpleTexture2D();
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
return GL_TRUE;
}
void Draw(MYESContext *myesContext)
{
myUserData *userData = (myUserData *)myesContext->userData;
GLfloat vVertices[] = {
-0.5f, 0.5f, 0.0f,
0.0f, 1.0f,
-0.5f, -0.5f, 0.0f,
0.0f, 0.0f,
0.5f, -0.5f, 0.0f,
1.0f, 0.0f,
0.5f, 0.5f, 0.0f,
1.0f, 1.0f
};
GLushort indices[] = {0, 1, 2, 0, 2, 3};
glViewport(0, 0, myesContext->width, myesContext->height);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(userData->programObject);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), vVertices);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), &vVertices[3]);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
// 1. 绑定纹理单元
glActiveTexture(GL_TEXTURE0);
// 2. 绑定纹理对象
glBindTexture(GL_TEXTURE_2D, userData->textureId);
// 3. 传递统一变量的值;0代表的是采样纹理单元0:GL_TEXTURE0
glUniform1i(userData->samplerLoc, 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}
void ShutDown(MYESContext *myesContext)
{
myUserData *userData = (myUserData *)myesContext->userData;
// 删除纹理对象
glDeleteTextures(1, &userData->textureId);
glDeleteProgram(userData->programObject);
}
int myesMain(MYESContext *myesContext)
{
myesContext->userData = malloc(sizeof(myUserData));
myesCreateWindow(myesContext, "9_1_simple_texture2D", 320, 240, MY_ES_WINDOW_RGB);
if (!Init(myesContext))
{
return GL_FALSE;
}
esRegisterDrawFunc(myesContext, Draw);
esRegisterShutdownFunc(myesContext, ShutDown);
return GL_TRUE;
}
1. OpenGL常用命令备忘录(Part B) -- glPixelStore
http://www.zwqxin.com/archives/opengl/opengl-api-memorandum-2.html
2. Android OpenGL ES 系列连载:(02)纹理映射
https://zhuanlan.zhihu.com/p/115210823
3. glTexImage2D
http://docs.gl/es2/glTexImage2D
标签:输入 char 单点 简单 img http def 备忘 需要
原文地址:https://www.cnblogs.com/pyjetson/p/14669256.html