4 #ifdef entry_point_testing
7 #include <GLFW\glfw3.h>
10 #include <glm\gtc\matrix_transform.hpp>
11 #include <glm\gtc\type_ptr.hpp>
16 #include "GBuffer.hpp"
19 #include "Texture.hpp"
20 #include "GradientMap.hpp"
21 #include "SSAOKernel.hpp"
22 #include "tar_config.hpp"
25 #include "cxxopts.hpp"
27 #define STB_IMAGE_WRITE_IMPLEMENTATION
28 #define STBI_MSC_SECURE_CRT
29 #include "stb_image_write.h"
31 #define TAR_MAX_LAYERS 5
32 #define TAR_AO_SAMPLES 256
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
;
41 bool g_onlyMasks
= false;
44 void render_config(tar_config_layer layer
, const std::string
& layerName
, FBuffer
* drawTarget
= NULL
);
46 //glm::mat4 g_mat4_viewm;
47 //glm::mat4 g_mat4_projm;
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
;
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
;
66 tar_config
* g_tar_config
;
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
;
74 uint32_t g_renderWidth
= 1024;
75 uint32_t g_renderHeight
= 1024;
76 uint32_t g_msaa_mul
= 1;
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
);
83 int app(int argc
, const char** argv
) {
85 #pragma region cxxopts
86 cxxopts::Options
options("AutoRadar", "Auto radar");
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(""))
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)")
95 ("positional", "Positional parameters", cxxopts::value
<std::vector
<std::string
>>());
97 options
.parse_positional("positional");
98 auto result
= options
.parse(argc
, argv
);
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");
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
>>();
108 g_mapfile_path
= sutil::ReplaceAll(positional
[0], "\n", "");
110 else throw cxxopts::option_required_exception("mapfile"); // We need a map file
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
, "\\", "/");
116 /* Check the rest of the flags */
117 g_onlyMasks
= result
["onlyMasks"].as
<bool>();
118 g_Masks
= result
["dumpMasks"].as
<bool>() || g_onlyMasks
;
121 //m_renderWidth = result["width"].as<uint32_t>();
122 //m_renderHeight = result["height"].as<uint32_t>();
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/";
130 #pragma region opengl_setup
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
);
137 glfwWindowHint(GLFW_VISIBLE
, GL_FALSE
);
139 GLFWwindow
* window
= glfwCreateWindow(g_renderWidth
, g_renderHeight
, "Ceci n'est pas une window", NULL
, NULL
);
141 if (window
== NULL
) {
142 printf("GLFW died\n");
147 glfwMakeContextCurrent(window
);
150 if (!gladLoadGLLoader((GLADloadproc
)glfwGetProcAddress
)) {
151 printf("GLAD died\n");
155 const unsigned char* glver
= glGetString(GL_VERSION
);
156 printf("(required: min core 3.3.0) opengl version: %s\n", glver
);
159 vfilesys
* filesys
= new vfilesys(g_game_path
+ "/gameinfo.txt");
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
);
166 #pragma region opengl_extra
168 std::vector
<float> __meshData
= {
176 g_mesh_screen_quad
= new Mesh(__meshData
, MeshMode::SCREEN_SPACE_UV
);
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");
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
;
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
);
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));
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();
210 glEnable(GL_DEPTH_TEST
);
211 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
216 #pragma region render
218 std::map
<tar_config_layer
*, FBuffer
*> _flayers
;
220 // Render all map segments
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
]);
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
);
231 glDisable(GL_DEPTH_TEST
);
233 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
234 glBlendEquation(GL_FUNC_ADD
);
237 ///g_gbuffer->BindPositionBufferToTexSlot(0);
238 ///g_shader_multilayer_blend->setInt("gbuffer_position", 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
);
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
);
253 for(int x
= 0; x
< g_tar_config
->layers
.size(); x
++)
255 tar_config_layer
* l
= &g_tar_config
->layers
[g_tar_config
->layers
.size() - x
- 1];
256 if (l
== &megalayer
) continue;
258 _flayers
[l
]->BindRTToTexSlot(1);
259 _flayers
[l
]->BindHeightToTexSlot(0);
261 g_shader_multilayer_blend
->setFloat("layer_min", l
->layer_min
);
262 g_shader_multilayer_blend
->setFloat("layer_max", l
->layer_max
);
264 g_mesh_screen_quad
->Draw();
267 g_shader_multilayer_blend
->setFloat("layer_min", megalayer
.layer_min
);
268 g_shader_multilayer_blend
->setFloat("layer_max", megalayer
.layer_max
);
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
);
274 _flayers
[&megalayer
]->BindRTToTexSlot(1);
275 _flayers
[&megalayer
]->BindHeightToTexSlot(0);
276 g_mesh_screen_quad
->Draw();
281 g_fbuffer_generic1
->Bind();
283 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
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
);
290 g_tar_config
->m_texture_background
->bindOnSlot(0);
291 g_shader_multilayer_final
->setInt("tex_background", 0);
293 g_fbuffer_generic
->BindRTToTexSlot(1);
294 g_shader_multilayer_final
->setInt("tex_layer", 1);
295 g_mesh_screen_quad
->Draw();
298 if (g_tar_config
->m_sampling_mode
== sampling_mode::FXAA
) {
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);
306 g_mesh_screen_quad
->Draw();
308 else if (g_tar_config
->m_sampling_mode
== sampling_mode::MSAA16x
309 || g_tar_config
->m_sampling_mode
== sampling_mode::MSAA4x
)
313 g_shader_msaa
->use();
314 g_shader_msaa
->setInt("sampler0", 0);
315 g_fbuffer_generic1
->BindRTToTexSlot(0);
316 g_mesh_screen_quad
->Draw();
320 //render_to_png(1024, 1024, ("comp" + std::to_string(i++) + ".png").c_str());
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
);
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
);
333 std::cout
<< "Generating radar .TXT... ";
335 kv::DataBlock node_radar
= kv::DataBlock();
336 node_radar
.name
= "\"" + g_mapfile_name
+ "\"";
337 node_radar
.Values
.insert({ "material", "overviews/" + g_mapfile_name
});
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
) });
343 if (g_tar_config
->layers
.size() > 1) {
344 kv::DataBlock node_vsections
= kv::DataBlock();
345 node_vsections
.name
= "\"verticalsections\"";
348 for (auto && layer
: g_tar_config
->layers
) {
349 kv::DataBlock node_layer
= kv::DataBlock();
351 node_layer
.name
= "\"default\""; ln
++;
353 else node_layer
.name
= "\"layer" + std::to_string(ln
++) + "\"";
355 node_layer
.Values
.insert({ "AltitudeMin", std::to_string(layer
.layer_max
) });
356 node_layer
.Values
.insert({ "AltitudeMax", std::to_string(layer
.layer_min
) });
358 node_vsections
.SubBlocks
.push_back(node_layer
);
361 node_radar
.SubBlocks
.push_back(node_vsections
);
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");
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
)) });
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
)) });
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
)) });
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
);
400 void render_config(tar_config_layer layer
, const std::string
& layerName
, FBuffer
* drawTarget
) {
401 // G BUFFER GENERATION ======================================================================================
402 #pragma region buffer_gen_geo
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
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
),
418 g_vmf_file
->SetMinMax(10000, -10000);
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
428 glm::mat4 l_mat4_viewm
= glm::lookAt(
430 glm::vec3(0.0f
, -1.0f
, 0.0f
),
433 std::cout
<< "v" << layer
.layer_min
<< "\n";
434 std::cout
<< "^" << layer
.layer_max
<< "\n";
436 g_vmf_file
->SetMinMax(layer
.layer_min
, layer
.layer_max
);
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
);
447 g_shader_gBuffer
->use();
448 g_shader_gBuffer
->setMatrix("projection", l_mat4_projm
);
449 g_shader_gBuffer
->setMatrix("view", l_mat4_viewm
);
451 glm::mat4 model
= glm::mat4();
452 g_shader_gBuffer
->setMatrix("model", model
);
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
);
460 glClear(GL_DEPTH_BUFFER_BIT
);
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
);
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
);
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
);
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
);
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
);
490 #pragma region mask_gen
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
);
496 g_shader_iBuffer
->use();
497 g_shader_iBuffer
->setMatrix("projection", l_mat4_projm
);
498 g_shader_iBuffer
->setMatrix("view", l_mat4_viewm
);
500 // LAYOUT ================================================================
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
);
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
);
513 // OBJECTIVES ============================================================
515 g_mask_objectives
->Bind();
516 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
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
);
522 // BUY ZONES =============================================================
524 g_mask_buyzone
->Bind();
525 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
527 g_shader_iBuffer
->setUnsigned("srcChr", 0x1U
);
528 g_vmf_file
->SetFilters({}, { "func_buyzone" });
529 g_vmf_file
->DrawEntities(g_shader_iBuffer
);
533 // FINAL COMPOSITE ===============================================================
534 #pragma region final_composite
536 MBuffer::Unbind(); // Release any frame buffer
538 if(drawTarget
!= NULL
)
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
);
546 g_shader_comp
->use();
549 //g_texture_background->bindOnSlot ( 0 );
550 //g_shader_comp->setInt("tex_background", 0 );
552 g_tar_config
->m_texture_gradient
->bindOnSlot( 1 );
553 g_shader_comp
->setInt("tex_gradient", 1 );
555 g_gbuffer
->BindPositionBufferToTexSlot ( 2 );
556 g_shader_comp
->setInt("gbuffer_position", 2 );
558 g_gbuffer
->BindNormalBufferToTexSlot ( 3 );
559 g_shader_comp
->setInt("gbuffer_normal", 3 );
561 g_gbuffer
->BindInfoBufferToTexSlot ( 4 );
562 g_shader_comp
->setInt("gbuffer_info", 4 );
564 g_mask_playspace
->BindMaskBufferToTexSlot ( 5 );
565 g_shader_comp
->setInt("umask_playspace", 5 );
567 g_mask_objectives
->BindMaskBufferToTexSlot( 6 );
568 g_shader_comp
->setInt("umask_objectives", 6 );
570 g_mask_buyzone
->BindMaskBufferToTexSlot ( 7 );
571 g_shader_comp
->setInt("umask_buyzone", 7 );
573 g_gbuffer_clean
->BindPositionBufferToTexSlot(8);
574 g_shader_comp
->setInt("gbuffer_clean_position", 8);
576 g_gbuffer
->BindOriginBufferToTexSlot(11);
577 g_shader_comp
->setInt("gbuffer_origin", 11);
579 g_texture_modulate
->bindOnSlot(10);
580 g_shader_comp
->setInt("tex_modulate", 10);
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
);
588 for (int i
= 0; i
< TAR_AO_SAMPLES
; i
++) {
589 g_shader_comp
->setVec3("samples[" + std::to_string(i
) + "]", g_ssao_samples
[i
]);
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
);
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
);
605 g_mesh_screen_quad
->Draw();
607 render_to_png(g_renderWidth
, g_renderHeight
, layerName
.c_str());
611 int main(int argc
, const char** argv
) {
613 return app(argc
, argv
);
615 catch (cxxopts::OptionException
& e
) {
616 std::cerr
<< "Parse error: " << e
.what() << "\n";
623 void render_to_png(int x
, int y
, const char* filepath
){
624 void* data
= malloc(4 * x
* y
);
626 glReadPixels(0, 0, x
, y
, GL_RGBA
, GL_UNSIGNED_BYTE
, data
);
628 stbi_flip_vertically_on_write(true);
629 stbi_write_png(filepath
, x
, y
, 4, data
, x
* 4);
634 void save_to_dds(int x
, int y
, const char* filepath
, IMG imgmode
)
636 void* data
= malloc(4 * x
* y
);
638 glReadPixels(0, 0, x
, y
, GL_RGB
, GL_UNSIGNED_BYTE
, data
);
640 dds_write((uint8_t*)data
, filepath
, x
, y
, imgmode
);
649 NVIDIA optimus systems will default to intel integrated graphics chips.
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
656 _declspec(dllexport
) DWORD NvOptimusEnablement
= 0x00000001;