mirror of
				https://github.com/NoelFB/blah.git
				synced 2025-11-04 01:41:34 +08:00 
			
		
		
		
	separated Textures from Samplers, to accommodate HLSL etc
This commit is contained in:
		@ -27,6 +27,7 @@ add_library(blah
 | 
			
		||||
	public/blah/graphics/mesh.cpp
 | 
			
		||||
	public/blah/graphics/renderpass.h
 | 
			
		||||
	public/blah/graphics/renderpass.cpp
 | 
			
		||||
	public/blah/graphics/sampler.h
 | 
			
		||||
	public/blah/graphics/shader.h
 | 
			
		||||
	public/blah/graphics/shader.cpp
 | 
			
		||||
	public/blah/graphics/texture.h
 | 
			
		||||
 | 
			
		||||
@ -43,11 +43,11 @@ namespace Blah
 | 
			
		||||
 | 
			
		||||
		// Creates a new Texture.
 | 
			
		||||
		// if the Texture is invalid, this should return an empty reference.
 | 
			
		||||
		TextureRef create_texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format);
 | 
			
		||||
		TextureRef create_texture(int width, int height, TextureFormat format);
 | 
			
		||||
 | 
			
		||||
		// Creates a new FrameBuffer.
 | 
			
		||||
		// if the FrameBuffer is invalid, this should return an empty reference.
 | 
			
		||||
		FrameBufferRef create_framebuffer(int width, int height, const TextureFormat* attachments, int attachmentCount);
 | 
			
		||||
		FrameBufferRef create_framebuffer(int width, int height, const TextureFormat* attachments, int attachment_count);
 | 
			
		||||
 | 
			
		||||
		// Creates a new Shader.
 | 
			
		||||
		// if the Shader is invalid, this should return an empty reference.
 | 
			
		||||
 | 
			
		||||
@ -58,9 +58,7 @@ namespace Blah
 | 
			
		||||
 | 
			
		||||
		struct StoredSampler
 | 
			
		||||
		{
 | 
			
		||||
			TextureFilter filter;
 | 
			
		||||
			TextureWrap wrap_x;
 | 
			
		||||
			TextureWrap wrap_y;
 | 
			
		||||
			TextureSampler sampler;
 | 
			
		||||
			ID3D11SamplerState* state;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
@ -79,7 +77,7 @@ namespace Blah
 | 
			
		||||
		ID3D11InputLayout* get_layout(D3D11_Shader* shader, const VertexFormat& format);
 | 
			
		||||
		ID3D11BlendState* get_blend(const BlendMode& blend);
 | 
			
		||||
		ID3D11RasterizerState* get_rasterizer(const RenderPass& pass);
 | 
			
		||||
		ID3D11SamplerState* get_sampler(const TextureRef& texture);
 | 
			
		||||
		ID3D11SamplerState* get_sampler(const TextureSampler& sampler);
 | 
			
		||||
		ID3D11DepthStencilState* get_depthstencil(const RenderPass& pass);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
@ -140,15 +138,23 @@ namespace Blah
 | 
			
		||||
			D3D11_SHADER_INPUT_BIND_DESC desc;
 | 
			
		||||
			reflector->GetResourceBindingDesc(i, &desc);
 | 
			
		||||
 | 
			
		||||
			if (desc.Type == D3D_SIT_TEXTURE && 
 | 
			
		||||
				desc.Dimension == D3D_SRV_DIMENSION_TEXTURE2D)
 | 
			
		||||
			if (desc.Type == D3D_SIT_TEXTURE && desc.Dimension == D3D_SRV_DIMENSION_TEXTURE2D)
 | 
			
		||||
			{
 | 
			
		||||
				auto uniform = append_to.expand();
 | 
			
		||||
				uniform->name = desc.Name;
 | 
			
		||||
				uniform->shader = shader_type;
 | 
			
		||||
				uniform->buffer_index = 0;
 | 
			
		||||
				uniform->array_length = max(1, desc.BindCount);
 | 
			
		||||
				uniform->type = UniformType::Texture;
 | 
			
		||||
				uniform->type = UniformType::Texture2D;
 | 
			
		||||
			}
 | 
			
		||||
			else if (desc.Type == D3D_SIT_SAMPLER)
 | 
			
		||||
			{
 | 
			
		||||
				auto uniform = append_to.expand();
 | 
			
		||||
				uniform->name = desc.Name;
 | 
			
		||||
				uniform->shader = shader_type;
 | 
			
		||||
				uniform->buffer_index = 0;
 | 
			
		||||
				uniform->array_length = max(1, desc.BindCount);
 | 
			
		||||
				uniform->type = UniformType::Sampler2D;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -224,10 +230,7 @@ namespace Blah
 | 
			
		||||
	private:
 | 
			
		||||
		int m_width;
 | 
			
		||||
		int m_height;
 | 
			
		||||
		TextureFilter m_filter;
 | 
			
		||||
		TextureFormat m_format;
 | 
			
		||||
		TextureWrap m_wrap_x;
 | 
			
		||||
		TextureWrap m_wrap_y;
 | 
			
		||||
		bool m_is_framebuffer;
 | 
			
		||||
		int m_size;
 | 
			
		||||
 | 
			
		||||
@ -235,14 +238,11 @@ namespace Blah
 | 
			
		||||
		ID3D11Texture2D* texture = nullptr;
 | 
			
		||||
		ID3D11ShaderResourceView* view = nullptr;
 | 
			
		||||
 | 
			
		||||
		D3D11_Texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format, bool is_framebuffer)
 | 
			
		||||
		D3D11_Texture(int width, int height, TextureFormat format, bool is_framebuffer)
 | 
			
		||||
		{
 | 
			
		||||
			m_width = width;
 | 
			
		||||
			m_height = height;
 | 
			
		||||
			m_filter = filter;
 | 
			
		||||
			m_format = format;
 | 
			
		||||
			m_wrap_x = wrap_x;
 | 
			
		||||
			m_wrap_y = wrap_y;
 | 
			
		||||
			m_is_framebuffer = is_framebuffer;
 | 
			
		||||
			m_size = 0;
 | 
			
		||||
 | 
			
		||||
@ -320,32 +320,6 @@ namespace Blah
 | 
			
		||||
			return m_format;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual void set_filter(TextureFilter filter) override
 | 
			
		||||
		{
 | 
			
		||||
			m_filter = filter;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual TextureFilter get_filter() const override
 | 
			
		||||
		{
 | 
			
		||||
			return m_filter;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual void set_wrap(TextureWrap x, TextureWrap y) override
 | 
			
		||||
		{
 | 
			
		||||
			m_wrap_x = x;
 | 
			
		||||
			m_wrap_y = y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual TextureWrap get_wrap_x() const override
 | 
			
		||||
		{
 | 
			
		||||
			return m_wrap_x;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual TextureWrap get_wrap_y() const override
 | 
			
		||||
		{
 | 
			
		||||
			return m_wrap_y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual void set_data(unsigned char* data) override
 | 
			
		||||
		{
 | 
			
		||||
			D3D11_BOX box;
 | 
			
		||||
@ -386,17 +360,12 @@ namespace Blah
 | 
			
		||||
		StackVector<ID3D11RenderTargetView*, Attachments::MaxCapacity - 1> color_views;
 | 
			
		||||
		ID3D11DepthStencilView* depth_view = nullptr;
 | 
			
		||||
 | 
			
		||||
		D3D11_FrameBuffer(int width, int height, const TextureFormat* attachments, int attachmentCount)
 | 
			
		||||
		D3D11_FrameBuffer(int width, int height, const TextureFormat* attachments, int attachment_count)
 | 
			
		||||
		{
 | 
			
		||||
			for (int i = 0; i < attachmentCount; i++)
 | 
			
		||||
			for (int i = 0; i < attachment_count; i++)
 | 
			
		||||
			{
 | 
			
		||||
				auto tex = new D3D11_Texture(
 | 
			
		||||
					width, height,
 | 
			
		||||
					TextureFilter::Linear,
 | 
			
		||||
					TextureWrap::Repeat,
 | 
			
		||||
					TextureWrap::Repeat,
 | 
			
		||||
					attachments[i],
 | 
			
		||||
					true);
 | 
			
		||||
				auto tex = new D3D11_Texture(width, height, attachments[i], true);
 | 
			
		||||
 | 
			
		||||
				m_attachments.push_back(TextureRef(tex));
 | 
			
		||||
 | 
			
		||||
				if (attachments[i] == TextureFormat::DepthStencil)
 | 
			
		||||
@ -891,9 +860,9 @@ namespace Blah
 | 
			
		||||
		state.swap_chain->Present(1, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	TextureRef GraphicsBackend::create_texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format)
 | 
			
		||||
	TextureRef GraphicsBackend::create_texture(int width, int height, TextureFormat format)
 | 
			
		||||
	{
 | 
			
		||||
		auto result = new D3D11_Texture(width, height, filter, wrap_x, wrap_y, format, false);
 | 
			
		||||
		auto result = new D3D11_Texture(width, height, format, false);
 | 
			
		||||
		if (result->texture)
 | 
			
		||||
			return TextureRef(result);
 | 
			
		||||
 | 
			
		||||
@ -901,9 +870,9 @@ namespace Blah
 | 
			
		||||
		return TextureRef();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	FrameBufferRef GraphicsBackend::create_framebuffer(int width, int height, const TextureFormat* attachments, int attachmentCount)
 | 
			
		||||
	FrameBufferRef GraphicsBackend::create_framebuffer(int width, int height, const TextureFormat* attachments, int attachment_count)
 | 
			
		||||
	{
 | 
			
		||||
		return FrameBufferRef(new D3D11_FrameBuffer(width, height, attachments, attachmentCount));
 | 
			
		||||
		return FrameBufferRef(new D3D11_FrameBuffer(width, height, attachments, attachment_count));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ShaderRef GraphicsBackend::create_shader(const ShaderData* data)
 | 
			
		||||
@ -936,7 +905,9 @@ namespace Blah
 | 
			
		||||
			const float* data = material->data();
 | 
			
		||||
			for (auto& it : shader->uniforms())
 | 
			
		||||
			{
 | 
			
		||||
				if (it.type == UniformType::Texture)
 | 
			
		||||
				if (it.type == UniformType::None ||
 | 
			
		||||
					it.type == UniformType::Texture2D ||
 | 
			
		||||
					it.type == UniformType::Sampler2D)
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				int size = 0;
 | 
			
		||||
@ -1071,7 +1042,7 @@ namespace Blah
 | 
			
		||||
			ctx->PSSetShader(shader->fragment, nullptr, 0);
 | 
			
		||||
			ctx->PSSetConstantBuffers(0, shader->fcb.size(), shader->fcb.begin());
 | 
			
		||||
 | 
			
		||||
			// Fragment Shader Textures & Samplers
 | 
			
		||||
			// Fragment Shader Textures
 | 
			
		||||
			auto& textures = pass.material->textures();
 | 
			
		||||
			for (int i = 0; i < textures.size(); i++)
 | 
			
		||||
			{
 | 
			
		||||
@ -1080,23 +1051,17 @@ namespace Blah
 | 
			
		||||
					// Assign the Texture
 | 
			
		||||
					auto view = ((D3D11_Texture*)textures[i].get())->view;
 | 
			
		||||
					ctx->PSSetShaderResources(i, 1, &view);
 | 
			
		||||
 | 
			
		||||
					// Assign the Sampler
 | 
			
		||||
 | 
			
		||||
					// TODO:
 | 
			
		||||
					// This is incorrect! Textures and Samplers are separate in HLSL.
 | 
			
		||||
					// For now, assuming there's 1 Sampler Per Texture, and we set it to
 | 
			
		||||
					// the properties of the texture at the same index.
 | 
			
		||||
 | 
			
		||||
					// I think most modern APIs separate these, where as OpenGL makes
 | 
			
		||||
					// them the same (afaik). Either we need to separate these in our
 | 
			
		||||
					// API, or find some work around here.
 | 
			
		||||
 | 
			
		||||
					auto sampler = state.get_sampler(textures[i]);
 | 
			
		||||
					if (sampler)
 | 
			
		||||
						ctx->PSSetSamplers(i, 1, &sampler);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Fragment Shader Samplers
 | 
			
		||||
			auto& samplers = pass.material->samplers();
 | 
			
		||||
			for (int i = 0; i < samplers.size(); i++)
 | 
			
		||||
			{
 | 
			
		||||
				auto sampler = state.get_sampler(samplers[i]);
 | 
			
		||||
				if (sampler)
 | 
			
		||||
					ctx->PSSetSamplers(i, 1, &sampler);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// RS
 | 
			
		||||
@ -1294,14 +1259,10 @@ namespace Blah
 | 
			
		||||
		return nullptr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ID3D11SamplerState* D3D11::get_sampler(const TextureRef& texture)
 | 
			
		||||
	ID3D11SamplerState* D3D11::get_sampler(const TextureSampler& sampler)
 | 
			
		||||
	{
 | 
			
		||||
		auto filter = texture->get_filter();
 | 
			
		||||
		auto wrap_x = texture->get_wrap_x();
 | 
			
		||||
		auto wrap_y = texture->get_wrap_y();
 | 
			
		||||
 | 
			
		||||
		for (auto& it : sampler_cache)
 | 
			
		||||
			if (it.filter == filter && it.wrap_x == wrap_x && it.wrap_y == wrap_y)
 | 
			
		||||
			if (it.sampler == sampler)
 | 
			
		||||
				return it.state;
 | 
			
		||||
 | 
			
		||||
		D3D11_SAMPLER_DESC desc = {};
 | 
			
		||||
@ -1311,19 +1272,19 @@ namespace Blah
 | 
			
		||||
		desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
 | 
			
		||||
		desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
 | 
			
		||||
 | 
			
		||||
		switch (filter)
 | 
			
		||||
		switch (sampler.filter)
 | 
			
		||||
		{
 | 
			
		||||
		case TextureFilter::Nearest: desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; break;
 | 
			
		||||
		case TextureFilter::Linear: desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch (wrap_x)
 | 
			
		||||
		switch (sampler.wrap_x)
 | 
			
		||||
		{
 | 
			
		||||
		case TextureWrap::Clamp: desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; break;
 | 
			
		||||
		case TextureWrap::Repeat: desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch (wrap_y)
 | 
			
		||||
		switch (sampler.wrap_y)
 | 
			
		||||
		{
 | 
			
		||||
		case TextureWrap::Clamp: desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; break;
 | 
			
		||||
		case TextureWrap::Repeat: desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; break;
 | 
			
		||||
@ -1335,9 +1296,7 @@ namespace Blah
 | 
			
		||||
		if (SUCCEEDED(hr))
 | 
			
		||||
		{
 | 
			
		||||
			auto entry = sampler_cache.expand();
 | 
			
		||||
			entry->filter = filter;
 | 
			
		||||
			entry->wrap_x = wrap_x;
 | 
			
		||||
			entry->wrap_y = wrap_y;
 | 
			
		||||
			entry->sampler = sampler;
 | 
			
		||||
			entry->state = result;
 | 
			
		||||
			return result;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -545,9 +545,7 @@ namespace Blah
 | 
			
		||||
		GLuint m_id;
 | 
			
		||||
		int m_width;
 | 
			
		||||
		int m_height;
 | 
			
		||||
		TextureWrap m_wrap_x;
 | 
			
		||||
		TextureWrap m_wrap_y;
 | 
			
		||||
		TextureFilter m_filter;
 | 
			
		||||
		TextureSampler m_sampler;
 | 
			
		||||
		TextureFormat m_format;
 | 
			
		||||
		GLenum m_gl_internal_format;
 | 
			
		||||
		GLenum m_gl_format;
 | 
			
		||||
@ -556,14 +554,12 @@ namespace Blah
 | 
			
		||||
	public:
 | 
			
		||||
		bool framebuffer_parent;
 | 
			
		||||
 | 
			
		||||
		OpenGL_Texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format)
 | 
			
		||||
		OpenGL_Texture(int width, int height, TextureFormat format)
 | 
			
		||||
		{
 | 
			
		||||
			m_id = 0;
 | 
			
		||||
			m_width = width;
 | 
			
		||||
			m_height = height;
 | 
			
		||||
			m_wrap_x = wrap_x;
 | 
			
		||||
			m_wrap_y = wrap_y;
 | 
			
		||||
			m_filter = filter;
 | 
			
		||||
			m_sampler = TextureSampler(TextureFilter::None, TextureWrap::None, TextureWrap::None);
 | 
			
		||||
			m_format = format;
 | 
			
		||||
			framebuffer_parent = false;
 | 
			
		||||
			m_gl_internal_format = GL_RED;
 | 
			
		||||
@ -609,12 +605,7 @@ namespace Blah
 | 
			
		||||
			gl.GenTextures(1, &m_id);
 | 
			
		||||
			gl.ActiveTexture(GL_TEXTURE0);
 | 
			
		||||
			gl.BindTexture(GL_TEXTURE_2D, m_id);
 | 
			
		||||
 | 
			
		||||
			gl.TexImage2D(GL_TEXTURE_2D, 0, m_gl_internal_format, width, height, 0, m_gl_format, m_gl_type, nullptr);
 | 
			
		||||
			gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (m_filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
 | 
			
		||||
			gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (m_filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
 | 
			
		||||
			gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (m_wrap_x == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
 | 
			
		||||
			gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (m_wrap_y == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		~OpenGL_Texture()
 | 
			
		||||
@ -643,38 +634,18 @@ namespace Blah
 | 
			
		||||
			return m_format;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual void set_filter(TextureFilter filter) override
 | 
			
		||||
		void update_sampler(const TextureSampler& sampler)
 | 
			
		||||
		{
 | 
			
		||||
			m_filter = filter;
 | 
			
		||||
			if (m_sampler != sampler)
 | 
			
		||||
			{
 | 
			
		||||
				m_sampler = sampler;
 | 
			
		||||
 | 
			
		||||
			gl.BindTexture(GL_TEXTURE_2D, m_id);
 | 
			
		||||
			gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
 | 
			
		||||
			gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual TextureFilter get_filter() const override
 | 
			
		||||
		{
 | 
			
		||||
			return m_filter;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual void set_wrap(TextureWrap x, TextureWrap y) override
 | 
			
		||||
		{
 | 
			
		||||
			m_wrap_x = x;
 | 
			
		||||
			m_wrap_y = y;
 | 
			
		||||
 | 
			
		||||
			gl.BindTexture(GL_TEXTURE_2D, m_id);
 | 
			
		||||
			gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (x == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
 | 
			
		||||
			gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (y == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual TextureWrap get_wrap_x() const override
 | 
			
		||||
		{
 | 
			
		||||
			return m_wrap_x;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual TextureWrap get_wrap_y() const override
 | 
			
		||||
		{
 | 
			
		||||
			return m_wrap_y;
 | 
			
		||||
				gl.BindTexture(GL_TEXTURE_2D, m_id);
 | 
			
		||||
				gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (m_sampler.filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
 | 
			
		||||
				gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (m_sampler.filter == TextureFilter::Nearest ? GL_NEAREST : GL_LINEAR));
 | 
			
		||||
				gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (m_sampler.wrap_x == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
 | 
			
		||||
				gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (m_sampler.wrap_y == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual void set_data(unsigned char* data) override
 | 
			
		||||
@ -899,20 +870,34 @@ namespace Blah
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
					UniformInfo uniform;
 | 
			
		||||
					uniform.name = name;
 | 
			
		||||
					uniform.type = UniformType::None;
 | 
			
		||||
					uniform.buffer_index = 0;
 | 
			
		||||
					uniform.array_length = size;
 | 
			
		||||
					uniform_locations.push_back(gl.GetUniformLocation(id, name));
 | 
			
		||||
 | 
			
		||||
					if (type == GL_SAMPLER_2D)
 | 
			
		||||
					{
 | 
			
		||||
						uniform.type = UniformType::Texture;
 | 
			
		||||
						uniform.shader = ShaderType::Fragment;
 | 
			
		||||
						UniformInfo tex_uniform;
 | 
			
		||||
						tex_uniform.name = name;
 | 
			
		||||
						tex_uniform.buffer_index = 0;
 | 
			
		||||
						tex_uniform.array_length = size;
 | 
			
		||||
						tex_uniform.type = UniformType::Texture2D;
 | 
			
		||||
						tex_uniform.shader = ShaderType::Fragment;
 | 
			
		||||
						uniform_locations.push_back(gl.GetUniformLocation(id, name));
 | 
			
		||||
						m_uniforms.push_back(tex_uniform);
 | 
			
		||||
 | 
			
		||||
						UniformInfo sampler_uniform;
 | 
			
		||||
						sampler_uniform.name = String(name).append("_sampler");
 | 
			
		||||
						sampler_uniform.buffer_index = 0;
 | 
			
		||||
						sampler_uniform.array_length = size;
 | 
			
		||||
						sampler_uniform.type = UniformType::Sampler2D;
 | 
			
		||||
						sampler_uniform.shader = ShaderType::Fragment;
 | 
			
		||||
						uniform_locations.push_back(gl.GetUniformLocation(id, name));
 | 
			
		||||
						m_uniforms.push_back(sampler_uniform);
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						UniformInfo uniform;
 | 
			
		||||
						uniform.name = name;
 | 
			
		||||
						uniform.type = UniformType::None;
 | 
			
		||||
						uniform.buffer_index = 0;
 | 
			
		||||
						uniform.array_length = size;
 | 
			
		||||
						uniform_locations.push_back(gl.GetUniformLocation(id, name));
 | 
			
		||||
						uniform.shader = (ShaderType)((int)ShaderType::Vertex | (int)ShaderType::Fragment);
 | 
			
		||||
 | 
			
		||||
						if (type == GL_FLOAT)
 | 
			
		||||
@ -933,9 +918,10 @@ namespace Blah
 | 
			
		||||
							Log::error("Unsupported Uniform Type");
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						m_uniforms.push_back(uniform);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					m_uniforms.push_back(uniform);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@ -1192,9 +1178,9 @@ namespace Blah
 | 
			
		||||
	void GraphicsBackend::before_render() {}
 | 
			
		||||
	void GraphicsBackend::after_render() {}
 | 
			
		||||
 | 
			
		||||
	TextureRef GraphicsBackend::create_texture(int width, int height, TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y, TextureFormat format)
 | 
			
		||||
	TextureRef GraphicsBackend::create_texture(int width, int height, TextureFormat format)
 | 
			
		||||
	{
 | 
			
		||||
		auto resource = new OpenGL_Texture(width, height, filter, wrap_x, wrap_y, format);
 | 
			
		||||
		auto resource = new OpenGL_Texture(width, height, format);
 | 
			
		||||
 | 
			
		||||
		if (resource->gl_id() <= 0)
 | 
			
		||||
		{
 | 
			
		||||
@ -1272,10 +1258,9 @@ namespace Blah
 | 
			
		||||
		{
 | 
			
		||||
			gl.UseProgram(shader->gl_id());
 | 
			
		||||
 | 
			
		||||
			// upload uniform values
 | 
			
		||||
			int texture_slot = 0;
 | 
			
		||||
			int gl_texture_slot = 0;
 | 
			
		||||
			GLint texture_ids[64];
 | 
			
		||||
 | 
			
		||||
			auto& uniforms = shader->uniforms();
 | 
			
		||||
			auto data = pass.material->data();
 | 
			
		||||
 | 
			
		||||
@ -1284,14 +1269,19 @@ namespace Blah
 | 
			
		||||
				auto location = shader->uniform_locations[i];
 | 
			
		||||
				auto& uniform = uniforms[i];
 | 
			
		||||
 | 
			
		||||
				// Sampler 2D
 | 
			
		||||
				if (uniform.type == UniformType::Texture)
 | 
			
		||||
				// Sampler 2D's are assigned by updating texture values
 | 
			
		||||
				if (uniform.type == UniformType::Sampler2D)
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				// Texture2D
 | 
			
		||||
				if (uniform.type == UniformType::Texture2D)
 | 
			
		||||
				{
 | 
			
		||||
					for (int n = 0; n < uniform.array_length; n++)
 | 
			
		||||
					{
 | 
			
		||||
						auto tex = pass.material->get_texture(i, n);
 | 
			
		||||
						auto tex = pass.material->get_texture(texture_slot, n);
 | 
			
		||||
						auto sampler = pass.material->get_sampler(texture_slot, n);
 | 
			
		||||
 | 
			
		||||
						gl.ActiveTexture(GL_TEXTURE0 + texture_slot);
 | 
			
		||||
						gl.ActiveTexture(GL_TEXTURE0 + gl_texture_slot);
 | 
			
		||||
 | 
			
		||||
						if (!tex)
 | 
			
		||||
						{
 | 
			
		||||
@ -1299,14 +1289,17 @@ namespace Blah
 | 
			
		||||
						}
 | 
			
		||||
						else
 | 
			
		||||
						{
 | 
			
		||||
							gl.BindTexture(GL_TEXTURE_2D, ((OpenGL_Texture*)tex.get())->gl_id());
 | 
			
		||||
							auto gl_tex = ((OpenGL_Texture*)tex.get());
 | 
			
		||||
							gl_tex->update_sampler(sampler);
 | 
			
		||||
							gl.BindTexture(GL_TEXTURE_2D, gl_tex->gl_id());
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						texture_ids[n] = texture_slot;
 | 
			
		||||
						texture_slot++;
 | 
			
		||||
						texture_ids[n] = gl_texture_slot;
 | 
			
		||||
						gl_texture_slot++;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					gl.Uniform1iv(location, (GLint)uniform.array_length, &texture_ids[0]);
 | 
			
		||||
					texture_slot++;
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,6 +19,7 @@
 | 
			
		||||
#include <blah/graphics/material.h>
 | 
			
		||||
#include <blah/graphics/mesh.h>
 | 
			
		||||
#include <blah/graphics/renderpass.h>
 | 
			
		||||
#include <blah/graphics/sampler.h>
 | 
			
		||||
#include <blah/graphics/shader.h>
 | 
			
		||||
#include <blah/graphics/texture.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -339,6 +339,18 @@ void Batch::set_texture(const TextureRef& texture)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Batch::set_sampler(const TextureSampler& sampler)
 | 
			
		||||
{
 | 
			
		||||
	if (m_batch.elements > 0 && sampler != m_batch.sampler)
 | 
			
		||||
	{
 | 
			
		||||
		m_batches.push_back(m_batch);
 | 
			
		||||
		m_batch.offset += m_batch.elements;
 | 
			
		||||
		m_batch.elements = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_batch.sampler = sampler;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Batch::render(const FrameBufferRef& target)
 | 
			
		||||
{
 | 
			
		||||
	Point size;
 | 
			
		||||
@ -394,7 +406,8 @@ void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4
 | 
			
		||||
	if (!pass.material)
 | 
			
		||||
		pass.material = m_default_material;
 | 
			
		||||
 | 
			
		||||
	pass.material->set_texture(0, b.texture, 0);
 | 
			
		||||
	pass.material->set_texture(0, b.texture);
 | 
			
		||||
	pass.material->set_sampler(0, b.sampler);
 | 
			
		||||
	pass.material->set_value(matrix_uniform, &matrix.m11, 16);
 | 
			
		||||
	
 | 
			
		||||
	pass.blend = b.blend;
 | 
			
		||||
@ -422,6 +435,7 @@ void Batch::clear()
 | 
			
		||||
	m_batch.blend = BlendMode::Normal;
 | 
			
		||||
	m_batch.material.reset();
 | 
			
		||||
	m_batch.texture.reset();
 | 
			
		||||
	m_batch.sampler = default_sampler;
 | 
			
		||||
	m_batch.scissor.w = m_batch.scissor.h = -1;
 | 
			
		||||
	m_batch.flip_vertically = false;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@
 | 
			
		||||
#include <blah/drawing/spritefont.h>
 | 
			
		||||
#include <blah/containers/vector.h>
 | 
			
		||||
#include <blah/graphics/blend.h>
 | 
			
		||||
#include <blah/graphics/sampler.h>
 | 
			
		||||
#include <blah/graphics/renderpass.h>
 | 
			
		||||
#include <blah/app.h>
 | 
			
		||||
 | 
			
		||||
@ -45,6 +46,9 @@ namespace Blah
 | 
			
		||||
		// The name of the Matrix Uniform in the Shader
 | 
			
		||||
		const char* matrix_uniform;
 | 
			
		||||
 | 
			
		||||
		// Default Sampler, set on clear
 | 
			
		||||
		TextureSampler default_sampler;
 | 
			
		||||
 | 
			
		||||
		Batch();
 | 
			
		||||
		Batch(const Batch& other) = delete;
 | 
			
		||||
		Batch& operator=(const Batch& other) = delete;
 | 
			
		||||
@ -112,6 +116,9 @@ namespace Blah
 | 
			
		||||
		// this (ex the `str` and `tex` methods)
 | 
			
		||||
		void set_texture(const TextureRef& texture);
 | 
			
		||||
 | 
			
		||||
		// Sets the current texture sampler for drawing.
 | 
			
		||||
		void set_sampler(const TextureSampler& sampler);
 | 
			
		||||
 | 
			
		||||
		// Draws the batch to the given target
 | 
			
		||||
		void render(const FrameBufferRef& target = App::backbuffer);
 | 
			
		||||
 | 
			
		||||
@ -194,6 +201,7 @@ namespace Blah
 | 
			
		||||
			MaterialRef material;
 | 
			
		||||
			BlendMode blend;
 | 
			
		||||
			TextureRef texture;
 | 
			
		||||
			TextureSampler sampler;
 | 
			
		||||
			bool flip_vertically;
 | 
			
		||||
			Rect scissor;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -89,7 +89,7 @@ namespace Blah
 | 
			
		||||
			rgba = blendColor;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		inline bool operator==(const BlendMode& rhs) const
 | 
			
		||||
		bool operator==(const BlendMode& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return
 | 
			
		||||
				color_op == rhs.color_op && color_src == rhs.color_src && color_dst == rhs.color_dst &&
 | 
			
		||||
@ -97,7 +97,7 @@ namespace Blah
 | 
			
		||||
				mask == rhs.mask && rgba == rhs.rgba;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		inline bool operator!=(const BlendMode& rhs) const
 | 
			
		||||
		bool operator!=(const BlendMode& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return !(*this == rhs);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -49,13 +49,20 @@ Material::Material(const ShaderRef& shader)
 | 
			
		||||
		if (uniform.type == UniformType::None)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (uniform.type == UniformType::Texture)
 | 
			
		||||
		if (uniform.type == UniformType::Texture2D)
 | 
			
		||||
		{
 | 
			
		||||
			for (int i = 0; i < uniform.array_length; i ++)
 | 
			
		||||
				m_textures.push_back(TextureRef());
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (uniform.type == UniformType::Sampler2D)
 | 
			
		||||
		{
 | 
			
		||||
			for (int i = 0; i < uniform.array_length; i++)
 | 
			
		||||
				m_samplers.push_back(TextureSampler());
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		float_size += calc_uniform_size(uniform);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -74,7 +81,7 @@ void Material::set_texture(const char* name, const TextureRef& texture, int inde
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
	for (auto& uniform : m_shader->uniforms())
 | 
			
		||||
	{
 | 
			
		||||
		if (uniform.type != UniformType::Texture)
 | 
			
		||||
		if (uniform.type != UniformType::Texture2D)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (strcmp(uniform.name, name) == 0)
 | 
			
		||||
@ -99,19 +106,20 @@ void Material::set_texture(int slot, const TextureRef& texture, int index)
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
	for (auto& uniform : m_shader->uniforms())
 | 
			
		||||
	{
 | 
			
		||||
		if (uniform.type == UniformType::Texture)
 | 
			
		||||
		{
 | 
			
		||||
			if (s == slot)
 | 
			
		||||
			{
 | 
			
		||||
				if (index > uniform.array_length)
 | 
			
		||||
					break;
 | 
			
		||||
		if (uniform.type != UniformType::Texture2D)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
				m_textures[offset + index] = texture;
 | 
			
		||||
		if (s == slot)
 | 
			
		||||
		{
 | 
			
		||||
			if (index > uniform.array_length)
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			offset += uniform.array_length;
 | 
			
		||||
			s++;
 | 
			
		||||
 | 
			
		||||
			m_textures[offset + index] = texture;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		offset += uniform.array_length;
 | 
			
		||||
		s++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -122,7 +130,7 @@ TextureRef Material::get_texture(const char* name, int index) const
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
	for (auto& uniform : m_shader->uniforms())
 | 
			
		||||
	{
 | 
			
		||||
		if (uniform.type != UniformType::Texture)
 | 
			
		||||
		if (uniform.type != UniformType::Texture2D)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (strcmp(uniform.name, name) == 0)
 | 
			
		||||
@ -145,21 +153,21 @@ TextureRef Material::get_texture(int slot, int index) const
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
	for (auto& uniform : m_shader->uniforms())
 | 
			
		||||
	{
 | 
			
		||||
		if (uniform.type == UniformType::Texture)
 | 
			
		||||
		if (uniform.type != UniformType::Texture2D)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (s == slot)
 | 
			
		||||
		{
 | 
			
		||||
			if (s == slot)
 | 
			
		||||
			{
 | 
			
		||||
				if (index > uniform.array_length)
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				return m_textures[offset + index];
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			offset += uniform.array_length;
 | 
			
		||||
			if (offset + index >= m_textures.size())
 | 
			
		||||
			if (index > uniform.array_length)
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			return m_textures[offset + index];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		offset += uniform.array_length;
 | 
			
		||||
		if (offset + index >= m_textures.size())
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		s++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -167,6 +175,107 @@ TextureRef Material::get_texture(int slot, int index) const
 | 
			
		||||
	return TextureRef();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Material::set_sampler(const char* name, const TextureSampler& sampler, int index)
 | 
			
		||||
{
 | 
			
		||||
	BLAH_ASSERT(m_shader, "Material Shader is invalid");
 | 
			
		||||
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
	for (auto& uniform : m_shader->uniforms())
 | 
			
		||||
	{
 | 
			
		||||
		if (uniform.type != UniformType::Sampler2D)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (strcmp(uniform.name, name) == 0)
 | 
			
		||||
		{
 | 
			
		||||
			m_samplers[offset + index] = sampler;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		offset += uniform.array_length;
 | 
			
		||||
		if (offset + index >= m_samplers.size())
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log::warn("No Sampler Uniform '%s' at index [%i] exists", name, index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Material::set_sampler(int slot, const TextureSampler& sampler, int index)
 | 
			
		||||
{
 | 
			
		||||
	BLAH_ASSERT(m_shader, "Material Shader is invalid");
 | 
			
		||||
 | 
			
		||||
	int s = 0;
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
	for (auto& uniform : m_shader->uniforms())
 | 
			
		||||
	{
 | 
			
		||||
		if (uniform.type != UniformType::Sampler2D)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (s == slot)
 | 
			
		||||
		{
 | 
			
		||||
			if (index > uniform.array_length)
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			m_samplers[offset + index] = sampler;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		offset += uniform.array_length;
 | 
			
		||||
		s++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TextureSampler Material::get_sampler(const char* name, int index) const
 | 
			
		||||
{
 | 
			
		||||
	BLAH_ASSERT(m_shader, "Material Shader is invalid");
 | 
			
		||||
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
	for (auto& uniform : m_shader->uniforms())
 | 
			
		||||
	{
 | 
			
		||||
		if (uniform.type != UniformType::Sampler2D)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (strcmp(uniform.name, name) == 0)
 | 
			
		||||
			return m_samplers[offset + index];
 | 
			
		||||
 | 
			
		||||
		offset += uniform.array_length;
 | 
			
		||||
		if (offset + index >= m_samplers.size())
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log::warn("No Sampler Uniform '%s' at index [%i] exists", name, index);
 | 
			
		||||
	return TextureSampler();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TextureSampler Material::get_sampler(int slot, int index) const
 | 
			
		||||
{
 | 
			
		||||
	BLAH_ASSERT(m_shader, "Material Shader is invalid");
 | 
			
		||||
 | 
			
		||||
	int s = 0;
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
	for (auto& uniform : m_shader->uniforms())
 | 
			
		||||
	{
 | 
			
		||||
		if (uniform.type != UniformType::Sampler2D)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (s == slot)
 | 
			
		||||
		{
 | 
			
		||||
			if (index > uniform.array_length)
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			return m_samplers[offset + index];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		offset += uniform.array_length;
 | 
			
		||||
		if (offset + index >= m_samplers.size())
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		s++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log::warn("No Sampler Uniform ['%i'] at index [%i] exists", slot, index);
 | 
			
		||||
	return TextureSampler();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Material::set_value(const char* name, const float* value, int64_t length)
 | 
			
		||||
{
 | 
			
		||||
	BLAH_ASSERT(m_shader, "Material Shader is invalid");
 | 
			
		||||
@ -176,7 +285,9 @@ void Material::set_value(const char* name, const float* value, int64_t length)
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
	for (auto& uniform : m_shader->uniforms())
 | 
			
		||||
	{
 | 
			
		||||
		if (uniform.type == UniformType::Texture || uniform.type == UniformType::None)
 | 
			
		||||
		if (uniform.type == UniformType::Texture2D ||
 | 
			
		||||
			uniform.type == UniformType::Sampler2D ||
 | 
			
		||||
			uniform.type == UniformType::None)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (strcmp(uniform.name, name) == 0)
 | 
			
		||||
@ -207,7 +318,9 @@ const float* Material::get_value(const char* name, int64_t* length) const
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
	for (auto& uniform : m_shader->uniforms())
 | 
			
		||||
	{
 | 
			
		||||
		if (uniform.type == UniformType::Texture || uniform.type == UniformType::None)
 | 
			
		||||
		if (uniform.type == UniformType::Texture2D ||
 | 
			
		||||
			uniform.type == UniformType::Sampler2D ||
 | 
			
		||||
			uniform.type == UniformType::None)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (strcmp(uniform.name, name) == 0)
 | 
			
		||||
@ -231,6 +344,11 @@ const Vector<TextureRef>& Material::textures() const
 | 
			
		||||
	return m_textures;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Vector<TextureSampler>& Material::samplers() const
 | 
			
		||||
{
 | 
			
		||||
	return m_samplers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const float* Material::data() const
 | 
			
		||||
{
 | 
			
		||||
	return m_data.begin();
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <blah/graphics/texture.h>
 | 
			
		||||
#include <blah/graphics/shader.h>
 | 
			
		||||
#include <blah/graphics/sampler.h>
 | 
			
		||||
#include <blah/containers/vector.h>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
@ -43,6 +44,18 @@ namespace Blah
 | 
			
		||||
		// Gets the texture, or an empty reference if invalid
 | 
			
		||||
		TextureRef get_texture(int slot, int array_index = 0) const;
 | 
			
		||||
 | 
			
		||||
		// Sets the sampler
 | 
			
		||||
		void set_sampler(const char* name, const TextureSampler& sampler, int array_index = 0);
 | 
			
		||||
 | 
			
		||||
		// Sets the sampler
 | 
			
		||||
		void set_sampler(int slot, const TextureSampler& sampler, int array_index = 0);
 | 
			
		||||
 | 
			
		||||
		// Gets the sampler
 | 
			
		||||
		TextureSampler get_sampler(const char* name, int array_index = 0) const;
 | 
			
		||||
 | 
			
		||||
		// Gets the sampler
 | 
			
		||||
		TextureSampler get_sampler(int slot, int array_index = 0) const;
 | 
			
		||||
 | 
			
		||||
		// Sets the value. `length` is the total number of floats to set
 | 
			
		||||
		void set_value(const char* name, const float* value, int64_t length);
 | 
			
		||||
 | 
			
		||||
@ -52,12 +65,16 @@ namespace Blah
 | 
			
		||||
		// Returns the internal Texture buffer
 | 
			
		||||
		const Vector<TextureRef>& textures() const;
 | 
			
		||||
 | 
			
		||||
		// Returns the internal Sampler buffer
 | 
			
		||||
		const Vector<TextureSampler>& samplers() const;
 | 
			
		||||
 | 
			
		||||
		// Returns the interal float buffer of all the values
 | 
			
		||||
		const float* data() const;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		ShaderRef m_shader;
 | 
			
		||||
		Vector<TextureRef> m_textures;
 | 
			
		||||
		Vector<TextureSampler> m_samplers;
 | 
			
		||||
		Vector<float> m_data;
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								public/blah/graphics/sampler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								public/blah/graphics/sampler.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace Blah
 | 
			
		||||
{
 | 
			
		||||
	enum class TextureFilter
 | 
			
		||||
	{
 | 
			
		||||
		None,
 | 
			
		||||
		Linear,
 | 
			
		||||
		Nearest
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	enum class TextureWrap
 | 
			
		||||
	{
 | 
			
		||||
		None,
 | 
			
		||||
		Clamp,
 | 
			
		||||
		Repeat
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	struct TextureSampler
 | 
			
		||||
	{
 | 
			
		||||
		TextureFilter filter;
 | 
			
		||||
		TextureWrap wrap_x;
 | 
			
		||||
		TextureWrap wrap_y;
 | 
			
		||||
 | 
			
		||||
		TextureSampler() :
 | 
			
		||||
			filter(TextureFilter::Linear),
 | 
			
		||||
			wrap_x(TextureWrap::Repeat),
 | 
			
		||||
			wrap_y(TextureWrap::Repeat) {}
 | 
			
		||||
 | 
			
		||||
		TextureSampler(TextureFilter filter) :
 | 
			
		||||
			filter(filter),
 | 
			
		||||
			wrap_x(TextureWrap::Repeat),
 | 
			
		||||
			wrap_y(TextureWrap::Repeat) {}
 | 
			
		||||
 | 
			
		||||
		TextureSampler(TextureFilter filter, TextureWrap wrap_x, TextureWrap wrap_y) :
 | 
			
		||||
			filter(filter),
 | 
			
		||||
			wrap_x(wrap_x),
 | 
			
		||||
			wrap_y(wrap_y) {}
 | 
			
		||||
 | 
			
		||||
		bool operator==(const TextureSampler& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return
 | 
			
		||||
				filter == rhs.filter &&
 | 
			
		||||
				wrap_x == rhs.wrap_x &&
 | 
			
		||||
				wrap_y == rhs.wrap_y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator!=(const TextureSampler& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return !(*this == rhs);
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
@ -15,7 +15,8 @@ namespace Blah
 | 
			
		||||
		Float4,
 | 
			
		||||
		Mat3x2,
 | 
			
		||||
		Mat4x4,
 | 
			
		||||
		Texture
 | 
			
		||||
		Texture2D,
 | 
			
		||||
		Sampler2D
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// Supported Shader Types
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ TextureRef Texture::create(int width, int height, TextureFormat format)
 | 
			
		||||
	BLAH_ASSERT((int)format > (int)TextureFormat::None && (int)format < (int)TextureFormat::Count, "Invalid texture format");
 | 
			
		||||
 | 
			
		||||
	if (width > 0 && height > 0)
 | 
			
		||||
		return GraphicsBackend::create_texture(width, height, TextureFilter::Linear, TextureWrap::Repeat, TextureWrap::Repeat, format);
 | 
			
		||||
		return GraphicsBackend::create_texture(width, height, format);
 | 
			
		||||
 | 
			
		||||
	return TextureRef();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,19 +3,6 @@
 | 
			
		||||
 | 
			
		||||
namespace Blah
 | 
			
		||||
{
 | 
			
		||||
	enum class TextureFilter
 | 
			
		||||
	{
 | 
			
		||||
		None,
 | 
			
		||||
		Linear,
 | 
			
		||||
		Nearest
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	enum class TextureWrap
 | 
			
		||||
	{
 | 
			
		||||
		None,
 | 
			
		||||
		Clamp,
 | 
			
		||||
		Repeat
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	enum class TextureFormat
 | 
			
		||||
	{
 | 
			
		||||
@ -76,21 +63,6 @@ namespace Blah
 | 
			
		||||
		// Gets the format of the Texture
 | 
			
		||||
		virtual TextureFormat format() const = 0;
 | 
			
		||||
 | 
			
		||||
		// Sets the filter of the Texture
 | 
			
		||||
		virtual void set_filter(TextureFilter filter) = 0;
 | 
			
		||||
 | 
			
		||||
		// Gets the filter of the Texture
 | 
			
		||||
		virtual TextureFilter get_filter() const = 0;
 | 
			
		||||
 | 
			
		||||
		// Sets the wrap of the Texture
 | 
			
		||||
		virtual void set_wrap(TextureWrap x, TextureWrap y) = 0;
 | 
			
		||||
 | 
			
		||||
		// Gets the wrap of the Texture
 | 
			
		||||
		virtual TextureWrap get_wrap_x() const = 0;
 | 
			
		||||
 | 
			
		||||
		// Gets the wrap of the Texture
 | 
			
		||||
		virtual TextureWrap get_wrap_y() const = 0;
 | 
			
		||||
 | 
			
		||||
		// Sets the data of the Texture.
 | 
			
		||||
		// Note that the pixel buffer should be in the same format as the Texture. There is no row padding.
 | 
			
		||||
		// If the pixel buffer isn't the same size as the texture, it will set the minimum available amount of data.
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user