diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index cb29400e..a7ea7ed8 100755 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -3480,9 +3480,9 @@ namespace CodeImp.DoomBuilder.Data // Set appropriate texture switch(meshes.Skins[j]) { - case "top.png": General.Map.Graphics.SetUniform(UniformName.texture1, textop); break; - case "bottom.png": General.Map.Graphics.SetUniform(UniformName.texture1, texbottom); break; - case "side.png": General.Map.Graphics.SetUniform(UniformName.texture1, texside); break; + case "top.png": General.Map.Graphics.SetTexture(0, textop); break; + case "bottom.png": General.Map.Graphics.SetTexture(0, texbottom); break; + case "side.png": General.Map.Graphics.SetTexture(0, texside); break; default: throw new Exception("Unexpected skin!"); } diff --git a/Source/Core/Rendering/RenderDevice.cs b/Source/Core/Rendering/RenderDevice.cs index 62f14199..863a56c2 100755 --- a/Source/Core/Rendering/RenderDevice.cs +++ b/Source/Core/Rendering/RenderDevice.cs @@ -92,14 +92,6 @@ namespace CodeImp.DoomBuilder.Rendering RenderDevice_SetUniform(Handle, uniform, new float[] { value.Red, value.Green, value.Blue, value.Alpha }, 4); } - public void SetUniform(UniformName uniform, BaseTexture value) - { - } - - public void SetUniform(UniformName uniform, TextureFilter value) - { - } - public void SetUniform(UniformName uniform, Matrix matrix) { RenderDevice_SetUniform(Handle, uniform, new float[] { @@ -213,6 +205,21 @@ namespace CodeImp.DoomBuilder.Rendering }); } + public void SetTexture(int unit, BaseTexture value) + { + RenderDevice_SetTexture(Handle, unit, value != null ? value.Handle : IntPtr.Zero); + } + + public void SetSamplerFilter(int unit, TextureFilter filter) + { + SetSamplerFilter(unit, filter, filter, filter, 0.0f); + } + + public void SetSamplerFilter(int unit, TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy) + { + RenderDevice_SetSamplerFilter(Handle, unit, minfilter, magfilter, mipfilter, maxanisotropy); + } + public void SetSamplerState(int unit, TextureAddress address) { SetSamplerState(unit, address, address, address); @@ -374,6 +381,12 @@ namespace CodeImp.DoomBuilder.Rendering [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] static extern void RenderDevice_SetTransform(IntPtr handle, TransformState state, float[] matrix); + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + static extern void RenderDevice_SetTexture(IntPtr handle, int unit, IntPtr texture); + + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] + static extern void RenderDevice_SetSamplerFilter(IntPtr handle, int unit, TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy); + [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] static extern void RenderDevice_SetSamplerState(IntPtr handle, int unit, TextureAddress addressU, TextureAddress addressV, TextureAddress addressW); @@ -484,7 +497,6 @@ namespace CodeImp.DoomBuilder.Rendering rendersettings, transformsettings, desaturation, - texture1, highlightcolor, worldviewproj, world, @@ -498,12 +510,7 @@ namespace CodeImp.DoomBuilder.Rendering lightColor, ignoreNormals, spotLight, - campos, - filtersettings, - magfiltersettings, - minfiltersettings, - mipfiltersettings, - maxanisotropysetting + campos } public enum Cull : int { None, Counterclockwise } diff --git a/Source/Core/Rendering/Renderer2D.cs b/Source/Core/Rendering/Renderer2D.cs index 488f062e..e923176e 100755 --- a/Source/Core/Rendering/Renderer2D.cs +++ b/Source/Core/Rendering/Renderer2D.cs @@ -235,7 +235,7 @@ namespace CodeImp.DoomBuilder.Rendering case RendererLayer.Background: if((backimageverts == null) || (General.Map.Grid.Background.Texture == null)) break; graphics.SetShader(aapass); - graphics.SetUniform(UniformName.texture1, General.Map.Grid.Background.Texture); + graphics.SetTexture(0, General.Map.Grid.Background.Texture); graphics.Shaders.SetDisplay2DSettings(1f / windowsize.Width, 1f / windowsize.Height, FSAA_FACTOR, layer.alpha, false); graphics.DrawUserPrimitives(PrimitiveType.TriangleStrip, 0, 2, backimageverts); graphics.SetVertexBuffer(0, screenverts, 0, sizeof(FlatVertex)); @@ -244,7 +244,7 @@ namespace CodeImp.DoomBuilder.Rendering // GRID case RendererLayer.Grid: graphics.SetShader(aapass); - graphics.SetUniform(UniformName.texture1, backtex); + graphics.SetTexture(0, backtex); graphics.Shaders.SetDisplay2DSettings(1f / backsize.Width, 1f / backsize.Height, FSAA_FACTOR, layer.alpha, false); graphics.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); break; @@ -252,7 +252,7 @@ namespace CodeImp.DoomBuilder.Rendering // GEOMETRY case RendererLayer.Geometry: graphics.SetShader(aapass); - graphics.SetUniform(UniformName.texture1, plottertex); + graphics.SetTexture(0, plottertex); graphics.Shaders.SetDisplay2DSettings(1f / structsize.Width, 1f / structsize.Height, FSAA_FACTOR, layer.alpha, false); graphics.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); break; @@ -260,7 +260,7 @@ namespace CodeImp.DoomBuilder.Rendering // THINGS case RendererLayer.Things: graphics.SetShader(aapass); - graphics.SetUniform(UniformName.texture1, thingstex); + graphics.SetTexture(0, thingstex); graphics.Shaders.SetDisplay2DSettings(1f / thingssize.Width, 1f / thingssize.Height, FSAA_FACTOR, layer.alpha, false); graphics.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); break; @@ -268,7 +268,7 @@ namespace CodeImp.DoomBuilder.Rendering // OVERLAY case RendererLayer.Overlay: graphics.SetShader(aapass); - graphics.SetUniform(UniformName.texture1, overlaytex); + graphics.SetTexture(0, overlaytex); graphics.Shaders.SetDisplay2DSettings(1f / overlaysize.Width, 1f / overlaysize.Height, FSAA_FACTOR, layer.alpha, false); graphics.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); break; @@ -276,7 +276,7 @@ namespace CodeImp.DoomBuilder.Rendering // SURFACE case RendererLayer.Surface: graphics.SetShader(aapass); - graphics.SetUniform(UniformName.texture1, surfacetex); + graphics.SetTexture(0, surfacetex); graphics.Shaders.SetDisplay2DSettings(1f / overlaysize.Width, 1f / overlaysize.Height, FSAA_FACTOR, layer.alpha, false); graphics.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2); break; @@ -288,7 +288,7 @@ namespace CodeImp.DoomBuilder.Rendering graphics.Present(); // Release binds - graphics.SetUniform(UniformName.texture1, null); + graphics.SetTexture(0, null); graphics.SetVertexBuffer(0, null, 0, 0); } @@ -1209,7 +1209,7 @@ namespace CodeImp.DoomBuilder.Rendering graphics.SetVertexBuffer(0, thingsvertices, 0, FlatVertex.Stride); // Set things texture - graphics.SetUniform(UniformName.texture1, General.Map.Data.ThingTexture.Texture); //mxd + graphics.SetTexture(0, General.Map.Data.ThingTexture.Texture); //mxd SetWorldTransformation(false); graphics.SetVertexDeclaration(graphics.Shaders.FlatVertexDecl); graphics.SetShader(ShaderName.things2d_thing); @@ -1323,7 +1323,7 @@ namespace CodeImp.DoomBuilder.Rendering } if(sprite.Texture == null) sprite.CreateTexture(); - graphics.SetUniform(UniformName.texture1, sprite.Texture); + graphics.SetTexture(0, sprite.Texture); // Determine next lock size locksize = (framegroup.Value.Count > THING_BUFFER_SIZE) ? THING_BUFFER_SIZE : framegroup.Value.Count; @@ -1418,7 +1418,7 @@ namespace CodeImp.DoomBuilder.Rendering } //mxd. Render thing arrows - graphics.SetUniform(UniformName.texture1, General.Map.Data.ThingTexture.Texture); + graphics.SetTexture(0, General.Map.Data.ThingTexture.Texture); graphics.SetShader(ShaderName.things2d_thing); // Determine next lock size @@ -1622,7 +1622,7 @@ namespace CodeImp.DoomBuilder.Rendering graphics.SetFogEnable(false); graphics.SetVertexDeclaration(graphics.Shaders.FlatVertexDecl); graphics.SetShader(ShaderName.display2d_normal); - graphics.SetUniform(UniformName.texture1, t); + graphics.SetTexture(0, t); SetWorldTransformation(transformcoords); graphics.Shaders.SetDisplay2DSettings(1f, 1f, 0f, 1f, General.Settings.ClassicBilinear); @@ -1674,7 +1674,7 @@ namespace CodeImp.DoomBuilder.Rendering graphics.SetFogEnable(false); graphics.SetVertexDeclaration(graphics.Shaders.FlatVertexDecl); graphics.SetShader(ShaderName.display2d_normal); - graphics.SetUniform(UniformName.texture1, label.Texture); + graphics.SetTexture(0, label.Texture); SetWorldTransformation(false); graphics.Shaders.SetDisplay2DSettings(1f, 1f, 0f, 1f, false); graphics.SetVertexBuffer(0, label.VertexBuffer, 0, FlatVertex.Stride); @@ -1714,7 +1714,7 @@ namespace CodeImp.DoomBuilder.Rendering // Text is created? if(!label.SkipRendering) { - graphics.SetUniform(UniformName.texture1, label.Texture); + graphics.SetTexture(0, label.Texture); graphics.SetVertexBuffer(0, label.VertexBuffer, 0, FlatVertex.Stride); // Draw @@ -1775,7 +1775,7 @@ namespace CodeImp.DoomBuilder.Rendering SetWorldTransformation(false); graphics.SetVertexDeclaration(graphics.Shaders.FlatVertexDecl); graphics.SetShader(ShaderName.display2d_normal); - graphics.SetUniform(UniformName.texture1, General.Map.Data.WhiteTexture.Texture); + graphics.SetTexture(0, General.Map.Data.WhiteTexture.Texture); graphics.Shaders.SetDisplay2DSettings(1f, 1f, 0f, 1f, General.Settings.ClassicBilinear); // Draw @@ -1811,7 +1811,7 @@ namespace CodeImp.DoomBuilder.Rendering SetWorldTransformation(false); graphics.SetVertexDeclaration(graphics.Shaders.FlatVertexDecl); graphics.SetShader(ShaderName.display2d_normal); - graphics.SetUniform(UniformName.texture1, General.Map.Data.WhiteTexture.Texture); + graphics.SetTexture(0, General.Map.Data.WhiteTexture.Texture); graphics.Shaders.SetDisplay2DSettings(1f, 1f, 0f, 1f, General.Settings.ClassicBilinear); // Draw @@ -1844,7 +1844,7 @@ namespace CodeImp.DoomBuilder.Rendering SetWorldTransformation(false); graphics.SetVertexDeclaration(graphics.Shaders.FlatVertexDecl); graphics.SetShader(ShaderName.display2d_normal); - graphics.SetUniform(UniformName.texture1, texture.Texture); + graphics.SetTexture(0, texture.Texture); graphics.Shaders.SetDisplay2DSettings(1f, 1f, 0f, 1f, General.Settings.ClassicBilinear); // Draw @@ -1944,7 +1944,7 @@ namespace CodeImp.DoomBuilder.Rendering SetWorldTransformation(false); graphics.SetVertexDeclaration(graphics.Shaders.FlatVertexDecl); graphics.SetShader(ShaderName.display2d_normal); - graphics.SetUniform(UniformName.texture1, General.Map.Data.WhiteTexture.Texture); + graphics.SetTexture(0, General.Map.Data.WhiteTexture.Texture); graphics.Shaders.SetDisplay2DSettings(1f, 1f, 0f, 1f, General.Settings.ClassicBilinear); // Draw @@ -1997,7 +1997,7 @@ namespace CodeImp.DoomBuilder.Rendering SetWorldTransformation(false); graphics.SetVertexDeclaration(graphics.Shaders.FlatVertexDecl); graphics.SetShader(ShaderName.display2d_normal); - graphics.SetUniform(UniformName.texture1, General.Map.Data.WhiteTexture.Texture); + graphics.SetTexture(0, General.Map.Data.WhiteTexture.Texture); graphics.Shaders.SetDisplay2DSettings(1f, 1f, 0f, 1f, General.Settings.ClassicBilinear); // Draw diff --git a/Source/Core/Rendering/Renderer3D.cs b/Source/Core/Rendering/Renderer3D.cs index 1677d479..27962dc3 100755 --- a/Source/Core/Rendering/Renderer3D.cs +++ b/Source/Core/Rendering/Renderer3D.cs @@ -497,7 +497,7 @@ namespace CodeImp.DoomBuilder.Rendering if(General.Settings.GZShowEventLines) RenderArrows(eventlines); // Remove references - graphics.SetUniform(UniformName.texture1, null); + graphics.SetTexture(0, null); //mxd. Trash collections solidgeo = null; @@ -757,7 +757,7 @@ namespace CodeImp.DoomBuilder.Rendering curtexture.CreateTexture(); // Apply texture - graphics.SetUniform(UniformName.texture1, curtexture.Texture); + graphics.SetTexture(0, curtexture.Texture); //mxd. Sort geometry by sector index group.Value.Sort((g1, g2) => g1.Sector.Sector.FixedIndex - g2.Sector.Sector.FixedIndex); @@ -857,7 +857,7 @@ namespace CodeImp.DoomBuilder.Rendering curtexture.CreateTexture(); // Apply texture - graphics.SetUniform(UniformName.texture1, curtexture.Texture); + graphics.SetTexture(0, curtexture.Texture); // Render all things with this texture foreach(VisualThing t in group.Value) @@ -1037,7 +1037,7 @@ namespace CodeImp.DoomBuilder.Rendering curtexture.CreateTexture(); // Apply texture - graphics.SetUniform(UniformName.texture1, curtexture.Texture); + graphics.SetTexture(0, curtexture.Texture); curtexturename = g.Texture.LongName; } @@ -1171,7 +1171,7 @@ namespace CodeImp.DoomBuilder.Rendering curtexture.CreateTexture(); // Apply texture - graphics.SetUniform(UniformName.texture1, curtexture.Texture); + graphics.SetTexture(0, curtexture.Texture); curtexturename = t.Texture.LongName; } @@ -1333,7 +1333,7 @@ namespace CodeImp.DoomBuilder.Rendering continue; if (settexture) - graphics.SetUniform(UniformName.texture1, g.Texture.Texture); + graphics.SetTexture(0, g.Texture.Texture); //normal lights int count = lightOffsets[0]; @@ -1488,7 +1488,7 @@ namespace CodeImp.DoomBuilder.Rendering foreach (KeyValuePair> group in geometrytolit) { if (group.Key.Texture == null) continue; - graphics.SetUniform(UniformName.texture1, group.Key.Texture); + graphics.SetTexture(0, group.Key.Texture); sector = RenderLightsFromGeometryList(group.Value, lights, sector, false); } @@ -1609,7 +1609,7 @@ namespace CodeImp.DoomBuilder.Rendering GZModel model = General.Map.Data.ModeldefEntries[t.Thing.Type].Model; for (int j = 0; j < model.Meshes.Count; j++) { - graphics.SetUniform(UniformName.texture1, model.Textures[j]); + graphics.SetTexture(0, model.Textures[j]); if (!lightpass) { @@ -1744,7 +1744,7 @@ namespace CodeImp.DoomBuilder.Rendering // Set render settings graphics.SetShader(ShaderName.world3d_skybox); - graphics.SetUniform(UniformName.texture1, General.Map.Data.SkyBox); + graphics.SetTexture(0, General.Map.Data.SkyBox); graphics.SetUniform(UniformName.world, world); graphics.SetUniform(UniformName.campos, new Vector4(cameraposition.x, cameraposition.y, cameraposition.z, 0f)); @@ -2014,12 +2014,12 @@ namespace CodeImp.DoomBuilder.Rendering if(crosshairbusy) { if(General.Map.Data.CrosshairBusy3D.Texture == null) General.Map.Data.CrosshairBusy3D.CreateTexture(); - graphics.SetUniform(UniformName.texture1, General.Map.Data.CrosshairBusy3D.Texture); + graphics.SetTexture(0, General.Map.Data.CrosshairBusy3D.Texture); } else { if(General.Map.Data.Crosshair3D.Texture == null) General.Map.Data.Crosshair3D.CreateTexture(); - graphics.SetUniform(UniformName.texture1, General.Map.Data.Crosshair3D.Texture); + graphics.SetTexture(0, General.Map.Data.Crosshair3D.Texture); } // Draw diff --git a/Source/Core/Rendering/ShaderManager.cs b/Source/Core/Rendering/ShaderManager.cs index b05a9c7f..2b51c091 100755 --- a/Source/Core/Rendering/ShaderManager.cs +++ b/Source/Core/Rendering/ShaderManager.cs @@ -124,8 +124,7 @@ namespace CodeImp.DoomBuilder.Rendering Matrix world = D3DDevice.GetTransform(TransformState.World); Matrix view = D3DDevice.GetTransform(TransformState.View); D3DDevice.SetUniform(UniformName.transformsettings, world * view); - TextureFilter filter = (bilinear ? TextureFilter.Linear : TextureFilter.Point); - D3DDevice.SetUniform(UniformName.filtersettings, filter); + D3DDevice.SetSamplerFilter(0, bilinear ? TextureFilter.Linear : TextureFilter.Point); } public void SetThings2DSettings(float alpha) @@ -148,10 +147,11 @@ namespace CodeImp.DoomBuilder.Rendering { //mxd. It's still nice to have anisotropic filtering when texture filtering is disabled TextureFilter magminfilter = (bilinear ? TextureFilter.Linear : TextureFilter.Point); - D3DDevice.SetUniform(UniformName.magfiltersettings, magminfilter); - D3DDevice.SetUniform(UniformName.minfiltersettings, (maxanisotropy > 1.0f ? TextureFilter.Anisotropic : magminfilter)); - D3DDevice.SetUniform(UniformName.mipfiltersettings, (bilinear ? TextureFilter.Linear : TextureFilter.None)); // [SB] use None, otherwise textures are still filtered - D3DDevice.SetUniform(UniformName.maxanisotropysetting, maxanisotropy); + D3DDevice.SetSamplerFilter(0, + maxanisotropy > 1.0f ? TextureFilter.Anisotropic : magminfilter, + magminfilter, + bilinear ? TextureFilter.Linear : TextureFilter.None, // [SB] use None, otherwise textures are still filtered + maxanisotropy); } } } diff --git a/Source/Core/Rendering/SurfaceManager.cs b/Source/Core/Rendering/SurfaceManager.cs index 19599b16..74d058d5 100755 --- a/Source/Core/Rendering/SurfaceManager.cs +++ b/Source/Core/Rendering/SurfaceManager.cs @@ -612,7 +612,7 @@ namespace CodeImp.DoomBuilder.Rendering foreach(KeyValuePair> imgsurfaces in surfaces) { graphics.SetShader(pass); - graphics.SetUniform(UniformName.texture1, imgsurfaces.Key.Texture); + graphics.SetTexture(0, imgsurfaces.Key.Texture); // Go for all surfaces VertexBuffer lastbuffer = null; diff --git a/Source/Native/RenderDevice.cpp b/Source/Native/RenderDevice.cpp index f6151718..4c3196b9 100644 --- a/Source/Native/RenderDevice.cpp +++ b/Source/Native/RenderDevice.cpp @@ -127,9 +127,50 @@ void RenderDevice::SetTransform(TransformState state, float* matrix) mNeedApply = true; } +void RenderDevice::SetTexture(int index, Texture* texture) +{ + mTextureUnits[index].Tex = texture; + mNeedApply = true; +} + +void RenderDevice::SetSamplerFilter(int index, TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy) +{ + mTextureUnits[index].MinFilter = GetGLMinFilter(minfilter, mipfilter); + mTextureUnits[index].MagFilter = (magfilter == TextureFilter::Point || magfilter == TextureFilter::None) ? GL_NEAREST : GL_LINEAR; + mTextureUnits[index].MaxAnisotropy = maxanisotropy; + mNeedApply = true; +} + +GLint RenderDevice::GetGLMinFilter(TextureFilter filter, TextureFilter mipfilter) +{ + if (mipfilter == TextureFilter::Linear) + { + if (filter == TextureFilter::Point || filter == TextureFilter::None) + return GL_LINEAR_MIPMAP_NEAREST; + else + return GL_LINEAR_MIPMAP_LINEAR; + } + else if (mipfilter == TextureFilter::Point) + { + if (filter == TextureFilter::Point || filter == TextureFilter::None) + return GL_NEAREST_MIPMAP_NEAREST; + else + return GL_NEAREST_MIPMAP_LINEAR; + } + else + { + if (filter == TextureFilter::Point || filter == TextureFilter::None) + return GL_NEAREST; + else + return GL_LINEAR; + } +} + void RenderDevice::SetSamplerState(int index, TextureAddress addressU, TextureAddress addressV, TextureAddress addressW) { - mSamplerStates[index] = { addressU, addressV, addressW }; + mTextureUnits[index].AddressU = addressU; + mTextureUnits[index].AddressV = addressV; + mTextureUnits[index].AddressW = addressW; mNeedApply = true; } @@ -343,7 +384,6 @@ static const int uniformLocations[(int)UniformName::NumUniforms] = { 64, // rendersettings 0, // transformsettings 108, // desaturation - -1, // texture1, 80, // highlightcolor 16, // worldviewproj 32, // world @@ -390,8 +430,6 @@ void RenderDevice::ApplyUniforms() glUniform1fv(locations[(int)UniformName::desaturation], 1, &mUniforms[108].valuef); glUniform1fv(locations[(int)UniformName::ignoreNormals], 1, &mUniforms[109].valuef); glUniform1fv(locations[(int)UniformName::spotLight], 1, &mUniforms[110].valuef); - - glUniform1i(locations[(int)UniformName::texture1], 0); } void RenderDevice::ApplyTextures() @@ -400,13 +438,23 @@ void RenderDevice::ApplyTextures() for (size_t i = 0; i < NumSlots; i++) { - auto& binding = mSamplerStates[i]; + auto& binding = mTextureUnits[i]; glActiveTexture(GL_TEXTURE0 + (GLenum)i); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode[(int)binding.AddressU]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode[(int)binding.AddressV]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, wrapMode[(int)binding.AddressW]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (binding.Tex) + { + GLenum target = binding.Tex->IsCubeTexture() ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; + + glBindTexture(target, binding.Tex->GetTexture()); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, binding.MinFilter); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, binding.MagFilter); + glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode[(int)binding.AddressU]); + glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode[(int)binding.AddressV]); + glTexParameteri(target, GL_TEXTURE_WRAP_R, wrapMode[(int)binding.AddressW]); + } + else + { + glBindTexture(GL_TEXTURE_2D, 0); + } } } @@ -536,6 +584,16 @@ void RenderDevice_SetTransform(RenderDevice* device, TransformState state, float device->SetTransform(state, matrix); } +void RenderDevice_SetTexture(RenderDevice* device, int unit, Texture* texture) +{ + device->SetTexture(unit, texture); +} + +void RenderDevice_SetSamplerFilter(RenderDevice* device, int unit, TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy) +{ + device->SetSamplerFilter(unit, minfilter, magfilter, mipfilter, maxanisotropy); +} + void RenderDevice_SetSamplerState(RenderDevice* device, int unit, TextureAddress addressU, TextureAddress addressV, TextureAddress addressW) { device->SetSamplerState(unit, addressU, addressV, addressW); diff --git a/Source/Native/RenderDevice.h b/Source/Native/RenderDevice.h index cea28cd0..1b92d5c8 100644 --- a/Source/Native/RenderDevice.h +++ b/Source/Native/RenderDevice.h @@ -55,7 +55,6 @@ enum class UniformName : int rendersettings, transformsettings, desaturation, - texture1, highlightcolor, worldviewproj, world, @@ -99,6 +98,8 @@ public: void SetZEnable(bool value); void SetZWriteEnable(bool value); void SetTransform(TransformState state, float* matrix); + void SetTexture(int unit, Texture* texture); + void SetSamplerFilter(int unit, TextureFilter minfilter, TextureFilter magfilter, TextureFilter mipfilter, float maxanisotropy); void SetSamplerState(int unit, TextureAddress addressU, TextureAddress addressV, TextureAddress addressW); void DrawPrimitives(PrimitiveType type, int startIndex, int primitiveCount); void DrawUserPrimitives(PrimitiveType type, int startIndex, int primitiveCount, const void* data); @@ -123,6 +124,8 @@ public: void CheckError(); + GLint GetGLMinFilter(TextureFilter filter, TextureFilter mipfilter); + OpenGLContext Context; struct VertexBinding @@ -135,11 +138,12 @@ public: long Stride = 0; }; - struct SamplerState + struct TextureUnit { - SamplerState() = default; - SamplerState(TextureAddress addressU, TextureAddress addressV, TextureAddress addressW) : AddressU(addressU), AddressV(addressV), AddressW(addressW) { } - + Texture* Tex = nullptr; + GLuint MinFilter = GL_NEAREST; + GLuint MagFilter = GL_NEAREST; + float MaxAnisotropy = 0.0f; TextureAddress AddressU = TextureAddress::Wrap; TextureAddress AddressV = TextureAddress::Wrap; TextureAddress AddressW = TextureAddress::Wrap; @@ -152,7 +156,7 @@ public: int mEnabledVertexAttributes[NumSlots] = { 0 }; VertexBinding mVertexBindings[NumSlots]; - SamplerState mSamplerStates[NumSlots]; + TextureUnit mTextureUnits[NumSlots]; IndexBuffer* mIndexBuffer = nullptr; diff --git a/Source/Native/Shader.cpp b/Source/Native/Shader.cpp index 435c200b..0e1a0b95 100644 --- a/Source/Native/Shader.cpp +++ b/Source/Native/Shader.cpp @@ -64,7 +64,6 @@ bool Shader::Compile(const std::string& vertexShader, const std::string& fragmen "rendersettings", "transformsettings", "desaturation", - "texture1", "highlightcolor", "worldviewproj", "world", diff --git a/Source/Native/Texture.cpp b/Source/Native/Texture.cpp index 65f7ea7c..52e950c8 100644 --- a/Source/Native/Texture.cpp +++ b/Source/Native/Texture.cpp @@ -6,6 +6,11 @@ Texture::Texture() { } +Texture::~Texture() +{ + // To do: move mTexture to a delete list as this might be called by a finalizer in a different thread +} + void Texture::Set2DImage(int width, int height) { mCubeTexture = false; @@ -42,6 +47,47 @@ void Texture::Unlock() { } +GLuint Texture::GetTexture() +{ + if (mTexture == 0) + { + if (!IsCubeTexture()) + { + GLint oldBinding = 0; + glActiveTexture(GL_TEXTURE0); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); + + glGenTextures(1, &mTexture); + glBindTexture(GL_TEXTURE_2D, mTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, !mPixels[0].empty() ? mPixels[0].data() : nullptr); + glGenerateMipmap(GL_TEXTURE_2D); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, oldBinding); + } + else + { + GLint oldBinding = 0; + glActiveTexture(GL_TEXTURE0); + glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldBinding); + + glGenTextures(1, &mTexture); + glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, !mPixels[0].empty() ? mPixels[0].data() : nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, !mPixels[1].empty() ? mPixels[1].data() : nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, !mPixels[2].empty() ? mPixels[2].data() : nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, !mPixels[3].empty() ? mPixels[3].data() : nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, !mPixels[4].empty() ? mPixels[4].data() : nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, mWidth, mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, !mPixels[5].empty() ? mPixels[5].data() : nullptr); + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_CUBE_MAP, oldBinding); + } + } + return mTexture; +} + ///////////////////////////////////////////////////////////////////////////// Texture* Texture_New() diff --git a/Source/Native/Texture.h b/Source/Native/Texture.h index 66f40e94..f547ba98 100644 --- a/Source/Native/Texture.h +++ b/Source/Native/Texture.h @@ -14,6 +14,7 @@ class Texture { public: Texture(); + ~Texture(); void Set2DImage(int width, int height); void SetCubeImage(int size); @@ -24,9 +25,14 @@ public: void* Lock(); void Unlock(); + bool IsCubeTexture() const { return mCubeTexture; } + + GLuint GetTexture(); + private: int mWidth = 0; int mHeight = 0; bool mCubeTexture = false; std::map> mPixels; + GLuint mTexture = 0; }; diff --git a/Source/Native/exports.def b/Source/Native/exports.def index 456c3a6a..9f8e52aa 100644 --- a/Source/Native/exports.def +++ b/Source/Native/exports.def @@ -23,6 +23,8 @@ EXPORTS RenderDevice_SetZEnable RenderDevice_SetZWriteEnable RenderDevice_SetTransform + RenderDevice_SetTexture + RenderDevice_SetSamplerFilter RenderDevice_SetSamplerState RenderDevice_DrawPrimitives RenderDevice_DrawUserPrimitives