diff --git a/platform/Windows/build.vcxproj b/platform/Windows/build.vcxproj index 013120236..977965d81 100644 --- a/platform/Windows/build.vcxproj +++ b/platform/Windows/build.vcxproj @@ -308,6 +308,7 @@ + @@ -379,6 +380,7 @@ + diff --git a/platform/Windows/build.vcxproj.filters b/platform/Windows/build.vcxproj.filters index dd6b1d3e4..65cea2d77 100644 --- a/platform/Windows/build.vcxproj.filters +++ b/platform/Windows/build.vcxproj.filters @@ -197,6 +197,9 @@ GL Interface + + GL Interface + @@ -406,6 +409,9 @@ GL Interface + + GL Interface + diff --git a/source/glbackend/gl_samplers.cpp b/source/glbackend/gl_samplers.cpp new file mode 100644 index 000000000..05fe54baa --- /dev/null +++ b/source/glbackend/gl_samplers.cpp @@ -0,0 +1,100 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2014-2016 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// + +#include "glad/glad.h" +#include "gl_samplers.h" + +struct TexFilter_s +{ + int minfilter; + int magfilter; + bool mipmapping; +} ; + +TexFilter_s TexFilter[]={ + {GL_NEAREST, GL_NEAREST, false}, + {GL_LINEAR, GL_LINEAR, false}, + {GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST, true}, + {GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR, true}, + {GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST, true}, + {GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, true}, + //{GL_LINEAR_MIPMAP_LINEAR, GL_NEAREST, true}, +}; + + +FSamplerManager::FSamplerManager() +{ + glGenSamplers(NumSamplers, mSamplers); + SetTextureFilterMode(); + glSamplerParameteri(mSamplers[5], GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glSamplerParameteri(mSamplers[5], GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glSamplerParameterf(mSamplers[5], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); + glSamplerParameterf(mSamplers[4], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); + glSamplerParameterf(mSamplers[6], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); + glSamplerParameteri(mSamplers[6], GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glSamplerParameteri(mSamplers[6], GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glSamplerParameteri(mSamplers[1], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[2], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[6], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(mSamplers[6], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +} + +FSamplerManager::~FSamplerManager() +{ + UnbindAll(); + glDeleteSamplers(NumSamplers, mSamplers); +} + +void FSamplerManager::UnbindAll() +{ + for (int i = 0; i < 8 /* fixme */; i++) + { + glBindSampler(i, 0); + } +} + +uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) +{ + unsigned int samp = mSamplers[num]; + glBindSampler(texunit, samp); + return 255; +} + + +void FSamplerManager::SetTextureFilterMode(int filter, int anisotropy) +{ + UnbindAll(); + + for (int i = 0; i < 4; i++) + { + glSamplerParameteri(mSamplers[i], GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter); + glSamplerParameteri(mSamplers[i], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); + glSamplerParameterf(mSamplers[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy); + } + glSamplerParameteri(mSamplers[4], GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter); + glSamplerParameteri(mSamplers[4], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); +} diff --git a/source/glbackend/gl_samplers.h b/source/glbackend/gl_samplers.h new file mode 100644 index 000000000..03f9837d4 --- /dev/null +++ b/source/glbackend/gl_samplers.h @@ -0,0 +1,39 @@ +#ifndef __GL_SAMPLERS_H +#define __GL_SAMPLERS_H + +#include + +enum ESampler +{ + SamplerRepeat, + SamplerClampX, + SamplerClampY, + SamplerClampXY, + Sampler2D, + SamplerNoFilter, + Sampler2DFiltered, + NumSamplers +}; + + +class FSamplerManager +{ + // We need 6 different samplers: 4 for the different clamping modes, + // one for 2D-textures and one for voxel textures + unsigned int mSamplers[NumSamplers]; + + void UnbindAll(); + +public: + + FSamplerManager(); + ~FSamplerManager(); + + uint8_t Bind(int texunit, int num, int lastval); + void SetTextureFilterMode(int mode, int aniso); + + +}; + +#endif + diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index 79deffaf1..2a25b8a28 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -1,10 +1,18 @@ #include "glbackend.h" #include "glad/glad.h" -#include +#include "gl_samplers.h" GLInstance GLInterface; -static std::vector Buffer; // cheap-ass implementation. The primary purpose is to get the GL accesses out of polymost.cpp, not writing something performant right away. +void GLInstance::Init() +{ + mSamplers = new FSamplerManager; +} + +void GLInstance::Deinit() +{ + if (mSamplers) delete mSamplers; +} std::pair GLInstance::AllocVertices(size_t num) { @@ -32,3 +40,12 @@ void GLInstance::Draw(EDrawType type, size_t start, size_t count) } glEnd(); } + + +void GLInstance::BindTexture(int texunit, int tex, int sampler) +{ + glActiveTexture(GL_TEXTURE0 + texunit); + glBindTexture(GL_TEXTURE_2D, tex); + mSamplers->Bind(texunit, sampler, 0); + glActiveTexture(GL_TEXTURE0); +} \ No newline at end of file diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index 93db04716..2c069dc15 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -1,6 +1,9 @@ #pragma once #include #include +#include + +class FSamplerManager; struct BaseVertex { @@ -41,12 +44,19 @@ enum EDrawType class GLInstance { + std::vector Buffer; // cheap-ass implementation. The primary purpose is to get the GL accesses out of polymost.cpp, not writing something performant right away. public: + FSamplerManager *mSamplers; + + void Init(); + void Deinit(); std::pair AllocVertices(size_t num); void Draw(EDrawType type, size_t start, size_t count); + void BindTexture(int texunit, int texid, int sampler); + }; extern GLInstance GLInterface; \ No newline at end of file