7a197fa97d157286a68a7ad9461e100335e2b5de
[tar-legacy.git] / MCDV / main2.cpp
1 #include "globals.h"
2 #include "vmf_new.hpp"
3
4 #ifdef entry_point_testing
5
6 #include <glad\glad.h>
7 #include <GLFW\glfw3.h>
8
9 #include <glm\glm.hpp>
10 #include <glm\gtc\matrix_transform.hpp>
11 #include <glm\gtc\type_ptr.hpp>
12
13 #include <iostream>
14 #include <vector>
15
16 #include "GBuffer.hpp"
17 #include "Shader.hpp"
18 #include "Mesh.hpp"
19 #include "Texture.hpp"
20 #include "GradientMap.hpp"
21 #include "SSAOKernel.hpp"
22 #include "tar_config.hpp"
23 #include "dds.hpp"
24
25 #include "cxxopts.hpp"
26
27 #define STB_IMAGE_WRITE_IMPLEMENTATION
28 #define STBI_MSC_SECURE_CRT
29 #include "stb_image_write.h"
30
31 #define TAR_MAX_LAYERS 5
32 #define TAR_AO_SAMPLES 256
33
34 std::string g_game_path = "D:/SteamLibrary/steamapps/common/Counter-Strike Global Offensive/csgo";
35 std::string g_mapfile_path = "sample_stuff/de_tavr_test";
36 std::string g_mapname;
37 std::string g_mapfile_name;
38 std::string g_folder_overviews;
39 std::string g_folder_resources;
40
41 bool g_onlyMasks = false;
42 bool g_Masks = false;
43
44 void render_config(tar_config_layer layer, const std::string& layerName, FBuffer* drawTarget = NULL);
45
46 //glm::mat4 g_mat4_viewm;
47 //glm::mat4 g_mat4_projm;
48
49 Shader* g_shader_gBuffer;
50 Shader* g_shader_iBuffer;
51 Shader* g_shader_comp;
52 Shader* g_shader_multilayer_blend;
53 Shader* g_shader_multilayer_final;
54 Shader* g_shader_fxaa;
55 Shader* g_shader_msaa;
56
57 GBuffer* g_gbuffer;
58 GBuffer* g_gbuffer_clean;
59 MBuffer* g_mask_playspace;
60 MBuffer* g_mask_buyzone;
61 MBuffer* g_mask_objectives;
62 FBuffer* g_fbuffer_generic;
63 FBuffer* g_fbuffer_generic1;
64
65 vmf* g_vmf_file;
66 tar_config* g_tar_config;
67
68 Mesh* g_mesh_screen_quad;
69 Texture* g_texture_background;
70 Texture* g_texture_modulate;
71 std::vector<glm::vec3> g_ssao_samples;
72 Texture* g_ssao_rotations;
73
74 uint32_t g_renderWidth = 1024;
75 uint32_t g_renderHeight = 1024;
76 uint32_t g_msaa_mul = 1;
77
78 void render_to_png(int x, int y, const char* filepath);
79 void save_to_dds(int x, int y, const char* filepath, IMG imgmode = IMG::MODE_DXT1);
80
81 #define _DEBUG
82
83 int app(int argc, const char** argv) {
84 #ifndef _DEBUG
85 #pragma region cxxopts
86 cxxopts::Options options("AutoRadar", "Auto radar");
87 options.add_options()
88 ("v,version", "Shows the software version")
89 ("g,game", "(REQUIRED) Specify game path", cxxopts::value<std::string>()->default_value(""))
90 ("m,mapfile", "(REQUIRED) Specify the map file (vmf)", cxxopts::value<std::string>()->default_value(""))
91
92 ("d,dumpMasks", "Toggles whether auto radar should output mask images (resources/map_file.resources/)")
93 ("o,onlyMasks", "Specift whether auto radar should only output mask images and do nothing else (resources/map_file.resources)")
94
95 ("positional", "Positional parameters", cxxopts::value<std::vector<std::string>>());
96
97 options.parse_positional("positional");
98 auto result = options.parse(argc, argv);
99
100 /* Check required parameters */
101 if (result.count("game")) g_game_path = sutil::ReplaceAll(result["game"].as<std::string>(), "\n", "");
102 else throw cxxopts::option_required_exception("game");
103
104 if (result.count("mapfile")) g_mapfile_path = result["mapfile"].as<std::string>();
105 else if (result.count("positional")) {
106 auto& positional = result["positional"].as<std::vector<std::string>>();
107
108 g_mapfile_path = sutil::ReplaceAll(positional[0], "\n", "");
109 }
110 else throw cxxopts::option_required_exception("mapfile"); // We need a map file
111
112 //Clean paths to what we can deal with
113 g_mapfile_path = sutil::ReplaceAll(g_mapfile_path, "\\", "/");
114 g_game_path = sutil::ReplaceAll(g_game_path, "\\", "/");
115
116 /* Check the rest of the flags */
117 g_onlyMasks = result["onlyMasks"].as<bool>();
118 g_Masks = result["dumpMasks"].as<bool>() || g_onlyMasks;
119
120 /* Render options */
121 //m_renderWidth = result["width"].as<uint32_t>();
122 //m_renderHeight = result["height"].as<uint32_t>();
123 #pragma endregion
124 #endif
125
126 g_mapfile_name = split(g_mapfile_path, '/').back();
127 g_folder_overviews = g_game_path + "/resource/overviews/";
128 g_folder_resources = g_folder_overviews + g_mapfile_name + ".resources/";
129
130 #pragma region opengl_setup
131 glfwInit();
132 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
133 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
134 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
135 glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
136
137 glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
138
139 GLFWwindow* window = glfwCreateWindow(g_renderWidth, g_renderHeight, "Ceci n'est pas une window", NULL, NULL);
140
141 if (window == NULL) {
142 printf("GLFW died\n");
143 glfwTerminate();
144 return -1;
145 }
146
147 glfwMakeContextCurrent(window);
148
149 // Deal with GLAD
150 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
151 printf("GLAD died\n");
152 return -1;
153 }
154
155 const unsigned char* glver = glGetString(GL_VERSION);
156 printf("(required: min core 3.3.0) opengl version: %s\n", glver);
157 #pragma endregion
158
159 vfilesys* filesys = new vfilesys(g_game_path + "/gameinfo.txt");
160
161 vmf::LinkVFileSystem(filesys);
162 g_vmf_file = vmf::from_file(g_mapfile_path + ".vmf");
163 g_vmf_file->InitModelDict();
164 g_tar_config = new tar_config(g_vmf_file);
165
166 #pragma region opengl_extra
167
168 std::vector<float> __meshData = {
169 -1, -1,
170 -1, 1,
171 1, -1,
172 -1, 1,
173 1, 1,
174 1, -1
175 };
176 g_mesh_screen_quad = new Mesh(__meshData, MeshMode::SCREEN_SPACE_UV);
177
178 // Set up shaders
179 g_shader_gBuffer = new Shader("shaders/gBuffer.vs", "shaders/gBuffer.fs");
180 g_shader_iBuffer = new Shader("shaders/gBuffer.vs", "shaders/iBuffer.fs");
181 g_shader_comp = new Shader("shaders/fullscreenbase.vs", "shaders/fullscreenbase.fs");
182 g_shader_multilayer_blend = new Shader("shaders/fullscreenbase.vs", "shaders/ss_comp_multilayer_blend.fs");
183 g_shader_multilayer_final = new Shader("shaders/fullscreenbase.vs", "shaders/ss_comp_multilayer_finalstage.fs");
184 g_shader_fxaa = new Shader("shaders/fullscreenbase.vs", "shaders/ss_fxaa.fs");
185 g_shader_msaa = new Shader("shaders/fullscreenbase.vs", "shaders/ss_msaa.fs");
186
187 if(g_tar_config->m_sampling_mode == sampling_mode::MSAA4x ||
188 g_tar_config->m_sampling_mode == sampling_mode::MSAA16x)
189 g_msaa_mul = g_tar_config->m_sampling_mode;
190
191 // Set up draw buffers
192 g_mask_playspace = new MBuffer(g_renderWidth * g_msaa_mul, g_renderHeight * g_msaa_mul);
193 g_mask_objectives = new MBuffer(g_renderWidth * g_msaa_mul, g_renderHeight * g_msaa_mul);
194 g_mask_buyzone = new MBuffer(g_renderWidth * g_msaa_mul, g_renderHeight * g_msaa_mul);
195 g_gbuffer = new GBuffer(g_renderWidth * g_msaa_mul, g_renderHeight * g_msaa_mul);
196 g_gbuffer_clean = new GBuffer(g_renderWidth * g_msaa_mul, g_renderHeight * g_msaa_mul);
197 g_fbuffer_generic = new FBuffer(g_renderWidth * g_msaa_mul, g_renderHeight * g_msaa_mul);
198 g_fbuffer_generic1 =new FBuffer(g_renderWidth * g_msaa_mul, g_renderHeight * g_msaa_mul);
199
200 // Setup camera projection matrices
201 //g_mat4_projm = glm::ortho(-2000.0f, 2000.0f, -2000.0f, 2000.0f, -1024.0f, 1024.0f);
202 //g_mat4_viewm = glm::lookAt(glm::vec3(0, 0, 0), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0, 0, 1));
203
204 // Load textures
205 g_texture_background = g_tar_config->m_texture_background;//new Texture("textures/grid.png");
206 g_texture_modulate = new Texture("textures/modulate.png");
207 g_ssao_samples = get_ssao_samples(TAR_AO_SAMPLES);
208 g_ssao_rotations = new ssao_rotations_texture();
209
210 glEnable(GL_DEPTH_TEST);
211 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
212 glFrontFace(GL_CW);
213
214 #pragma endregion
215
216 #pragma region render
217
218 std::map<tar_config_layer*, FBuffer*> _flayers;
219
220 // Render all map segments
221 int c = 0;
222 for (auto && layer : g_tar_config->layers){
223 _flayers.insert({ &layer, new FBuffer(g_renderWidth, g_renderHeight) });
224 render_config(layer, "layer" + std::to_string(c++) + ".png", _flayers[&layer]);
225 }
226
227 // Render out everything so we got acess to G Buffer info in final composite
228 if(g_tar_config->layers.size() > 1) render_config(tar_config_layer(), "layerx.png", NULL);
229 GBuffer::Unbind();
230
231 glDisable(GL_DEPTH_TEST);
232 glEnable(GL_BLEND);
233 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
234 glBlendEquation(GL_FUNC_ADD);
235
236
237 ///g_gbuffer->BindPositionBufferToTexSlot(0);
238 ///g_shader_multilayer_blend->setInt("gbuffer_position", 0);
239
240 int i = 0;
241 for (auto && megalayer : g_tar_config->layers){
242 g_fbuffer_generic->Bind();
243 glClearColor(0.0, 0.0, 0.0, 0.0);
244 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
245
246 g_shader_multilayer_blend->use();
247 g_shader_multilayer_blend->setInt("tex_layer", 1);
248 g_shader_multilayer_blend->setInt("gbuffer_height", 0);
249 g_shader_multilayer_blend->setFloat("saturation", 0.1f);
250 g_shader_multilayer_blend->setFloat("value", 0.5669f);
251 g_shader_multilayer_blend->setFloat("active", 0.0f);
252
253 for(int x = 0; x < g_tar_config->layers.size(); x++)
254 {
255 tar_config_layer* l = &g_tar_config->layers[g_tar_config->layers.size() - x - 1];
256 if (l == &megalayer) continue;
257
258 _flayers[l]->BindRTToTexSlot(1);
259 _flayers[l]->BindHeightToTexSlot(0);
260
261 g_shader_multilayer_blend->setFloat("layer_min", l->layer_min);
262 g_shader_multilayer_blend->setFloat("layer_max", l->layer_max);
263
264 g_mesh_screen_quad->Draw();
265 }
266
267 g_shader_multilayer_blend->setFloat("layer_min", megalayer.layer_min);
268 g_shader_multilayer_blend->setFloat("layer_max", megalayer.layer_max);
269
270 //g_shader_multilayer_blend->setFloat("saturation", 1.0f);
271 //g_shader_multilayer_blend->setFloat("value", 1.0f);
272 g_shader_multilayer_blend->setFloat("active", 1.0f);
273
274 _flayers[&megalayer]->BindRTToTexSlot(1);
275 _flayers[&megalayer]->BindHeightToTexSlot(0);
276 g_mesh_screen_quad->Draw();
277
278
279 FBuffer::Unbind();
280
281 g_fbuffer_generic1->Bind();
282
283 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
284
285 g_shader_multilayer_final->use();
286 g_shader_multilayer_final->setFloat("blend_outline", g_tar_config->m_outline_enable? 1.0f:0.0f);
287 g_shader_multilayer_final->setVec4("color_outline", g_tar_config->m_color_outline);
288 g_shader_multilayer_final->setInt("outline_width", g_tar_config->m_outline_width * g_msaa_mul);
289
290 g_tar_config->m_texture_background->bindOnSlot(0);
291 g_shader_multilayer_final->setInt("tex_background", 0);
292
293 g_fbuffer_generic->BindRTToTexSlot(1);
294 g_shader_multilayer_final->setInt("tex_layer", 1);
295 g_mesh_screen_quad->Draw();
296
297 // Apply FXAA
298 if (g_tar_config->m_sampling_mode == sampling_mode::FXAA) {
299 FBuffer::Unbind();
300
301 g_shader_fxaa->use();
302 g_shader_fxaa->setInt("sampler0", 0);
303 g_shader_fxaa->setVec2("resolution", glm::vec2(g_renderWidth, g_renderHeight));
304 g_fbuffer_generic1->BindRTToTexSlot(0);
305
306 g_mesh_screen_quad->Draw();
307 }
308 else if (g_tar_config->m_sampling_mode == sampling_mode::MSAA16x
309 || g_tar_config->m_sampling_mode == sampling_mode::MSAA4x)
310 {
311 FBuffer::Unbind();
312
313 g_shader_msaa->use();
314 g_shader_msaa->setInt("sampler0", 0);
315 g_fbuffer_generic1->BindRTToTexSlot(0);
316 g_mesh_screen_quad->Draw();
317 }
318
319 // final composite
320 //render_to_png(1024, 1024, ("comp" + std::to_string(i++) + ".png").c_str());
321 if (i == 0) {
322 save_to_dds(g_renderWidth, g_renderHeight, filesys->create_output_filepath("resource/overviews/" + g_mapfile_name +"_radar.dds", true).c_str(), g_tar_config->m_dds_img_mode);
323 i++;
324 }
325 else {
326 save_to_dds(g_renderWidth, g_renderHeight, filesys->create_output_filepath("resource/overviews/" + g_mapfile_name + "_layer" + std::to_string(i++) + "_radar.dds", true).c_str(), g_tar_config->m_dds_img_mode);
327 }
328 FBuffer::Unbind();
329 }
330
331 #pragma endregion
332
333 std::cout << "Generating radar .TXT... ";
334
335 kv::DataBlock node_radar = kv::DataBlock();
336 node_radar.name = "\"" + g_mapfile_name + "\"";
337 node_radar.Values.insert({ "material", "overviews/" + g_mapfile_name });
338
339 node_radar.Values.insert({ "pos_x", std::to_string(g_tar_config->m_view_origin.x) });
340 node_radar.Values.insert({ "pos_y", std::to_string(g_tar_config->m_view_origin.y) });
341 node_radar.Values.insert({ "scale", std::to_string(g_tar_config->m_render_ortho_scale / g_renderWidth) });
342
343 if (g_tar_config->layers.size() > 1) {
344 kv::DataBlock node_vsections = kv::DataBlock();
345 node_vsections.name = "\"verticalsections\"";
346
347 int ln = 0;
348 for (auto && layer : g_tar_config->layers) {
349 kv::DataBlock node_layer = kv::DataBlock();
350 if (ln == 0) {
351 node_layer.name = "\"default\""; ln++;
352 }
353 else node_layer.name = "\"layer" + std::to_string(ln++) + "\"";
354
355 node_layer.Values.insert({ "AltitudeMin", std::to_string(layer.layer_max) });
356 node_layer.Values.insert({ "AltitudeMax", std::to_string(layer.layer_min) });
357
358 node_vsections.SubBlocks.push_back(node_layer);
359 }
360
361 node_radar.SubBlocks.push_back(node_vsections);
362 }
363
364 // Try resolve spawn positions
365 glm::vec3* loc_spawnCT = g_vmf_file->calculateSpawnAVG_PMIN("info_player_counterterrorist");
366 glm::vec3* loc_spawnT = g_vmf_file->calculateSpawnAVG_PMIN("info_player_terrorist");
367
368 if (loc_spawnCT != NULL) {
369 node_radar.Values.insert({ "CTSpawn_x", std::to_string(util::roundf(remap(loc_spawnCT->x, g_tar_config->m_view_origin.x, g_tar_config->m_view_origin.x + g_tar_config->m_render_ortho_scale, 0.0f, 1.0f), 0.01f)) });
370 node_radar.Values.insert({ "CTSpawn_y", std::to_string(util::roundf(remap(loc_spawnCT->z, g_tar_config->m_view_origin.y, g_tar_config->m_view_origin.y - g_tar_config->m_render_ortho_scale, 0.0f, 1.0f), 0.01f)) });
371 }
372 if (loc_spawnT != NULL) {
373 node_radar.Values.insert({ "TSpawn_x", std::to_string(util::roundf(remap(loc_spawnT->x, g_tar_config->m_view_origin.x, g_tar_config->m_view_origin.x + g_tar_config->m_render_ortho_scale, 0.0f, 1.0f), 0.01f)) });
374 node_radar.Values.insert({ "TSpawn_y", std::to_string(util::roundf(remap(loc_spawnT->z, g_tar_config->m_view_origin.y, g_tar_config->m_view_origin.y - g_tar_config->m_render_ortho_scale, 0.0f, 1.0f), 0.01f)) });
375 }
376
377 int hostn = 1;
378 for (auto && hostage : g_vmf_file->get_entities_by_classname("info_hostage_spawn")) {
379 node_radar.Values.insert({ "Hostage" + std::to_string(hostn) + "_x", std::to_string(util::roundf(remap(hostage->m_origin.x, g_tar_config->m_view_origin.x, g_tar_config->m_view_origin.x + g_tar_config->m_render_ortho_scale, 0.0f, 1.0f), 0.01f)) });
380 node_radar.Values.insert({ "Hostage" + std::to_string(hostn++) + "_y", std::to_string(util::roundf(remap(hostage->m_origin.z, g_tar_config->m_view_origin.y, g_tar_config->m_view_origin.y - g_tar_config->m_render_ortho_scale, 0.0f, 1.0f), 0.01f)) });
381 }
382
383 std::ofstream out(filesys->create_output_filepath("resource/overviews/" + g_mapfile_name + ".txt", true).c_str());
384 out << "// TAVR - AUTO RADAR. v 2.5.0a\n";
385 node_radar.Serialize(out);
386 out.close();
387
388 IL_EXIT:
389 glfwTerminate();
390 #ifdef _DEBUG
391 system("PAUSE");
392 #endif
393 return 0;
394 }
395
396 #endif
397
398 #define __RENDERCLIP
399
400 void render_config(tar_config_layer layer, const std::string& layerName, FBuffer* drawTarget) {
401 // G BUFFER GENERATION ======================================================================================
402 #pragma region buffer_gen_geo
403
404 #ifdef RENDERCLIP
405 glm::mat4 l_mat4_projm = glm::ortho(
406 g_tar_config->m_view_origin.x, // -X
407 g_tar_config->m_view_origin.x + g_tar_config->m_render_ortho_scale, // +X
408 g_tar_config->m_view_origin.y - g_tar_config->m_render_ortho_scale, // -Y
409 g_tar_config->m_view_origin.y, // +Y
410 0.0f, //g_tar_config->m_map_bounds.NWU.y, // NEARZ
411 glm::abs(layer.layer_max - layer.layer_min));// g_tar_config->m_map_bounds.SEL.y); // FARZ
412
413 glm::mat4 l_mat4_viewm = glm::lookAt(
414 glm::vec3(0, -layer.layer_max, 0),
415 glm::vec3(0.0f, -layer.layer_max -1.0f, 0.0f),
416 glm::vec3(0, 0, 1));
417
418 g_vmf_file->SetMinMax(10000, -10000);
419 #else
420 glm::mat4 l_mat4_projm = glm::ortho(
421 g_tar_config->m_view_origin.x, // -X
422 g_tar_config->m_view_origin.x + g_tar_config->m_render_ortho_scale, // +X
423 g_tar_config->m_view_origin.y - g_tar_config->m_render_ortho_scale, // -Y
424 g_tar_config->m_view_origin.y, // +Y
425 -10000.0f, //g_tar_config->m_map_bounds.NWU.y, // NEARZ
426 10000.0f);// g_tar_config->m_map_bounds.SEL.y); // FARZ
427
428 glm::mat4 l_mat4_viewm = glm::lookAt(
429 glm::vec3(0, 0, 0),
430 glm::vec3(0.0f, -1.0f, 0.0f),
431 glm::vec3(0, 0, 1));
432
433 std::cout << "v" << layer.layer_min << "\n";
434 std::cout << "^" << layer.layer_max << "\n";
435
436 g_vmf_file->SetMinMax(layer.layer_min, layer.layer_max);
437 #endif
438
439 g_gbuffer->Bind();
440
441 glClearColor(-10000.0, -10000.0, -10000.0, 1.0);
442 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
443 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
444 glEnable(GL_CULL_FACE);
445 glCullFace(GL_BACK);
446
447 g_shader_gBuffer->use();
448 g_shader_gBuffer->setMatrix("projection", l_mat4_projm);
449 g_shader_gBuffer->setMatrix("view", l_mat4_viewm);
450
451 glm::mat4 model = glm::mat4();
452 g_shader_gBuffer->setMatrix("model", model);
453
454 // Draw everything
455 g_vmf_file->SetFilters({}, { "func_detail", "prop_static" });
456 g_vmf_file->DrawWorld(g_shader_gBuffer);
457 g_vmf_file->DrawEntities(g_shader_gBuffer);
458
459 // Clear depth
460 glClear(GL_DEPTH_BUFFER_BIT);
461
462 // Render again BUT JUST THE IMPORTANT BITS
463 g_vmf_file->SetFilters({ g_tar_config->m_visgroup_layout, g_tar_config->m_visgroup_mask }, { "func_detail", "prop_static" });
464 g_vmf_file->DrawWorld(g_shader_gBuffer);
465 g_vmf_file->DrawEntities(g_shader_gBuffer);
466
467 g_vmf_file->SetFilters({ g_tar_config->m_visgroup_overlap }, { "func_detail", "prop_static" });
468 g_vmf_file->DrawWorld(g_shader_gBuffer, {}, TAR_MIBUFFER_OVERLAP);
469 g_vmf_file->DrawEntities(g_shader_gBuffer, {}, TAR_MIBUFFER_OVERLAP);
470
471 // Draw cover with cover flag set
472 g_vmf_file->SetFilters({ g_tar_config->m_visgroup_cover }, { "func_detail", "prop_static" });
473 g_vmf_file->DrawWorld(g_shader_gBuffer, {}, TAR_MIBUFFER_COVER0);
474 g_vmf_file->DrawEntities(g_shader_gBuffer, {}, TAR_MIBUFFER_COVER0);
475
476 GBuffer::Unbind();
477
478 g_gbuffer_clean->Bind();
479 glClearColor(0.0, 0.0, 0.0, 1.0);
480 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
481
482 g_vmf_file->SetFilters({ g_tar_config->m_visgroup_layout, g_tar_config->m_visgroup_mask }, { "func_detail", "prop_static" });
483 g_vmf_file->DrawWorld(g_shader_gBuffer);
484 g_vmf_file->DrawEntities(g_shader_gBuffer);
485
486 GBuffer::Unbind();
487
488 #pragma endregion
489
490 #pragma region mask_gen
491
492 g_mask_playspace->Bind();
493 glClearColor(0.0, 0.0, 0.0, 1.0);
494 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
495
496 g_shader_iBuffer->use();
497 g_shader_iBuffer->setMatrix("projection", l_mat4_projm);
498 g_shader_iBuffer->setMatrix("view", l_mat4_viewm);
499
500 // LAYOUT ================================================================
501
502 g_shader_iBuffer->setUnsigned("srcChr", 0x1U);
503 g_vmf_file->SetFilters({ g_tar_config->m_visgroup_layout }, { "func_detail", "prop_static" });
504 g_vmf_file->DrawWorld(g_shader_iBuffer);
505 g_vmf_file->DrawEntities(g_shader_iBuffer);
506
507 // Subtractive brushes
508 g_shader_iBuffer->setUnsigned("srcChr", 0x0U);
509 g_vmf_file->SetFilters({ g_tar_config->m_visgroup_mask }, { "func_detail", "prop_static" });
510 g_vmf_file->DrawWorld(g_shader_iBuffer);
511 g_vmf_file->DrawEntities(g_shader_iBuffer);
512
513 // OBJECTIVES ============================================================
514
515 g_mask_objectives->Bind();
516 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
517
518 g_shader_iBuffer->setUnsigned("srcChr", 0x1U);
519 g_vmf_file->SetFilters({}, { "func_bomb_target", "func_hostage_rescue" });
520 g_vmf_file->DrawEntities(g_shader_iBuffer);
521
522 // BUY ZONES =============================================================
523
524 g_mask_buyzone->Bind();
525 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
526
527 g_shader_iBuffer->setUnsigned("srcChr", 0x1U);
528 g_vmf_file->SetFilters({}, { "func_buyzone" });
529 g_vmf_file->DrawEntities(g_shader_iBuffer);
530
531 #pragma endregion
532
533 // FINAL COMPOSITE ===============================================================
534 #pragma region final_composite
535
536 MBuffer::Unbind(); // Release any frame buffer
537
538 if(drawTarget != NULL)
539 drawTarget->Bind();
540
541 glClearColor(0.0, 0.0, 0.0, 1.0);
542 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
543 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
544 glDisable(GL_CULL_FACE);
545
546 g_shader_comp->use();
547
548 // Bind RT's
549 //g_texture_background->bindOnSlot ( 0 );
550 //g_shader_comp->setInt("tex_background", 0 );
551
552 g_tar_config->m_texture_gradient->bindOnSlot( 1 );
553 g_shader_comp->setInt("tex_gradient", 1 );
554
555 g_gbuffer->BindPositionBufferToTexSlot ( 2 );
556 g_shader_comp->setInt("gbuffer_position", 2 );
557
558 g_gbuffer->BindNormalBufferToTexSlot ( 3 );
559 g_shader_comp->setInt("gbuffer_normal", 3 );
560
561 g_gbuffer->BindInfoBufferToTexSlot ( 4 );
562 g_shader_comp->setInt("gbuffer_info", 4 );
563
564 g_mask_playspace->BindMaskBufferToTexSlot ( 5 );
565 g_shader_comp->setInt("umask_playspace", 5 );
566
567 g_mask_objectives->BindMaskBufferToTexSlot( 6 );
568 g_shader_comp->setInt("umask_objectives", 6 );
569
570 g_mask_buyzone->BindMaskBufferToTexSlot ( 7 );
571 g_shader_comp->setInt("umask_buyzone", 7 );
572
573 g_gbuffer_clean->BindPositionBufferToTexSlot(8);
574 g_shader_comp->setInt("gbuffer_clean_position", 8);
575
576 g_gbuffer->BindOriginBufferToTexSlot(11);
577 g_shader_comp->setInt("gbuffer_origin", 11);
578
579 g_texture_modulate->bindOnSlot(10);
580 g_shader_comp->setInt("tex_modulate", 10);
581
582 g_ssao_rotations->bindOnSlot ( 9 );
583 g_shader_comp->setInt("ssaoRotations", 9 );
584 g_shader_comp->setFloat("ssaoScale", g_tar_config->m_ao_scale);
585 g_shader_comp->setMatrix("projection", l_mat4_projm);
586 g_shader_comp->setMatrix("view", l_mat4_viewm);
587
588 for (int i = 0; i < TAR_AO_SAMPLES; i++) {
589 g_shader_comp->setVec3("samples[" + std::to_string(i) + "]", g_ssao_samples[i]);
590 }
591
592 // Bind uniforms
593 g_shader_comp->setVec3("bounds_NWU", g_tar_config->m_map_bounds.NWU);
594 g_shader_comp->setVec3("bounds_SEL", g_tar_config->m_map_bounds.SEL);
595
596 g_shader_comp->setVec4("color_objective", g_tar_config->m_color_objective);
597 g_shader_comp->setVec4("color_buyzone", g_tar_config->m_color_buyzone);
598 g_shader_comp->setVec4("color_cover", g_tar_config->m_color_cover);
599 g_shader_comp->setVec4("color_cover2", g_tar_config->m_color_cover2);
600 g_shader_comp->setVec4("color_ao", g_tar_config->m_color_ao);
601 g_shader_comp->setFloat("blend_objective_stripes", g_tar_config->m_outline_stripes_enable? 0.0f: 1.0f);
602 g_shader_comp->setFloat("blend_ao", g_tar_config->m_ao_enable? 1.0f: 0.0f);
603 g_shader_comp->setInt("mssascale", g_msaa_mul);
604
605 g_mesh_screen_quad->Draw();
606
607 render_to_png(g_renderWidth, g_renderHeight, layerName.c_str());
608 #pragma endregion
609 }
610
611 int main(int argc, const char** argv) {
612 try {
613 return app(argc, argv);
614 }
615 catch (cxxopts::OptionException& e) {
616 std::cerr << "Parse error: " << e.what() << "\n";
617 }
618
619 return 1;
620 }
621
622
623 void render_to_png(int x, int y, const char* filepath){
624 void* data = malloc(4 * x * y);
625
626 glReadPixels(0, 0, x, y, GL_RGBA, GL_UNSIGNED_BYTE, data);
627
628 stbi_flip_vertically_on_write(true);
629 stbi_write_png(filepath, x, y, 4, data, x * 4);
630
631 free(data);
632 }
633
634 void save_to_dds(int x, int y, const char* filepath, IMG imgmode)
635 {
636 void* data = malloc(4 * x * y);
637
638 glReadPixels(0, 0, x, y, GL_RGB, GL_UNSIGNED_BYTE, data);
639
640 dds_write((uint8_t*)data, filepath, x, y, imgmode);
641
642 free(data);
643 }
644
645
646
647 /*
648
649 NVIDIA optimus systems will default to intel integrated graphics chips.
650
651 This export gets picked up by NVIDIA drivers (v 302+).
652 It will force usage of the dedicated video device in the machine, which likely has full coverage of 3.3
653
654 */
655 extern "C" {
656 _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
657 }