1 /*
2  Copyright (c) 2013 yvt
3 
4  This file is part of OpenSpades.
5 
6  OpenSpades 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  OpenSpades 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.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OpenSpades.  If not, see <http://www.gnu.org/licenses/>.
18 
19  */
20 
21 #include "GLModelRenderer.h"
22 #include <Core/Debug.h>
23 #include "GLModel.h"
24 #include "GLProfiler.h"
25 #include "GLRenderer.h"
26 
27 namespace spades {
28 	namespace draw {
GLModelRenderer(GLRenderer * r)29 		GLModelRenderer::GLModelRenderer(GLRenderer *r) : device(r->GetGLDevice()), renderer(r) {
30 			SPADES_MARK_FUNCTION();
31 			modelCount = 0;
32 		}
33 
~GLModelRenderer()34 		GLModelRenderer::~GLModelRenderer() {
35 			SPADES_MARK_FUNCTION();
36 			Clear();
37 		}
38 
AddModel(GLModel * model,const client::ModelRenderParam & param)39 		void GLModelRenderer::AddModel(GLModel *model, const client::ModelRenderParam &param) {
40 			SPADES_MARK_FUNCTION();
41 			if (model->renderId == -1) {
42 				model->renderId = (int)models.size();
43 				RenderModel m;
44 				m.model = model;
45 				model->AddRef();
46 				models.push_back(m);
47 			}
48 			modelCount++;
49 			models[model->renderId].params.push_back(param);
50 		}
51 
RenderShadowMapPass()52 		void GLModelRenderer::RenderShadowMapPass() {
53 			SPADES_MARK_FUNCTION();
54 
55 			GLProfiler::Context profiler(renderer->GetGLProfiler(), "Model [%d model(s), %d unique model type(s)]", modelCount,
56 			                    (int)models.size());
57 
58 			int numModels = 0;
59 			for (size_t i = 0; i < models.size(); i++) {
60 				RenderModel &m = models[i];
61 				GLModel *model = m.model;
62 				model->RenderShadowMapPass(m.params);
63 				numModels += (int)m.params.size();
64 			}
65 #if 0
66 			printf("Model types: %d, Number of models: %d\n",
67 				   (int)models.size(), numModels);
68 #endif
69 		}
70 
Prerender()71 		void GLModelRenderer::Prerender() {
72 			device->ColorMask(false, false, false, false);
73 
74 			GLProfiler::Context profiler(renderer->GetGLProfiler(), "Model [%d model(s), %d unique model type(s)]", modelCount,
75 								(int)models.size());
76 
77 			int numModels = 0;
78 			for (size_t i = 0; i < models.size(); i++) {
79 				RenderModel &m = models[i];
80 				GLModel *model = m.model;
81 				model->Prerender(m.params);
82 				numModels += (int)m.params.size();
83 			}
84 			device->ColorMask(true, true, true, true);
85 		}
86 
RenderSunlightPass()87 		void GLModelRenderer::RenderSunlightPass() {
88 			SPADES_MARK_FUNCTION();
89 
90 			GLProfiler::Context profiler(renderer->GetGLProfiler(), "Model [%d model(s), %d unique model type(s)]", modelCount,
91 			                    (int)models.size());
92 
93 			for (size_t i = 0; i < models.size(); i++) {
94 				RenderModel &m = models[i];
95 				GLModel *model = m.model;
96 
97 				model->RenderSunlightPass(m.params);
98 			}
99 		}
100 
RenderDynamicLightPass(std::vector<GLDynamicLight> lights)101 		void GLModelRenderer::RenderDynamicLightPass(std::vector<GLDynamicLight> lights) {
102 			SPADES_MARK_FUNCTION();
103 
104 			GLProfiler::Context profiler(renderer->GetGLProfiler(), "Model [%d model(s), %d unique model type(s)]", modelCount,
105 			                    (int)models.size());
106 
107 			if (!lights.empty()) {
108 
109 				for (size_t i = 0; i < models.size(); i++) {
110 					RenderModel &m = models[i];
111 					GLModel *model = m.model;
112 
113 					model->RenderDynamicLightPass(m.params, lights);
114 				}
115 			}
116 		}
117 
Clear()118 		void GLModelRenderer::Clear() {
119 			// last phase: clear scene
120 			for (size_t i = 0; i < models.size(); i++) {
121 				models[i].model->renderId = -1;
122 				models[i].model->Release();
123 			}
124 			models.clear();
125 
126 			modelCount = 0;
127 		}
128 	}
129 }
130