summaryrefslogtreecommitdiff
path: root/Runtime/Graphics/RenderCommands.h
blob: ecb0904a05e00790c9bbccbf9c248077f9c5c56f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#pragma once
#include "OpenGL.h"
#include <vector>

struct RenderCommand
{
	virtual void Execute() = 0;
};

typedef std::vector<RenderCommand*> RenderCommandGroup;
void ReleaseRenderCommandGroup(RenderCommandGroup& group);

// Cull Off|Front|Back|Both
struct Cmd_Cull : RenderCommand
{
	enum ECullFace {
		Cull_Disable, 
		Cull_Front,
		Cull_Back,
		Cull_Both,
	};

	ECullFace cull;

	void Execute() override
	{
		if (cull == ECullFace::Cull_Disable)
		{
			glDisable(GL_CULL_FACE);
			return;
		}
		glEnable(GL_CULL_FACE);
		switch (cull)
		{
			case ECullFace::Cull_Front: glCullFace(GL_FRONT); break;
			case ECullFace::Cull_Back: glCullFace(GL_BACK); break;
			case ECullFace::Cull_Both: glCullFace(GL_FRONT_AND_BACK); break;
		}
	}
};

// Blend Off
// Blend <srcFac> <dstFac>
struct Cmd_Blend : RenderCommand
{
	enum EBlend
	{
		Blend_Zero,						// 0
		Blend_One,						// 1
		Blend_Src_Color,				// 源颜色向量C¯source
		Blend_One_Minus_Src_Color,		//  1−C¯source
		Blend_Dst_Color,				// 目标颜色向量C¯destination
		Blend_One_Minus_Dst_Color,		//  1−C¯destination
		Blend_Src_Alpha,				// C¯source的alpha值
		Blend_One_Minus_Src_Alpha,		//  1− C¯source的alpha值
		Blend_Dst_Alpha,				//  C¯destination的alpha值
		Blend_One_Minus_Dst_Alpha,		//  1− C¯destination的alpha值
		Blend_Constant_Color,			// 常颜色向量C¯constant
		Blend_One_Minus_Constant_Color,	// 1−C¯constant
		Blend_Constant_Alpha,			// C¯constant的alpha值
		Blend_One_Minus_Constant_Alpha,	// 1− C¯constant的alpha值
	};

	bool enable;
	EBlend srcFac;
	EBlend dstFac;

	void Execute() override
	{
		if (!enable)
			glDisable(GL_BLEND);
		glEnable(GL_BLEND);
        glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
		GLenum src, dst;
		switch (srcFac)
		{
			case EBlend::Blend_Zero: src = GL_ZERO; break;
			case EBlend::Blend_One: src = GL_ONE; break;
			case EBlend::Blend_Src_Color: src = GL_SRC_COLOR; break;
			case EBlend::Blend_One_Minus_Src_Color: src = GL_ONE_MINUS_SRC_COLOR; break;
			case EBlend::Blend_Dst_Color: src = GL_DST_COLOR; break;
			case EBlend::Blend_One_Minus_Dst_Color: src = GL_ONE_MINUS_DST_COLOR; break;
			case EBlend::Blend_Src_Alpha: src = GL_SRC_ALPHA; break;
			case EBlend::Blend_One_Minus_Src_Alpha: src = GL_ONE_MINUS_SRC_ALPHA; break;
			case EBlend::Blend_Dst_Alpha: src = GL_DST_ALPHA; break;
			case EBlend::Blend_One_Minus_Dst_Alpha: src = GL_ONE_MINUS_DST_ALPHA; break;
			case EBlend::Blend_Constant_Color: src = GL_CONSTANT_COLOR; break;
			case EBlend::Blend_One_Minus_Constant_Color: src = GL_ONE_MINUS_CONSTANT_COLOR; break;
			case EBlend::Blend_Constant_Alpha: src = GL_CONSTANT_ALPHA; break;
			case EBlend::Blend_One_Minus_Constant_Alpha: src = GL_ONE_MINUS_CONSTANT_ALPHA; break;
		}
		switch (dstFac)
		{
			case EBlend::Blend_Zero: dst = GL_ZERO; break;
			case EBlend::Blend_One: dst = GL_ONE; break;
			case EBlend::Blend_Src_Color: dst = GL_SRC_COLOR; break;
			case EBlend::Blend_One_Minus_Src_Color: dst = GL_ONE_MINUS_SRC_COLOR; break;
			case EBlend::Blend_Dst_Color: dst = GL_DST_COLOR; break;
			case EBlend::Blend_One_Minus_Dst_Color: dst = GL_ONE_MINUS_DST_COLOR; break;
			case EBlend::Blend_Src_Alpha: dst = GL_SRC_ALPHA; break;
			case EBlend::Blend_One_Minus_Src_Alpha: dst = GL_ONE_MINUS_SRC_ALPHA; break;
			case EBlend::Blend_Dst_Alpha: dst = GL_DST_ALPHA; break;
			case EBlend::Blend_One_Minus_Dst_Alpha: dst = GL_ONE_MINUS_DST_ALPHA; break;
			case EBlend::Blend_Constant_Color: dst = GL_CONSTANT_COLOR; break;
			case EBlend::Blend_One_Minus_Constant_Color: dst = GL_ONE_MINUS_CONSTANT_COLOR; break;
			case EBlend::Blend_Constant_Alpha: dst = GL_CONSTANT_ALPHA; break;
			case EBlend::Blend_One_Minus_Constant_Alpha: dst = GL_ONE_MINUS_CONSTANT_ALPHA; break;
		}
		glBlendFunc(src, dst);
	}
};

// DepthTest Off|<func>
struct Cmd_DepthTest : RenderCommand
{
	enum EDepthTest
	{
		DepthTest_Off,      // 不进行深度测试
		DepthTest_Always,   // 永远通过测试
		DepthTest_Never,    // 永远不通过测试
		DepthTest_Less,	    // 在片段深度值小于缓冲区的深度时通过测试
		DepthTest_Equal,    // 在片段深度值等于缓冲区的深度时通过测试
		DepthTest_Lequal,   // 在片段深度值小于等于缓冲区的深度时通过测试
		DepthTest_Greater,  // 在片段深度值大于缓冲区的深度时通过测试
		DepthTest_Notequal, // 在片段深度值不等于缓冲区的深度时通过测试
		DepthTest_Gequal,   // 在片段深度值大于等于缓冲区的深度时通过测试
	};

	EDepthTest test;

	void Execute() override
	{
		if (test == EDepthTest::DepthTest_Off)
		{
			glDisable(GL_DEPTH_TEST);
			return;
		}
		glEnable(GL_DEPTH_TEST);
		switch (test)
		{
			case EDepthTest::DepthTest_Always:    glDepthFunc(GL_ALWAYS); break;
			case EDepthTest::DepthTest_Never:	  glDepthFunc(GL_NEVER); break;
			case EDepthTest::DepthTest_Less:	  glDepthFunc(GL_LESS); break;
			case EDepthTest::DepthTest_Equal:	  glDepthFunc(GL_EQUAL); break;
			case EDepthTest::DepthTest_Lequal:	  glDepthFunc(GL_LEQUAL); break;
			case EDepthTest::DepthTest_Greater:	  glDepthFunc(GL_GREATER); break;
			case EDepthTest::DepthTest_Notequal:  glDepthFunc(GL_NOTEQUAL); break;
			case EDepthTest::DepthTest_Gequal:	  glDepthFunc(GL_GEQUAL); break;
		}
	}
};

// DepthWrite Off|On
struct Cmd_DepthWrite : RenderCommand
{
	bool write;
	void Execute() override
	{
		if(write)
			glDepthMask(GL_TRUE);
		else 
			glDepthMask(GL_FALSE);
	}
};