1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 
17 #ifndef C4LANDSCAPE_RENDER_H
18 #define C4LANDSCAPE_RENDER_H
19 
20 #include "C4ForbidLibraryCompilation.h"
21 #include "graphics/C4FacetEx.h"
22 #include "graphics/C4Shader.h"
23 #include "graphics/C4Surface.h"
24 
25 #include <chrono>
26 
27 // Data we want to store per landscape pixel
28 enum C4LR_Byte {
29 	C4LR_Material,
30 	C4LR_BiasX,
31 	C4LR_BiasY,
32 	C4LR_Scaler,
33 	C4LR_Place,
34 
35 	C4LR_ByteCount
36 };
37 
38 // Uniform data we give the shader (constants from its viewpoint)
39 // Don't forget to update GetUniformName when introducing new uniforms!
40 enum C4LR_Uniforms
41 {
42 	C4LRU_ProjectionMatrix,
43 
44 	C4LRU_LandscapeTex,
45 	C4LRU_ScalerTex,
46 	C4LRU_MaterialTex,
47 	C4LRU_LightTex,
48 	C4LRU_AmbientTex,
49 
50 	C4LRU_Gamma,
51 	C4LRU_Resolution,
52 	C4LRU_Center,
53 	C4LRU_MatMapTex,
54 	C4LRU_MaterialDepth,
55 	C4LRU_MaterialSize,
56 	C4LRU_AmbientBrightness,
57 	C4LRU_AmbientTransform,
58 	C4LRU_Modulation,
59 
60 	C4LRU_FrameCounter,
61 	C4LRU_Time,
62 
63 	C4LRU_Count
64 };
65 
66 enum C4LR_Attributes
67 {
68 	C4LRA_Position,
69 	C4LRA_LandscapeTexCoord,
70 	C4LRA_LightTexCoord,
71 
72 	C4LRA_Count
73 };
74 
75 // How much data we want to store per landscape pixel
76 const int C4LR_BytesPerPx = 3;
77 
78 // How much data we can hold per surface, how much surfaces we therefore need.
79 const int C4LR_BytesPerSurface = 4;
80 const int C4LR_SurfaceCount = (C4LR_ByteCount + C4LR_BytesPerSurface - 1) / C4LR_BytesPerSurface;
81 
82 class C4Landscape; class C4TextureMap;
83 
84 class C4LandscapeRender
85 {
86 public:
87 	C4LandscapeRender() = default;
88 	virtual ~C4LandscapeRender() = default;
89 
90 protected:
91 	int32_t iWidth{0}, iHeight{0};
92 	C4TextureMap *pTexs{nullptr};
93 
94 public:
95 
96 	virtual bool ReInit(int32_t iWidth, int32_t iHeight) = 0;
97 	virtual bool Init(int32_t iWidth, int32_t iHeight, C4TextureMap *pTexs, C4GroupSet *pGraphics) = 0;
98 	virtual void Clear() = 0;
99 
100 	// Returns the rectangle of pixels that must be updated on changes in the given rect
101 	virtual C4Rect GetAffectedRect(C4Rect Rect) = 0;
102 
103 	// Updates the landscape rendering to reflect the landscape contents in
104 	// the given rectangle
105 	virtual void Update(C4Rect Rect, C4Landscape *pSource) = 0;
106 
107 	virtual void Draw(const C4TargetFacet &cgo, const class C4FoWRegion *Light, uint32_t clrMod) = 0;
108 };
109 
110 #ifndef USE_CONSOLE
111 class C4LandscapeRenderGL : public C4LandscapeRender
112 {
113 public:
114 	C4LandscapeRenderGL();
115 	~C4LandscapeRenderGL() override;
116 
117 private:
118 	// surfaces
119 	C4Surface *Surfaces[C4LR_SurfaceCount];
120 
121 	// shader
122 	C4Shader Shader;
123 	C4Shader ShaderLight;
124 	static const char *UniformNames[];
125 	// VBO for landscape vertex data
126 	GLuint hVBO;
127 	// VAO IDs for rendering landscape w/ and w/o light
128 	unsigned int hVAOIDNoLight;
129 	unsigned int hVAOIDLight;
130 
131 	// 1D texture for material map
132 	GLuint matMapTexture;
133 	// 2D texture array of material textures
134 	GLuint hMaterialTexture;
135 	// material texture positions in texture array
136 	std::vector<StdCopyStrBuf> MaterialTextureMap;
137 	// depth of material texture in layers
138 	int32_t iMaterialTextureDepth;
139 	// size of material textures (unzoomed)
140 	int32_t iMaterialWidth, iMaterialHeight;
141 
142 	// scaler image
143 	C4FacetSurface fctScaler;
144 
145 	// shader timer
146 	std::chrono::time_point<std::chrono::steady_clock> TimerStart;
147 
148 public:
149 	bool ReInit(int32_t iWidth, int32_t iHeight) override;
150 	bool Init(int32_t iWidth, int32_t iHeight, C4TextureMap *pMap, C4GroupSet *pGraphics) override;
151 	void Clear() override;
152 
153 	C4Rect GetAffectedRect(C4Rect Rect) override;
154 	void Update(C4Rect Rect, C4Landscape *pSource) override;
155 
156 	void Draw(const C4TargetFacet &cgo, const C4FoWRegion *Light, uint32_t clrMod) override;
157 
158 private:
159 	bool InitLandscapeTexture();
160 	bool InitMaterialTexture(C4TextureMap *pMap);
161 	bool LoadShader(C4GroupSet *pGraphics, C4Shader& shader, const char* name, int ssc);
162 	bool LoadShaders(C4GroupSet *pGraphics);
163 	bool InitVBO();
164 	void ClearShaders();
165 	bool LoadScaler(C4GroupSet *pGraphics);
166 
167 	int CalculateScalerBitmask(int x, int y, C4Rect To, C4Landscape *pSource);
168 
169 	int32_t LookupTextureTransition(const char *szFrom, const char *szTo);
170 	void AddTextureTransition(const char *szFrom, const char *szTo);
171 	void AddTextureAnim(const char *szTextureAnim);
172 	void AddTexturesFromMap(C4TextureMap *pMap);
173 	void BuildMatMap(uint32_t *pTex);
174 };
175 #endif
176 
177 #endif // C4LANDSCAPE_RENDER_H
178