• HazelEngine 学习记录 - Single Shader 2D Renderer


    Single Shader 2D Renderer

    本节介绍了一种能够使用一个 shader 就可以实现用固定颜色填充的矩形以及用纹理填充的矩形的绘制。具体的做法就是:在绘制纯色矩形的时候,创建一张纯色的纹理传给 shader ,就可以实现上述操作了。

    在 shader 中,这样实现最后颜色输出:

    uniform vec4 u_Color;
    uniform sampler2D u_Texture;
    
    void main()
    {
    	color = texture(u_Texture, v_TexCoord * 10.0) * u_Color;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    当我们想要传入 texture 进行绘制的时候,就将 u_Color设置为白色,当我们想要进行纯色矩形绘制的时候,就创建一个白色 texture 进行绑定。

    添加了一个用 width 和 height 进行创建的 Create 函数:

    Ref<Texture2D> Texture2D::Create(uint32_t width, uint32_t height)
    	{
    		switch (Renderer::GetAPI())
    		{
    			case RendererAPI::API::None:    HZ_CORE_ASSERT(false, "RendererAPI::None is currently not supported!"); return nullptr;
    			case RendererAPI::API::OpenGL:  return CreateRef<OpenGLTexture2D>(width, height);
    		}
    
    		HZ_CORE_ASSERT(false, "Unknown RendererAPI!");
    		return nullptr;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    然后在 OpenGLTexture 中进行实现:

    	OpenGLTexture2D::OpenGLTexture2D(uint32_t width, uint32_t height)
    		: m_Width(width), m_Height(height)
    	{
    		m_InternalFormat = GL_RGBA8;
    		m_DataFormat = GL_RGBA;
    
    		glCreateTextures(GL_TEXTURE_2D, 1, &m_RendererID);
    		glTextureStorage2D(m_RendererID, 1, m_InternalFormat, m_Width, m_Height);
    
    		glTextureParameteri(m_RendererID, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    		glTextureParameteri(m_RendererID, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    
    		glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_S, GL_REPEAT);
    		glTextureParameteri(m_RendererID, GL_TEXTURE_WRAP_T, GL_REPEAT);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    这里指定了纹理的形式为 8字节的 RGBA,数据格式为 RGBA,然后设置了纹理采样和平铺的方式。

    添加了一个函数 SetData 用于给纹理数据进行设置,也就是为了我们创建一个纯色的 texture,在Renderer2D 中,创建了一个 whiteTexture ,然后设置其数据为纯白:

    		uint32_t whiteTextureData = 0xffffffff;
    		s_Data->WhiteTexture->SetData(&whiteTextureData, sizeof(uint32_t));
    
    • 1
    • 2

    绘制纹理部分,我们将 u_Color设置为白色:

    s_Data->TextureShader->SetFloat4("u_Color", glm::vec4(1.0f));
    		texture->Bind();
    
    • 1
    • 2

    然后运行查看结果:

    在这里插入图片描述

    可以看到,红色和蓝色的固定颜色矩形也被绘制上了 texture,这是因为没有给纯色矩形绘制绑定纯白的 texture:

    s_Data->TextureShader->SetFloat4("u_Color", color);
    		s_Data->WhiteTexture->Bind();
    
    • 1
    • 2

    在这里插入图片描述
    这样绘制结果就正确了。
    但是在绘制纯色矩形的时候,不应该绑定之前的纹理,所以应该在绘制之后将当前绑定的纹理取消绑定:

    //OpenGLRendererAPI.cpp::DrawIndexed
    glBindTexture(GL_TEXTURE_2D, 0);
    
    • 1
    • 2

    注释掉白色纹理绑定那行代码检验结果,发现绘制的图形是黑色的,说明之前的 texture 已经解除绑定:

    在这里插入图片描述
    补充
    之前将 shared_ptr 用 Ref 进行了封装,但是没有实现对应的 make_shared

    	template<typename T>
    	using Scope = std::unique_ptr<T>;
    	template<typename T, typename ... Args>
    	constexpr Scope<T> CreateScope(Args&& ... args)
    	{
    		return std::make_unique<T>(std::forward<Args>(args)...);
    	}
    
    	template<typename T>
    	using Ref = std::shared_ptr<T>;
    	template<typename T, typename ... Args>
    	constexpr Ref<T> CreateRef(Args&& ... args)
    	{
    		return std::make_shared<T>(std::forward<Args>(args)...);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    别再用Mybatis Plus 的伪批量新增了!
    【附源码】Python计算机毕业设计融资租赁管理系统
    商业楼智能照明解决方案,配套产品有哪些
    Docker容器-harbor私有仓库部署与管理
    马踏棋盘算法 贪心算法优化
    【VSCode】Windows系统的WSL无法启动vscode问题
    java并发包的基石:AbstractQueuedSychronier及synchornized
    Week 7 - Distributional Representations(分布表示)
    【算法与数据结构】二叉树的三种遍历代码实现(下)—— 非递归方式实现(大量图解)
    AI引擎助力,CamScanner智能高清滤镜开启扫描新纪元!
  • 原文地址:https://blog.csdn.net/miyazono_/article/details/127839565