1 /* 2 * This file is part of the Colobot: Gold Edition source code 3 * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam 4 * http://epsitec.ch; http://colobot.info; http://github.com/colobot 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 * See the GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see http://gnu.org/licenses 18 */ 19 20 /** 21 * \file graphics/opengl/gl14device.h 22 * \brief OpenGL implementation - CGL14Device class 23 */ 24 25 #pragma once 26 27 #include "graphics/core/device.h" 28 29 #include "graphics/core/material.h" 30 31 #include "graphics/opengl/glframebuffer.h" 32 #include "graphics/opengl/glutil.h" 33 34 #include "math/matrix.h" 35 36 #include <string> 37 #include <vector> 38 #include <set> 39 #include <map> 40 41 42 // Graphics module namespace 43 namespace Gfx 44 { 45 46 enum ShadowMappingSupport 47 { 48 SMS_NONE, //! No support for depth textures 49 SMS_ARB, //! ARB extension 50 SMS_CORE //! Core support 51 }; 52 53 /** 54 \class CGL14Device 55 \brief Implementation of CDevice interface in OpenGL 56 57 Provides the concrete implementation of 3D device in OpenGL. 58 59 This class should be initialized (by calling Initialize() ) only after 60 setting the video mode by CApplication, once the OpenGL context is defined. 61 Because of that, CGL14DeviceConfig is outside the CDevice class and must be set 62 in CApplication. 63 */ 64 class CGL14Device : public CDevice 65 { 66 public: 67 CGL14Device(const DeviceConfig &config); 68 virtual ~CGL14Device(); 69 70 void DebugHook() override; 71 void DebugLights() override; 72 73 std::string GetName() override; 74 75 bool Create() override; 76 void Destroy() override; 77 78 void ConfigChanged(const DeviceConfig &newConfig) override; 79 80 void BeginScene() override; 81 void EndScene() override; 82 83 void Clear() override; 84 85 void SetRenderMode(RenderMode mode) override; 86 87 void SetTransform(TransformType type, const Math::Matrix &matrix) override; 88 89 void SetMaterial(const Material &material) override; 90 91 int GetMaxLightCount() override; 92 void SetLight(int index, const Light &light) override; 93 void SetLightEnabled(int index, bool enabled) override; 94 95 Texture CreateTexture(CImage *image, const TextureCreateParams ¶ms) override; 96 Texture CreateTexture(ImageData *data, const TextureCreateParams ¶ms) override; 97 Texture CreateDepthTexture(int width, int height, int depth) override; 98 void UpdateTexture(const Texture& texture, Math::IntPoint offset, ImageData* data, TexImgFormat format) override; 99 void DestroyTexture(const Texture &texture) override; 100 void DestroyAllTextures() override; 101 102 int GetMaxTextureStageCount() override; 103 void SetTexture(int index, const Texture &texture) override; 104 void SetTexture(int index, unsigned int textureId) override; 105 void SetTextureEnabled(int index, bool enabled) override; 106 107 void SetTextureStageParams(int index, const TextureStageParams ¶ms) override; 108 109 void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override; 110 111 virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount, 112 Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; 113 virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, 114 Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; 115 virtual void DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount) override; 116 117 virtual void DrawPrimitives(PrimitiveType type, const Vertex *vertices, 118 int first[], int count[], int drawCount, 119 Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; 120 virtual void DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices, 121 int first[], int count[], int drawCount, 122 Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override; 123 virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices, 124 int first[], int count[], int drawCount) override; 125 CreateStaticBuffer(PrimitiveType primitiveType,const Vertex * vertices,int vertexCount)126 unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override 127 { 128 return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); 129 } CreateStaticBuffer(PrimitiveType primitiveType,const VertexTex2 * vertices,int vertexCount)130 unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override 131 { 132 return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); 133 } CreateStaticBuffer(PrimitiveType primitiveType,const VertexCol * vertices,int vertexCount)134 unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override 135 { 136 return CreateStaticBufferImpl(primitiveType, vertices, vertexCount); 137 } UpdateStaticBuffer(unsigned int bufferId,PrimitiveType primitiveType,const Vertex * vertices,int vertexCount)138 void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override 139 { 140 UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); 141 } UpdateStaticBuffer(unsigned int bufferId,PrimitiveType primitiveType,const VertexTex2 * vertices,int vertexCount)142 void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override 143 { 144 UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); 145 } UpdateStaticBuffer(unsigned int bufferId,PrimitiveType primitiveType,const VertexCol * vertices,int vertexCount)146 void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override 147 { 148 UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount); 149 } 150 151 void DrawStaticBuffer(unsigned int bufferId) override; 152 void DestroyStaticBuffer(unsigned int bufferId) override; 153 154 int ComputeSphereVisibility(const Math::Vector ¢er, float radius) override; 155 156 void SetViewport(int x, int y, int width, int height) override; 157 158 void SetRenderState(RenderState state, bool enabled) override; 159 160 void SetColorMask(bool red, bool green, bool blue, bool alpha) override; 161 162 void SetDepthTestFunc(CompFunc func) override; 163 164 void SetDepthBias(float factor, float units) override; 165 166 void SetAlphaTestFunc(CompFunc func, float refValue) override; 167 168 void SetBlendFunc(BlendFunc srcBlend, BlendFunc dstBlend) override; 169 170 void SetClearColor(const Color &color) override; 171 172 void SetGlobalAmbient(const Color &color) override; 173 174 void SetFogParams(FogMode mode, const Color &color, float start, float end, float density) override; 175 176 void SetCullMode(CullMode mode) override; 177 178 void SetShadeModel(ShadeModel model) override; 179 180 void SetShadowColor(float value) override; 181 182 void SetFillMode(FillMode mode) override; 183 184 void CopyFramebufferToTexture(Texture& texture, int xOffset, int yOffset, int x, int y, int width, int height) override; 185 186 std::unique_ptr<CFrameBufferPixels> GetFrameBufferPixels() const override; 187 188 CFramebuffer* GetFramebuffer(std::string name) override; 189 190 CFramebuffer* CreateFramebuffer(std::string name, const FramebufferParams& params) override; 191 192 void DeleteFramebuffer(std::string name) override; 193 194 bool IsAnisotropySupported() override; 195 int GetMaxAnisotropyLevel() override; 196 197 int GetMaxSamples() override; 198 199 bool IsShadowMappingSupported() override; 200 201 int GetMaxTextureSize() override; 202 203 bool IsFramebufferSupported() override; 204 205 private: 206 //! Updates internal modelview matrix 207 void UpdateModelviewMatrix(); 208 //! Updates position for given light based on transformation matrices 209 void UpdateLightPosition(int index); 210 //! Updates position for all lights based on transformation matrices 211 void UpdateLightPositions(); 212 //! Updates the texture params for given texture stage 213 void UpdateTextureParams(int index); 214 215 //! Enables shadows 216 void EnableShadows(); 217 //! Disables shadows 218 void DisableShadows(); 219 220 template <typename Vertex> 221 unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); 222 template <typename Vertex> 223 void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount); 224 225 private: 226 //! Current config 227 DeviceConfig m_config; 228 229 //! Current world matrix 230 Math::Matrix m_worldMat; 231 //! Current view matrix 232 Math::Matrix m_viewMat; 233 //! OpenGL modelview matrix = world matrix * view matrix 234 Math::Matrix m_modelviewMat; 235 //! Current projection matrix 236 Math::Matrix m_projectionMat; 237 //! Combined world-view-projection matrix 238 Math::Matrix m_combinedMatrix; 239 //! Current shadow matrix 240 Math::Matrix m_shadowMatrix; 241 //! true means that combined matrix is outdated 242 bool m_combinedMatrixOutdated = true; 243 244 //! The current material 245 Material m_material; 246 247 //! Whether lighting is enabled 248 bool m_lighting = false; 249 //! Current lights 250 std::vector<Light> m_lights; 251 //! Current lights enable status 252 std::vector<bool> m_lightsEnabled; 253 254 //! Current textures; \c nullptr value means unassigned 255 std::vector<Texture> m_currentTextures; 256 //! Current texture stages enable status 257 std::vector<bool> m_texturesEnabled; 258 //! Current texture params 259 std::vector<TextureStageParams> m_textureStageParams; 260 //! Texture unit remap 261 std::vector<int> m_remap; 262 263 //! Set of all created textures 264 std::set<Texture> m_allTextures; 265 //! White texture 266 GLuint m_whiteTexture = 0; 267 268 //! Map of framebuffers 269 std::map<std::string, std::unique_ptr<CFramebuffer>> m_framebuffers; 270 271 //! Info about static VBO buffers 272 struct VboObjectInfo 273 { 274 PrimitiveType primitiveType = {}; 275 unsigned int bufferId = 0; 276 VertexType vertexType = {}; 277 int vertexCount = 0; 278 }; 279 280 //! Detected capabilities 281 //! Depth texture support 282 ShadowMappingSupport m_shadowMappingSupport = SMS_NONE; 283 //! glMultiDrawArrays() available 284 bool m_multiDrawArrays = false; 285 //! Framebuffer support 286 FramebufferSupport m_framebufferSupport = FBS_NONE; 287 //! Map of saved VBO objects 288 std::map<unsigned int, VboObjectInfo> m_vboObjects; 289 //! Last ID of VBO object 290 unsigned int m_lastVboId = 0; 291 292 //! true means shadow mapping is enabled 293 bool m_shadowMapping = false; 294 //! true means that quality shadows are enabled 295 bool m_shadowQuality = true; 296 297 298 //! Pointers to OpenGL functions 299 PFNGLGENBUFFERSPROC m_glGenBuffers = nullptr; 300 PFNGLDELETEBUFFERSPROC m_glDeleteBuffers = nullptr; 301 PFNGLBINDBUFFERPROC m_glBindBuffer = nullptr; 302 PFNGLBUFFERDATAPROC m_glBufferData = nullptr; 303 PFNGLBUFFERSUBDATAPROC m_glBufferSubData = nullptr; 304 }; 305 306 307 } // namespace Gfx 308