gs-mipmapper: Formatting and refactoring

This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2018-09-28 23:32:35 +02:00
parent bb5c1f80b5
commit 95018868dc
2 changed files with 33 additions and 34 deletions

View file

@ -18,6 +18,7 @@
*/
#include "gs-mipmapper.h"
#include "plugin.h"
extern "C" {
#pragma warning(push)
@ -57,41 +58,41 @@ struct gs_d3d11_device {
gs::mipmapper::~mipmapper()
{
vertexBuffer.reset();
renderTarget.reset();
vertex_buffer.reset();
render_target.reset();
effect.reset();
}
gs::mipmapper::mipmapper()
{
vertexBuffer = std::make_unique<gs::vertex_buffer>(6, 1);
auto v0 = vertexBuffer->at(0);
vertex_buffer = std::make_unique<gs::vertex_buffer>(6, 1);
auto v0 = vertex_buffer->at(0);
v0.position->x = 0;
v0.position->y = 0;
v0.uv[0]->x = 0;
v0.uv[0]->y = 0;
auto v1 = vertexBuffer->at(1);
auto v4 = vertexBuffer->at(4);
auto v1 = vertex_buffer->at(1);
auto v4 = vertex_buffer->at(4);
v4.position->x = v1.position->x = 1.0;
v4.position->y = v1.position->y = 0;
v4.uv[0]->x = v1.uv[0]->x = 1.0;
v4.uv[0]->y = v1.uv[0]->y = 0;
auto v2 = vertexBuffer->at(2);
auto v3 = vertexBuffer->at(3);
auto v2 = vertex_buffer->at(2);
auto v3 = vertex_buffer->at(3);
v3.position->x = v2.position->x = 0;
v3.position->y = v2.position->y = 1.0;
v3.uv[0]->x = v2.uv[0]->x = 0;
v3.uv[0]->y = v2.uv[0]->y = 1.0;
auto v5 = vertexBuffer->at(5);
auto v5 = vertex_buffer->at(5);
v5.position->x = 1.0;
v5.position->y = 1.0;
v5.uv[0]->x = 1.0;
v5.uv[0]->y = 1.0;
vertexBuffer->update();
vertex_buffer->update();
char* effect_file = obs_module_file("effects/mipgen.effect");
effect = std::make_unique<gs::effect>(effect_file);
@ -132,23 +133,15 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
if ((source->get_color_format() != target->get_color_format())) {
throw std::invalid_argument("source and target must have same format");
}
obs_enter_graphics();
// Copy original texture
gs_copy_texture(target->get_object(), source->get_object());
//gs_copy_texture(target->get_object(), source->get_object());
// Test if we actually need to recreate the render target for a different format.
bool recreate = false;
if (renderTarget) {
recreate = (source->get_color_format() != renderTarget->get_color_format());
} else {
recreate = true;
}
// Re-create the render target if necessary.
if (recreate) {
renderTarget = std::make_unique<gs::rendertarget>(source->get_color_format(), GS_ZS_NONE);
// Test if we actually need to recreate the render target for a different format or at all.
if ((!render_target) || (source->get_color_format() != render_target->get_color_format())) {
render_target = std::make_unique<gs::rendertarget>(source->get_color_format(), GS_ZS_NONE);
}
// Render
@ -180,7 +173,7 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
break;
}
gs_load_vertexbuffer(vertexBuffer->update());
gs_load_vertexbuffer(vertex_buffer->update());
gs_load_indexbuffer(nullptr);
if (source->get_type() == gs::texture::type::Normal) {
@ -198,36 +191,41 @@ void gs::mipmapper::rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr
target_t2->GetDesc(&target_t2desc);
dev->context->CopySubresourceRegion(target_t2, 0, 0, 0, 0, source_t2, 0, nullptr);
// If we do not have any miplevels, just stop now.
if (target_t2desc.MipLevels == 1) {
obs_leave_graphics();
return;
}
for (size_t mip = 1; mip < target_t2desc.MipLevels; mip++) {
for (size_t mip = 1; mip <= target_t2desc.MipLevels; mip++) {
texture_width /= 2;
texture_height /= 2;
texel_width *= 2;
texel_height *= 2;
// Draw mipmap layer
{
auto op = renderTarget->render(texture_width, texture_height);
try {
auto op = render_target->render(texture_width, texture_height);
effect->get_parameter("image").set_texture(target);
effect->get_parameter("level").set_int(mip - 1);
effect->get_parameter("level").set_int(mip);
effect->get_parameter("imageTexel").set_float2(texel_width, texel_height);
effect->get_parameter("strength").set_float(strength);
while (gs_effect_loop(effect->get_object(), technique.c_str())) {
gs_draw(gs_draw_mode::GS_TRIS, 0, vertexBuffer->size());
gs_draw(gs_draw_mode::GS_TRIS, 0, vertex_buffer->size());
}
} catch (...) {
P_LOG_ERROR("Failed to render mipmap layer.");
}
// Copy
ID3D11Texture2D* rt =
reinterpret_cast<ID3D11Texture2D*>(gs_texture_get_obj(renderTarget->get_object()));
dev->context->CopySubresourceRegion(target_t2, mip, 0, 0, 0, rt, 0, nullptr);
reinterpret_cast<ID3D11Texture2D*>(gs_texture_get_obj(render_target->get_object()));
uint32_t level = D3D11CalcSubresource(mip, 0, target_t2desc.MipLevels);
dev->context->CopySubresourceRegion(target_t2, level, 0, 0, 0, rt, 0, NULL);
}
}
#endif

View file

@ -32,8 +32,8 @@ extern "C" {
namespace gs {
class mipmapper {
std::unique_ptr<gs::vertex_buffer> vertexBuffer;
std::unique_ptr<gs::rendertarget> renderTarget;
std::unique_ptr<gs::vertex_buffer> vertex_buffer;
std::unique_ptr<gs::rendertarget> render_target;
std::unique_ptr<gs::effect> effect;
public:
@ -50,6 +50,7 @@ namespace gs {
~mipmapper();
mipmapper();
void rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr<gs::texture> target, gs::mipmapper::generator generator, float_t strength);
void rebuild(std::shared_ptr<gs::texture> source, std::shared_ptr<gs::texture> target,
gs::mipmapper::generator generator, float_t strength);
};
} // namespace gs