1 #pragma once
2 
3 #include "lc_array.h"
4 #include "lc_math.h"
5 #include "lc_colors.h"
6 #include "lc_mesh.h"
7 
8 class lcVertexBuffer
9 {
10 public:
lcVertexBuffer()11 	constexpr lcVertexBuffer()
12 		: Pointer(nullptr)
13 	{
14 	}
15 
IsValid()16 	bool IsValid() const
17 	{
18 		return Pointer != nullptr;
19 	}
20 
21 	union
22 	{
23 		GLuint Object;
24 		void* Pointer;
25 	};
26 };
27 
28 class lcIndexBuffer
29 {
30 public:
lcIndexBuffer()31 	constexpr lcIndexBuffer()
32 		: Pointer(nullptr)
33 	{
34 	}
35 
IsValid()36 	bool IsValid() const
37 	{
38 		return Pointer != nullptr;
39 	}
40 
41 	union
42 	{
43 		GLuint Object;
44 		void* Pointer;
45 	};
46 };
47 
48 enum class lcMaterialType
49 {
50 	UnlitColor,
51 	UnlitColorConditional,
52 	UnlitTextureModulate,
53 	UnlitTextureDecal,
54 	UnlitVertexColor,
55 	UnlitViewSphere,
56 	FakeLitColor,
57 	FakeLitTextureDecal,
58 	Count
59 };
60 
61 enum class lcProgramAttrib
62 {
63 	Position,
64 	Normal,
65 	TexCoord,
66 	Color,
67 	ControlPoint1 = 0,
68 	ControlPoint2,
69 	ControlPoint3,
70 	ControlPoint4,
71 	Count
72 };
73 
74 struct lcProgram
75 {
76 	GLuint Object;
77 	GLint WorldViewProjectionMatrixLocation;
78 	GLint WorldMatrixLocation;
79 	GLint MaterialColorLocation;
80 	GLint LightPositionLocation;
81 	GLint EyePositionLocation;
82 	GLint HighlightParamsLocation;
83 };
84 
85 enum class lcPolygonOffset
86 {
87 	None,
88 	Opaque,
89 	Translucent
90 };
91 
92 enum class lcDepthFunction
93 {
94 	LessEqual,
95 	Always
96 };
97 
98 struct lcVertexAttribState
99 {
100 	GLint Size = 0;
101 	GLenum Type = 0;
102 	GLboolean Normalized = 0;
103 	bool Enabled = 0;
104 	GLsizei Stride = 0;
105 	const void* Pointer = nullptr;
106 	GLuint VertexBufferObject = 0;
107 };
108 
109 class lcContext : protected QOpenGLFunctions
110 {
111 public:
112 	lcContext();
113 	~lcContext();
114 
115 	lcContext(const lcContext&) = delete;
116 	lcContext& operator=(const lcContext&) = delete;
117 
118 	static bool InitializeRenderer();
119 	static void ShutdownRenderer();
120 	static lcContext* GetGlobalOffscreenContext();
121 
122 	void CreateResources();
123 	void DestroyResources();
124 
125 	void SetDefaultState();
126 	void ClearResources();
127 
128 	void MakeCurrent();
129 
130 	void SetGLContext(QOpenGLContext* GLContext, QOpenGLWidget* Widget);
131 	void SetOffscreenContext();
132 
133 	void ClearColorAndDepth(const lcVector4& ClearColor);
134 	void ClearDepth();
135 
SetWorldMatrix(const lcMatrix44 & WorldMatrix)136 	void SetWorldMatrix(const lcMatrix44& WorldMatrix)
137 	{
138 		mWorldMatrix = WorldMatrix;
139 		mWorldMatrixDirty = true;
140 	}
141 
SetViewMatrix(const lcMatrix44 & ViewMatrix)142 	void SetViewMatrix(const lcMatrix44& ViewMatrix)
143 	{
144 		mViewMatrix = ViewMatrix;
145 		mViewMatrixDirty = true;
146 		mViewProjectionMatrixDirty = true;
147 	}
148 
SetProjectionMatrix(const lcMatrix44 & ProjectionMatrix)149 	void SetProjectionMatrix(const lcMatrix44& ProjectionMatrix)
150 	{
151 		mProjectionMatrix = ProjectionMatrix;
152 		mProjectionMatrixDirty = true;
153 		mViewProjectionMatrixDirty = true;
154 	}
155 
GetProjectionMatrix()156 	const lcMatrix44& GetProjectionMatrix()
157 	{
158 		return mProjectionMatrix;
159 	}
160 
161 	void SetMaterial(lcMaterialType MaterialType);
162 	void SetViewport(int x, int y, int Width, int Height);
163 	void SetPolygonOffset(lcPolygonOffset PolygonOffset);
164 	void SetDepthWrite(bool Enable);
165 	void SetDepthFunction(lcDepthFunction DepthFunction);
166 	void EnableCullFace(bool Enable);
167 	void SetLineWidth(float LineWidth);
168 	void SetSmoothShading(bool Smooth);
169 	void BindTexture2D(GLuint Texture);
170 	void BindTextureCubeMap(GLuint Texture);
171 	void UnbindTexture2D(GLuint Texture);
172 	void UnbindTextureCubeMap(GLuint Texture);
173 
SetColor(const lcVector4 & Color)174 	void SetColor(const lcVector4& Color)
175 	{
176 		mColor = Color;
177 		mColorDirty = true;
178 	}
179 
SetHighlightParams(const lcVector4 & HighlightPosition,const lcVector4 & TextColor,const lcVector4 & BackgroundColor,const lcVector4 & HighlightColor)180 	void SetHighlightParams(const lcVector4& HighlightPosition, const lcVector4& TextColor, const lcVector4& BackgroundColor, const lcVector4& HighlightColor)
181 	{
182 		mHighlightParams[0] = HighlightPosition;
183 		mHighlightParams[1] = TextColor;
184 		mHighlightParams[2] = BackgroundColor;
185 		mHighlightParams[3] = HighlightColor;
186 		mHighlightParamsDirty = true;
187 	}
188 
189 	void SetColor(float Red, float Green, float Blue, float Alpha);
190 	void SetColorIndex(int ColorIndex);
191 	void SetColorIndexTinted(int ColorIndex, lcInterfaceColor InterfaceColor, float Weight);
192 	void SetColorIndexTinted(int ColorIndex, const lcVector4& Tint);
193 	void SetEdgeColorIndex(int ColorIndex);
194 	void SetEdgeColorIndexTinted(int ColorIndex, const lcVector4& Tint);
195 	void SetInterfaceColor(lcInterfaceColor InterfaceColor);
196 
197 	lcVertexBuffer CreateVertexBuffer(int Size, const void* Data);
198 	void DestroyVertexBuffer(lcVertexBuffer& VertexBuffer);
199 	lcIndexBuffer CreateIndexBuffer(int Size, const void* Data);
200 	void DestroyIndexBuffer(lcIndexBuffer& IndexBuffer);
201 
202 	void ClearVertexBuffer();
203 	void SetVertexBuffer(lcVertexBuffer VertexBuffer);
204 	void SetVertexBufferPointer(const void* VertexBuffer);
205 
206 	void ClearIndexBuffer();
207 	void SetIndexBuffer(lcIndexBuffer IndexBuffer);
208 	void SetIndexBufferPointer(const void* IndexBuffer);
209 
210 	void SetVertexFormat(int BufferOffset, int PositionSize, int NormalSize, int TexCoordSize, int ColorSize, bool EnableNormals);
211 	void SetVertexFormatPosition(int PositionSize);
212 	void SetVertexFormatConditional(int BufferOffset);
213 	void DrawPrimitives(GLenum Mode, GLint First, GLsizei Count);
214 	void DrawIndexedPrimitives(GLenum Mode, GLsizei Count, GLenum Type, int Offset);
215 
216 	void BindMesh(const lcMesh* Mesh);
217 
218 protected:
219 	static bool CreateOffscreenContext();
220 	static void DestroyOffscreenContext();
221 
222 	void CreateShaderPrograms();
223 	void FlushState();
224 
225 	void SetVertexAttribPointer(lcProgramAttrib Attrib, GLint Size, GLenum Type, GLboolean Normalized, GLsizei Stride, const void* Pointer);
226 	void EnableVertexAttrib(lcProgramAttrib Attrib);
227 	void DisableVertexAttrib(lcProgramAttrib Attrib);
228 
229 	QOpenGLWidget* mWidget = nullptr;
230 	QOpenGLContext* mContext = nullptr;
231 
232 	GLuint mVertexBufferObject;
233 	GLuint mIndexBufferObject;
234 	const char* mVertexBufferPointer;
235 	const char* mIndexBufferPointer;
236 	const char* mVertexBufferOffset;
237 
238 	lcMaterialType mMaterialType;
239 	bool mNormalEnabled;
240 	bool mTexCoordEnabled;
241 	bool mColorEnabled;
242 
243 	lcVertexAttribState mVertexAttribState[static_cast<int>(lcProgramAttrib::Count)];
244 
245 	GLuint mTexture2D;
246 	GLuint mTextureCubeMap;
247 	lcPolygonOffset mPolygonOffset;
248 	bool mDepthWrite;
249 	lcDepthFunction mDepthFunction;
250 	bool mCullFace;
251 	float mLineWidth;
252 	int mMatrixMode;
253 	bool mTextureEnabled;
254 
255 	lcVector4 mColor;
256 	lcMatrix44 mWorldMatrix;
257 	lcMatrix44 mViewMatrix;
258 	lcMatrix44 mProjectionMatrix;
259 	lcMatrix44 mViewProjectionMatrix;
260 	lcVector4 mHighlightParams[4];
261 	bool mColorDirty;
262 	bool mWorldMatrixDirty;
263 	bool mViewMatrixDirty;
264 	bool mProjectionMatrixDirty;
265 	bool mViewProjectionMatrixDirty;
266 	bool mHighlightParamsDirty;
267 
268 	static std::unique_ptr<QOpenGLContext> mOffscreenContext;
269 	static std::unique_ptr<QOffscreenSurface> mOffscreenSurface;
270 	static std::unique_ptr<lcContext> mGlobalOffscreenContext;
271 
272 	static lcProgram mPrograms[static_cast<int>(lcMaterialType::Count)];
273 
274 	Q_DECLARE_TR_FUNCTIONS(lcContext);
275 };
276 
277