增加SamplerObject使用范例,使用SamplerObject来设置纹理过滤等参数,而非在纹理上设置
This commit is contained in:
parent
967c385d8b
commit
7cf879207f
@ -3,4 +3,5 @@ add_subdirectory(OutputGLInfo)
|
||||
add_subdirectory(NullWindow)
|
||||
add_subdirectory(DirectGLRender)
|
||||
add_subdirectory(DirectGLTexture)
|
||||
add_subdirectory(TextureSampler)
|
||||
# add_subdirectory(DrawTriangle)
|
||||
|
4
example/TextureSampler/CMakeLists.txt
Normal file
4
example/TextureSampler/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
add_executable(TextureSampler main.cpp TGATexture.cpp)
|
||||
|
||||
target_link_libraries(TextureSampler PRIVATE ${ULRE})
|
||||
|
153
example/TextureSampler/TGATexture.cpp
Normal file
153
example/TextureSampler/TGATexture.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
#include<GLEWCore/glew.h>
|
||||
#include<hgl/type/DataType.h>
|
||||
#include<fstream>
|
||||
#include<iostream>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
namespace
|
||||
{
|
||||
#pragma pack(push,1)
|
||||
struct TGAHeader
|
||||
{
|
||||
uint8 id;
|
||||
uint8 color_map_type;
|
||||
uint8 image_type; // 1 colormap image ,2 true-color,3 grayscale
|
||||
|
||||
uint16 color_map_first;
|
||||
uint16 color_map_length;
|
||||
uint8 color_map_size;
|
||||
|
||||
uint16 x_origin;
|
||||
uint16 y_origin;
|
||||
|
||||
uint16 width;
|
||||
uint16 height;
|
||||
uint8 bit;
|
||||
|
||||
uint8 image_desc;
|
||||
};
|
||||
|
||||
union TGAImageDesc
|
||||
{
|
||||
//不要把此union放到上面的struct中,否则Visual C++会将此union编译成4字节。GCC无此问题
|
||||
uint8 image_desc;
|
||||
struct
|
||||
{
|
||||
uint alpha_depth:4;
|
||||
uint reserved:1;
|
||||
uint direction:1; //0 lower-left,1 upper left
|
||||
};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}//namespace
|
||||
|
||||
bool LoadTGATexture(const std::string &filename,GLuint &tex_id)
|
||||
{
|
||||
std::ifstream file;
|
||||
|
||||
file.open(filename,std::ifstream::in|std::ifstream::binary);
|
||||
|
||||
if(!file.is_open())
|
||||
{
|
||||
std::cerr<<"[ERROR] open file<"<<filename.c_str()<<"> failed."<<std::endl;
|
||||
return(false);
|
||||
}
|
||||
|
||||
file.seekg(0,std::ifstream::end);
|
||||
const int file_length=file.tellg();
|
||||
|
||||
char *data=new char[file_length];
|
||||
|
||||
file.seekg(0,std::ifstream::beg);
|
||||
file.read(data,file_length);
|
||||
file.close();
|
||||
|
||||
TGAHeader *header=(TGAHeader *)data;
|
||||
|
||||
uint videomemory_format;
|
||||
uint source_format;
|
||||
uint line_size=0;
|
||||
|
||||
if(header->image_type==2)
|
||||
{
|
||||
if(header->bit==24)
|
||||
{
|
||||
videomemory_format=GL_RGB8;
|
||||
source_format=GL_BGR;
|
||||
line_size=header->width*3;
|
||||
}
|
||||
else if(header->bit==32)
|
||||
{
|
||||
videomemory_format=GL_RGBA8;
|
||||
source_format=GL_BGRA;
|
||||
line_size=header->width*4;
|
||||
}
|
||||
}
|
||||
else if(header->image_type==3&&header->bit==8)
|
||||
{
|
||||
videomemory_format=GL_R8;
|
||||
source_format=GL_RED;
|
||||
line_size=header->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr<<"[ERROR] Image format error,filename: "<<filename.c_str()<<std::endl;
|
||||
delete[] data;
|
||||
return(false);
|
||||
}
|
||||
|
||||
glCreateTextures(GL_TEXTURE_2D,1,&tex_id);
|
||||
|
||||
glTextureStorage2D(tex_id,1,videomemory_format,header->width,header->height);
|
||||
|
||||
TGAImageDesc img_desc;
|
||||
|
||||
img_desc.image_desc=header->image_desc;
|
||||
|
||||
if(img_desc.direction==1)
|
||||
glTextureSubImage2D(tex_id,0,0,0,header->width,header->height,source_format,GL_UNSIGNED_BYTE,data+sizeof(TGAHeader));
|
||||
else
|
||||
{
|
||||
char *new_img=new char[line_size*header->height];
|
||||
char *sp=data+sizeof(TGAHeader)+line_size*(header->height-1);
|
||||
char *tp=new_img;
|
||||
|
||||
for(int i=0;i<header->height;i++)
|
||||
{
|
||||
memcpy(tp,sp,line_size);
|
||||
tp+=line_size;
|
||||
sp-=line_size;
|
||||
}
|
||||
|
||||
glTextureSubImage2D(tex_id,0,0,0,header->width,header->height,source_format,GL_UNSIGNED_BYTE,new_img);
|
||||
delete[] new_img;
|
||||
}
|
||||
|
||||
glGenerateTextureMipmap(tex_id);
|
||||
|
||||
std::cout<<"load image file<"<<filename.c_str()<<">:<"<<header->width<<"x"<<header->height<<"> to texture ok"<<std::endl;
|
||||
|
||||
delete[] data;
|
||||
return(true);
|
||||
}
|
||||
|
||||
GLuint CreateSamplerObject(GLint min_filter,GLint mag_filter,GLint clamp,const GLfloat *border_color)
|
||||
{
|
||||
GLuint sampler_object;
|
||||
|
||||
glGenSamplers(1,&sampler_object);
|
||||
|
||||
glSamplerParameteri(sampler_object,GL_TEXTURE_MIN_FILTER,min_filter);
|
||||
glSamplerParameteri(sampler_object,GL_TEXTURE_MAG_FILTER,mag_filter);
|
||||
glSamplerParameteri(sampler_object,GL_TEXTURE_WRAP_S,clamp);
|
||||
glSamplerParameteri(sampler_object,GL_TEXTURE_WRAP_T,clamp);
|
||||
|
||||
glSamplerParameterfv(sampler_object,GL_TEXTURE_BORDER_COLOR,border_color);
|
||||
|
||||
return(sampler_object);
|
||||
}
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
212
example/TextureSampler/main.cpp
Normal file
212
example/TextureSampler/main.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
#include<hgl/graph/RenderDevice.h>
|
||||
#include<hgl/graph/RenderDriver.h>
|
||||
#include<hgl/graph/RenderWindow.h>
|
||||
#include<iostream>
|
||||
#include<GLEWCore/glew.h>
|
||||
#include<hgl/graph/Shader.h>
|
||||
#include<hgl/math/Math.h>
|
||||
#include<hgl/graph/VertexArray.h>
|
||||
|
||||
using namespace hgl;
|
||||
using namespace hgl::graph;
|
||||
|
||||
constexpr uint screen_width=640;
|
||||
constexpr uint screen_height=640;
|
||||
|
||||
GLuint texture_id=0;
|
||||
GLuint sampler_id=0;
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
bool LoadTGATexture(const std::string &filename,GLuint &tex_id);
|
||||
GLuint CreateSamplerObject(GLint min_filter,GLint mag_filter,GLint clamp,const GLfloat *border_color);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr char vertex_shader[]=R"(
|
||||
#version 330 core
|
||||
|
||||
in vec2 Vertex;
|
||||
in vec2 TexCoord;
|
||||
|
||||
out vec2 FragmentTexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragmentTexCoord=TexCoord;
|
||||
|
||||
gl_Position=vec4(Vertex,0.0,1.0);
|
||||
})";
|
||||
|
||||
constexpr char fragment_shader[]=R"(
|
||||
#version 330 core
|
||||
|
||||
uniform sampler2D TextureLena;
|
||||
|
||||
in vec2 FragmentTexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor=texture(TextureLena,FragmentTexCoord);
|
||||
})";
|
||||
|
||||
Shader shader;
|
||||
|
||||
bool InitShader()
|
||||
{
|
||||
if(!shader.AddVertexShader(vertex_shader))
|
||||
return(false);
|
||||
|
||||
if(!shader.AddFragmentShader(fragment_shader))
|
||||
return(false);
|
||||
|
||||
if(!shader.Build())
|
||||
return(false);
|
||||
|
||||
if(!shader.Use())
|
||||
return(false);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
VB2f *vb_vertex=nullptr;
|
||||
VB2f *vb_texcoord=nullptr;
|
||||
VertexArray *va=nullptr;
|
||||
|
||||
constexpr float vertex_data[]={ -0.75f, 0.75f,
|
||||
-0.75f,-0.75f,
|
||||
0.75f, 0.75f,
|
||||
0.75f,-0.75f
|
||||
};
|
||||
|
||||
constexpr float texcoord_data[]={ -0.25,-0.25,
|
||||
-0.25, 1.25,
|
||||
1.25,-0.25,
|
||||
1.25, 1.25 };
|
||||
|
||||
|
||||
void BindVBO2VAO(const int vao,const int binding_index,const int shader_location,VertexBufferBase *vb)
|
||||
{
|
||||
glVertexArrayAttribBinding(vao,shader_location,binding_index);
|
||||
glVertexArrayAttribFormat(vao,shader_location,vb->GetComponent(),vb->GetDataType(),GL_FALSE,0);
|
||||
glEnableVertexArrayAttrib(vao,shader_location);
|
||||
glVertexArrayVertexBuffer(vao,binding_index,vb->GetBufferIndex(),0,vb->GetStride());
|
||||
}
|
||||
|
||||
void InitVertexBuffer()
|
||||
{
|
||||
vb_vertex=new VB2f(4,vertex_data);
|
||||
vb_texcoord=new VB2f(4,texcoord_data);
|
||||
|
||||
va=new VertexArray(GL_TRIANGLE_STRIP, //画三角形条
|
||||
2); //两个属性
|
||||
|
||||
const int vertex_location=shader.GetAttribLocation("Vertex"); ///<取得顶点数据输入流对应的shader地址
|
||||
const int texcoord_location=shader.GetAttribLocation("TexCoord"); ///<取得纹理坐标数据输入流对应的shader地址
|
||||
|
||||
int binding_index=0; //绑定点
|
||||
|
||||
const int vao=va->GetVAO();
|
||||
|
||||
va->SetVertexBuffer(vb_vertex);
|
||||
va->AddVertexAttribBuffer(vb_texcoord);
|
||||
|
||||
BindVBO2VAO(vao,binding_index,vertex_location,vb_vertex);
|
||||
++binding_index;
|
||||
BindVBO2VAO(vao,binding_index,texcoord_location,vb_texcoord);
|
||||
}
|
||||
|
||||
bool InitTexture()
|
||||
{
|
||||
if(!LoadTGATexture("lena.tga",texture_id))
|
||||
return(false);
|
||||
|
||||
const GLfloat border_color[4]={1,1,0,1};
|
||||
|
||||
sampler_id=CreateSamplerObject(GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST, GL_CLAMP_TO_BORDER,border_color);
|
||||
|
||||
int texture_location=shader.GetUniformLocation("TextureLena");
|
||||
|
||||
glBindTextureUnit(0,texture_id);
|
||||
glBindSampler(0,sampler_id);
|
||||
|
||||
shader.SetUniform1i(texture_location,0);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
constexpr GLfloat clear_color[4]=
|
||||
{
|
||||
77.f/255.f,
|
||||
78.f/255.f,
|
||||
83.f/255.f,
|
||||
1.f
|
||||
};
|
||||
|
||||
constexpr GLfloat clear_depth=1.0f;
|
||||
|
||||
void draw()
|
||||
{
|
||||
glClearBufferfv(GL_COLOR,0,clear_color);
|
||||
glClearBufferfv(GL_DEPTH,0,&clear_depth);
|
||||
|
||||
va->Draw();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
RenderDevice *device=CreateRenderDeviceGLFW();
|
||||
|
||||
if(!device)
|
||||
{
|
||||
std::cerr<<"Create RenderDevice(GLFW) failed."<<std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!device->Init())
|
||||
{
|
||||
std::cerr<<"Init RenderDevice(GLFW) failed."<<std::endl;
|
||||
return -2;
|
||||
}
|
||||
|
||||
WindowSetup ws;
|
||||
|
||||
ws.Name=U8_TEXT("Direct use \"OpenGL Core API\" Render");
|
||||
|
||||
RenderSetup rs;
|
||||
|
||||
RenderWindow *win=device->Create(screen_width,screen_height,&ws,&rs);
|
||||
|
||||
win->MakeToCurrent(); //切换当前窗口到前台
|
||||
|
||||
InitOpenGLDebug(); //初始化OpenGL调试输出
|
||||
|
||||
if(!InitShader())
|
||||
{
|
||||
std::cerr<<"init shader failed."<<std::endl;
|
||||
return -3;
|
||||
}
|
||||
|
||||
InitVertexBuffer();
|
||||
|
||||
if(!InitTexture())
|
||||
return -4;
|
||||
|
||||
win->Show();
|
||||
|
||||
while(win->IsOpen())
|
||||
{
|
||||
draw();
|
||||
|
||||
win->SwapBuffer(); //交换前后台显示缓冲区
|
||||
win->PollEvent(); //处理窗口事件
|
||||
}
|
||||
|
||||
delete win;
|
||||
delete device;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user