目标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(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)
{
}
运行结果