目标GL_TEXTURE*
|
采样器类型 |
维度
|
1D
|
sampler1D
|
1D
|
1D_ARRAY
|
sampler1DArray
|
1D数组
|
2D
|
sampler2D
|
2D
|
2D_ARRAY
|
sampler2DArray
|
2D数组
|
2D_MULTISAMPLE
|
sampler2DMS
|
2D多重采样
|
2D_MULTISAMPLE_ARRAY
|
sampler2DMSArray
|
2D多重采样数组
|
3D
|
sampler3D
|
3D
|
CUBE
|
samplerCube
|
立方体纹理映射
|
ARRAY
|
samplerCubeArray
|
立方体映射数组 |
RECTANGLE
|
samplerRect
|
2D矩阵
|
BUFFER
|
samplerBuffer
|
1D缓存
|
pname
|
param
|
GL_TEXTURE_MAG_FILTER
|
GL_NEAREST、GL_LINEAR
|
GL_TEXTURE_MIN_FILTER
|
GL_NEAREST、GL_LINEAR、GL_NEAREST_MIPMAP_NEAREST、GL_NEAREST_MIPMAP_LINEAR、GL_LINEAR_MIPMAP_NEAREST、GL_LINEAR_MIPMAP_LINEAR
|
GL_TEXTURE_WRAP_S、GL_TEXTURE_WRAP_T
|
GL_REPEAT、GL_CLAMP_TO_EDGE、GL_MIRRORED_REPEAT
|
GLuint vglLoadTexture(const char* filename, GLuint texture, vglImageData* image) { vglImageData local_image; int level; if (image == 0) image = &local_image; vglLoadImage(filename, image); if (texture == 0) { glGenTextures(1, &texture); } glBindTexture(image->target, texture); GLubyte * ptr = (GLubyte *)image->mip[0].data; switch (image->target) { case GL_TEXTURE_1D: glTexStorage1D(image->target, image->mipLevels, image->internalFormat, image->mip[0].width); //根据从dds中读取到的纹理数据,分配纹理内存,设置纹理格式。 for (level = 0; level < image->mipLevels; ++level) { glTexSubImage1D(GL_TEXTURE_1D, level, 0, image->mip[level].width, image->format, image->type, image->mip[level].data);//设置数据,minmap } break; case GL_TEXTURE_1D_ARRAY: glTexStorage2D(image->target, image->mipLevels, image->internalFormat, image->mip[0].width, image->slices); for (level = 0; level < image->mipLevels; ++level) { glTexSubImage2D(GL_TEXTURE_1D, level, 0, 0, image->mip[level].width, image->slices, image->format, image->type, image->mip[level].data); } break; case GL_TEXTURE_2D: glTexStorage2D(image->target, image->mipLevels, image->internalFormat, image->mip[0].width, image->mip[0].height); for (level = 0; level < image->mipLevels; ++level) { glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, image->mip[level].width, image->mip[level].height, image->format, image->type, image->mip[level].data); } break; case GL_TEXTURE_CUBE_MAP: for (level = 0; level < image->mipLevels; ++level) { ptr = (GLubyte *)image->mip[level].data; for (int face = 0; face < 6; face++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, image->internalFormat, image->mip[level].width, image->mip[level].height, 0, image->format, image->type, ptr + image->sliceStride * face); } } break; case GL_TEXTURE_2D_ARRAY: glTexStorage3D(image->target, image->mipLevels, image->internalFormat, image->mip[0].width, image->mip[0].height, image->slices); for (level = 0; level < image->mipLevels; ++level) { glTexSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0, 0, 0, image->mip[level].width, image->mip[level].height, image->slices, image->format, image->type, image->mip[level].data); } break; case GL_TEXTURE_CUBE_MAP_ARRAY: glTexStorage3D(image->target, image->mipLevels, image->internalFormat, image->mip[0].width, image->mip[0].height, image->slices); break; case GL_TEXTURE_3D: glTexStorage3D(image->target, image->mipLevels, image->internalFormat, image->mip[0].width, image->mip[0].height, image->mip[0].depth); for (level = 0; level < image->mipLevels; ++level) { glTexSubImage3D(GL_TEXTURE_3D, level, 0, 0, 0, image->mip[level].width, image->mip[level].height, image->mip[level].depth, image->format, image->type, image->mip[level].data); } break; default: break; } glTexParameteriv(image->target, GL_TEXTURE_SWIZZLE_RGBA, reinterpret_cast<const GLint *>(image->swizzle)); if (image == &local_image) { vglUnloadImage(image); } return texture; }a、简单纹理加载
#include "vermilion.h" #include "loadTexture.h" #include "vbm.h" #include "vmath.h" #include "vutils.h" namespace loadTexture { float aspect = 800.0f/600.0f; GLuint base_prog; GLuint vao; GLuint quad_vbo; GLuint tex; }; using namespace loadTexture; void loadTextureInit() { base_prog = glCreateProgram(); static const char quad_shader_vs[] = "#version 330 core\n" "\n" "layout (location = 0) in vec2 in_position;\n" "layout (location = 1) in vec2 in_tex_coord;\n" "\n" "out vec2 tex_coord;\n" "\n" "void main(void)\n" "{\n" " gl_Position = vec4(in_position, 0.5, 1.0);\n" " tex_coord = in_tex_coord;\n"//把纹理坐标传递给下一阶段。 "}\n" ; static const char quad_shader_fs[] = "#version 330 core\n" "\n" "in vec2 tex_coord;\n" "\n" "layout (location = 0) out vec4 color;\n" "\n" "uniform sampler2D tex;\n" "\n" "void main(void)\n" "{\n" " color = texture(tex, tex_coord);\n"//texture 根据纹理坐标采集纹素。 "}\n" ; vglAttachShaderSource( base_prog, GL_VERTEX_SHADER, quad_shader_vs ); vglAttachShaderSource( base_prog, GL_FRAGMENT_SHADER, quad_shader_fs ); glGenBuffers( 1, &quad_vbo ); glBindBuffer( GL_ARRAY_BUFFER, quad_vbo ); static const GLfloat quad_data[] = { 0.5f, -0.5f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; glBufferData( GL_ARRAY_BUFFER, sizeof(quad_data), quad_data, GL_STATIC_DRAW ); glGenVertexArrays( 1, &vao ); glBindVertexArray( vao ); glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) ); //设置顶点着色器的输出,顶点坐标 glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET( 8 * sizeof(float) ) );//顶点数据,纹理坐标 glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glLinkProgram( base_prog ); //char buf[1024]; //glGetProgramInfoLog( base_prog, 1024, NULL, buf ); vglImageData image; tex = vglLoadTexture("../8edlib/media/test.dds", 0, &image ); //内部实现了纹理加载操作glGenTexture(),glBindTexture(),glStorage*(),glTexSubImage*() glTexParameteri( image.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); //纹理缩小过滤模式 vglUnloadImage(&image);//纹理信息已经保存在纹理对象当中,释放内存 } void loadTextureDisplay() { float t = float(GetTickCount() & 0x3FFF) / float(0x3FFF); static const vmath::vec3 X(1.0f, 0.0f, 0.0f); static const vmath::vec3 Y(0.0f, 1.0f, 0.0f); static const vmath::vec3 Z(0.0f, 0.0f, 1.0f); glClearColor(0.0f, 1.0f, 0.0f, 1.0f); glClearDepth( 1.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glDisable( GL_CULL_FACE );//禁用剔除操作 glUseProgram( base_prog ); glBindVertexArray( vao ); glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );//扇形三角形绘制 } void loadTextureUpdate(float delta) { }运行结果:
#include "commonHead.h" #include "vbm.h" #include "vutils.h" namespace textureWrap { float aspect = 800.0f/600.0f; GLuint base_prog; GLuint vao; GLuint quad_vbo; GLuint tex; }; using namespace textureWrap; void textureWrapInit() { base_prog = glCreateProgram(); static const char quad_shader_vs[] = "#version 330 core\n" "\n" "layout (location = 0) in vec2 in_position;\n" "layout (location = 1) in vec2 in_tex_coord;\n" "\n" "out vec2 tex_coord;\n" "\n" "void main(void)\n" "{\n" " gl_Position = vec4(in_position, 0.5, 1.0);\n" " tex_coord = in_tex_coord;\n" "}\n" ; static const char quad_shader_fs[] = "#version 330 core\n" "\n" "in vec2 tex_coord;\n" "\n" "layout (location = 0) out vec4 color;\n" "\n" "uniform sampler2D tex;\n" "\n" "void main(void)\n" "{\n" " color = texture(tex, tex_coord);\n" "}\n" ; vglAttachShaderSource( base_prog, GL_VERTEX_SHADER, quad_shader_vs ); vglAttachShaderSource( base_prog, GL_FRAGMENT_SHADER, quad_shader_fs ); glGenBuffers( 1, &quad_vbo ); glBindBuffer( GL_ARRAY_BUFFER, quad_vbo ); static const GLfloat quad_data[] = { -0.75f, -0.75f, 0.75f, -0.75f, 0.75f, 0.75f, -0.75f, 0.75f, 0.0f, 0.0f, 4.0f, 0.0f, 4.0f, 4.0f, 0.0f, 4.0f }; glBufferData( GL_ARRAY_BUFFER, sizeof(quad_data), quad_data, GL_STATIC_DRAW ); glGenVertexArrays( 1, &vao ); glBindVertexArray( vao ); glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) ); glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET( 8 * sizeof(float) ) ); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glLinkProgram( base_prog ); glGenTextures( 1, &tex ); glBindTexture( GL_TEXTURE_2D, tex ); glTexStorage2D( GL_TEXTURE_2D, 4, GL_RGBA8, 8, 8 ); //分配内存,不可改变 static const unsigned char texture_data[] = { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF }; glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RED, GL_UNSIGNED_BYTE, texture_data );//数据初始化 static const GLint swizzles[] = { GL_RED, GL_RED, GL_RED, GL_ONE };//只使用纹理的红色通道 glTexParameteriv( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzles ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );//纹理过滤函数,缩小 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );//纹理过滤函数,放大 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );//超出-1.0~1.0f的纹理坐标处理方式设置s方向 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );//t方向 glGenerateMipmap( GL_TEXTURE_2D );//产生层级纹理。 } void textureWrapUpdate(float) { } void textureWrapDisplay() { unsigned int ticks = GetTickCount(); float t = float(ticks & 0x3FFF) / float(0x3FFF); static const vmath::vec3 X(1.0f, 0.0f, 0.0f); static const vmath::vec3 Y(0.0f, 1.0f, 0.0f); static const vmath::vec3 Z(0.0f, 0.0f, 1.0f); glClearColor( 0.3f, 0.3f, 0.3f, 1.0f ); glClearDepth( 1.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glDisable( GL_CULL_FACE ); glUseProgram( base_prog ); static const GLenum wrap_modes[] = { GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, GL_REPEAT, GL_MIRRORED_REPEAT }; //GL_CLAMP_TO_EDGE : 当纹理坐标超出0.0—1.0时,使用纹理边缘的纹素返回。 //GL_CLAMP_TO_BORDER : 读取纹理范围之外的卓彪将生成用来形成最总的纹理常数边界颜色。可以通过glTexParameterfv()以GL_TEXTURE_BORDER_COLOR为参数设置边界颜色值。 //GL_REPEAT : 包裹纹理,无限重复,只有纹理坐标的小数部分用来生成纹理坐标,整数部分被抛弃。 //GL_MIRRORED_REPEAT : 是一个特殊的模式,纹理可以以镜像模式重复。整数部分是偶数的纹理坐标只考虑小数部分,整数部分是奇数的纹理坐标是1.0减去其小数部分来形成最终坐标。 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_modes[3] ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_modes[3] ); glBindVertexArray( vao ); glDrawArrays( GL_TRIANGLE_FAN, 0, 4 ); }运行结果:
#include "multiTexture\multiTexture.h" #include "vbm.h" #include "vutils.h" #include "vermilion.h" namespace multiTexture { float aspect = 800.0f/600.0f; GLuint base_prog; GLuint vao; GLuint quad_vbo; GLuint tex1; GLuint tex2; GLint time_loc; }; using namespace multiTexture; void multiTextureInit() { base_prog = glCreateProgram(); static const char quad_shader_vs[] = "#version 330 core\n" "\n" "layout (location = 0) in vec2 in_position;\n" "layout (location = 1) in vec2 in_tex_coord;\n" "\n" "out vec2 tex_coord0;\n" "out vec2 tex_coord1;\n" "\n" "uniform float time;\n" "\n" "void main(void)\n" "{\n" " mat2 m = mat2( vec2(cos(time), sin(time)),\n" //书中源码这里定义的是const mat2是会产生连接时错误,因为m是根据时间而改变的,不可以为const " vec2(-sin(time), cos(time)) );\n" " gl_Position = vec4(in_position, 0.5, 1.0);\n" " tex_coord0 = in_tex_coord * m;\n" " tex_coord1 = in_tex_coord * transpose(m);\n"//构造的是一个旋转矩阵, "}\n" ; static const char quad_shader_fs[] = "#version 330 core\n" "\n" "in vec2 tex_coord0;\n" "in vec2 tex_coord1;\n" "\n" "layout (location = 0) out vec4 color;\n" "\n" "uniform sampler2D tex1;\n" //sampler1 "uniform sampler2D tex2;\n" //sampler2 "\n" "void main(void)\n" "{\n" " color = texture(tex1, tex_coord0) + texture(tex2, tex_coord1);\n" //对两个纹理采样进行混合,add "}\n" ; vglAttachShaderSource( base_prog, GL_VERTEX_SHADER, quad_shader_vs ); vglAttachShaderSource(base_prog, GL_FRAGMENT_SHADER, quad_shader_fs); glGenBuffers( 1, &quad_vbo ); glBindBuffer( GL_ARRAY_BUFFER, quad_vbo ); static const GLfloat quad_data[] = { 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; glBufferData( GL_ARRAY_BUFFER, sizeof(quad_data), quad_data, GL_STATIC_DRAW ); glGenVertexArrays( 1, &vao ); glBindVertexArray( vao ); glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) ); glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET( sizeof(float) * 8 ) ); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glLinkProgram( base_prog ); char buf[1024]; glGetProgramInfoLog(base_prog, 1024, NULL, buf); glUseProgram(base_prog); time_loc = glGetUniformLocation( base_prog, "time" ); glUniform1i(glGetUniformLocation(base_prog, "tex1"), 0); glUniform1i( glGetUniformLocation(base_prog, "tex2"), 1); vglImageData image; tex1 = vglLoadTexture("../8edlib/media/test.dds", 0, &image ); glBindTexture( image.target, tex1 ); glTexParameteri( image.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); vglUnloadImage( &image ); tex2 = vglLoadTexture("../8edlib/media/test3.dds", 0, &image); vglUnloadImage( &image ); } void multiTextureDisplay() { float t = float(GetTickCount() & 0x3FFF) / float(0x3FFF); static const vmath::vec3 X(1.0f, 0.0f, 0.0f); static const vmath::vec3 Y(0.0f, 1.0f, 0.0f); static const vmath::vec3 Z(0.0f, 0.0f, 1.0f); glClearColor( 0.0f, 1.0f, 0.0f, 1.0f ); glClearDepth( 1.0f ); glDisable( GL_CULL_FACE ); glUseProgram( base_prog ); glUniform1f( time_loc, t ); glBindVertexArray( vao ); glActiveTexture( GL_TEXTURE0 ); //启用纹理单元0 glBindTexture( GL_TEXTURE_2D, tex1 ); glActiveTexture( GL_TEXTURE1 ); //启用纹理单元1 glBindTexture(GL_TEXTURE_2D, tex2 ); glDrawArrays( GL_TRIANGLE_FAN, 0, 4 ); GLenum errcode = glGetError(); const char* buf1 = (const char*)glewGetErrorString(errcode); } void multiTextureUpdate(float delta) { }运行结果