From 7cf879207fdda0af355ce29ff9dceebb010c737e Mon Sep 17 00:00:00 2001 From: hyzboy Date: Sat, 8 Dec 2018 15:58:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0SamplerObject=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E8=8C=83=E4=BE=8B=EF=BC=8C=E4=BD=BF=E7=94=A8SamplerOb?= =?UTF-8?q?ject=E6=9D=A5=E8=AE=BE=E7=BD=AE=E7=BA=B9=E7=90=86=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E7=AD=89=E5=8F=82=E6=95=B0=EF=BC=8C=E8=80=8C=E9=9D=9E?= =?UTF-8?q?=E5=9C=A8=E7=BA=B9=E7=90=86=E4=B8=8A=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/CMakeLists.txt | 1 + example/TextureSampler/CMakeLists.txt | 4 + example/TextureSampler/TGATexture.cpp | 153 +++++++++++++++++++ example/TextureSampler/main.cpp | 212 ++++++++++++++++++++++++++ 4 files changed, 370 insertions(+) create mode 100644 example/TextureSampler/CMakeLists.txt create mode 100644 example/TextureSampler/TGATexture.cpp create mode 100644 example/TextureSampler/main.cpp diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 1e07a0d2..4ff09480 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -3,4 +3,5 @@ add_subdirectory(OutputGLInfo) add_subdirectory(NullWindow) add_subdirectory(DirectGLRender) add_subdirectory(DirectGLTexture) +add_subdirectory(TextureSampler) # add_subdirectory(DrawTriangle) diff --git a/example/TextureSampler/CMakeLists.txt b/example/TextureSampler/CMakeLists.txt new file mode 100644 index 00000000..7d1c0fd9 --- /dev/null +++ b/example/TextureSampler/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable(TextureSampler main.cpp TGATexture.cpp) + +target_link_libraries(TextureSampler PRIVATE ${ULRE}) + diff --git a/example/TextureSampler/TGATexture.cpp b/example/TextureSampler/TGATexture.cpp new file mode 100644 index 00000000..d91c0850 --- /dev/null +++ b/example/TextureSampler/TGATexture.cpp @@ -0,0 +1,153 @@ +#include +#include +#include +#include + +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<"< failed."<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: "<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;iheight;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<"<:<"<width<<"x"<height<<"> to texture ok"< +#include +#include +#include +#include +#include +#include +#include + +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."<Init()) + { + std::cerr<<"Init RenderDevice(GLFW) failed."<Create(screen_width,screen_height,&ws,&rs); + + win->MakeToCurrent(); //切换当前窗口到前台 + + InitOpenGLDebug(); //初始化OpenGL调试输出 + + if(!InitShader()) + { + std::cerr<<"init shader failed."<Show(); + + while(win->IsOpen()) + { + draw(); + + win->SwapBuffer(); //交换前后台显示缓冲区 + win->PollEvent(); //处理窗口事件 + } + + delete win; + delete device; + + return 0; +}