Skip to content
Permalink
Browse files

opengl: fooling around with transparency in shader

  • Loading branch information
JaCzekanski committed Aug 30, 2019
1 parent e435c3c commit cf2c138241b0cb347fb38a4e1f307a21c02c6874
Showing with 147 additions and 26 deletions.
  1. +7 −5 data/shader/render.shader
  2. +1 −1 src/config.cpp
  3. +6 −5 src/platform/windows/gui/options.cpp
  4. +132 −15 src/renderer/opengl/opengl.cpp
  5. +1 −0 src/renderer/opengl/opengl.h
@@ -149,16 +149,18 @@ void main() {
if (((fragFlags & SemiTransparency) == SemiTransparency)
&& ((fragBitcount != BIT_NONE && color.a != 0.f) || (fragBitcount == BIT_NONE))) {
uint transparency = (fragFlags & 0x60u) >> 5;
if (transparency == Bby2plusFby2)
if (transparency == Bby2plusFby2) {
// Works ok, (benchmark.exe, not ok: skullmonkeys)
color.a = 0.5f;
else if (transparency == BplusF) {
} else if (transparency == BplusF) {
// Works ok (Tekken 3 Sword glow)
color.a = 0.5f;
} else if (transparency == BminusF) {
color.r = -color.r;
color.g = -color.g;
color.b = -color.b;
color.a = 0.5f;
} else if (transparency == BplusFby4) {
color.r = 0;
color.g = 0;
color.b = 1.f;
color.a = 0.25f;
}
// color.a = 0.5f;
@@ -152,7 +152,7 @@ const json defaultConfig = {
{"options", {
{"graphics", {
{"rendering_mode", RenderingMode::SOFTWARE},
{"filtering", false},
{"transparency", true},
{"widescreen", false},
{"forceWidescreen", false},
{"resolution", {
@@ -103,13 +103,14 @@ void graphicsOptionsWindow() {
}
ImGui::PopItemWidth();
}
}

bool filtering = config["options"]["graphics"]["filtering"];
if (ImGui::Checkbox("Filtering", &filtering)) {
config["options"]["graphics"]["filtering"] = filtering;
bus.notify(Event::Config::Graphics{});
bool transparency = config["options"]["graphics"]["transparency"];
if (ImGui::Checkbox("Transparency", &transparency)) {
config["options"]["graphics"]["transparency"] = transparency;
bus.notify(Event::Config::Graphics{});
}
}

bool widescreen = config["options"]["graphics"]["widescreen"];
if (ImGui::Checkbox("Widescreen (16/9)", &widescreen)) {
config["options"]["graphics"]["widescreen"] = widescreen;
@@ -2,7 +2,9 @@
#include <SDL.h>
#include <algorithm>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <imgui.h>
#include <stb_image_write.h>
#include <glm/gtc/type_ptr.hpp>
#include "config.h"
#include "utils/string.h"

@@ -93,13 +95,13 @@ bool OpenGL::setup() {
auto mode = config["options"]["graphics"]["rendering_mode"].get<RenderingMode>();
hardwareRendering = (mode & RenderingMode::HARDWARE) != 0;

bool filtering = config["options"]["graphics"]["filtering"];
transparency = config["options"]["graphics"]["transparency"];

renderWidth = config["options"]["graphics"]["resolution"]["width"];
renderHeight = config["options"]["graphics"]["resolution"]["height"];

renderBuffer = std::make_unique<Buffer>(bufferSize * sizeof(gpu::Vertex));
renderTex = std::make_unique<Texture>(renderWidth, renderHeight, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, filtering);
renderTex = std::make_unique<Texture>(renderWidth, renderHeight, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, false);
renderFramebuffer = std::make_unique<Framebuffer>(renderTex->get());

blitBuffer = std::make_unique<Buffer>(makeBlitBuf().size() * sizeof(BlitStruct));
@@ -309,28 +311,143 @@ void OpenGL::renderVertices(gpu::GPU* gpu) {
renderShader->getUniform("displayAreaPos").f(areaX, areaY);
renderShader->getUniform("displayAreaSize").f(areaW, areaH);

// Render
auto mapType = [](int type) {
if (type == gpu::Vertex::Type::Line)
return GL_LINES;
else
return GL_TRIANGLES;
};
int lastType = gpu::Vertex::Type::Polygon;
int begin = 0;
int count = 0;
for (size_t i = 0; i < buffer.size(); i++) {
++count;
int type = buffer[i].type;

if (i == 0 || (lastType == type && i < buffer.size() - 1)) continue;
#if 0
const std::array<const char*, 15> blendModes= {{
"GL_ZERO",
"GL_ONE",
"GL_SRC_COLOR",
"GL_ONE_MINUS_SRC_COLOR",
"GL_DST_COLOR",
"GL_ONE_MINUS_DST_COLOR",
"GL_SRC_ALPHA",
"GL_ONE_MINUS_SRC_ALPHA",
"GL_DST_ALPHA",
"GL_ONE_MINUS_DST_ALPHA",
"GL_CONSTANT_COLOR",
"GL_ONE_MINUS_CONSTANT_COLOR",
"GL_CONSTANT_ALPHA",
"GL_ONE_MINUS_CONSTANT_ALPHA",
"GL_SRC_ALPHA_SATURATE"
}};

auto mapBlendMode = [](int mode) {
switch (mode){
case 0: return GL_ZERO;
case 1: return GL_ONE;
case 2: return GL_SRC_COLOR;
case 3: return GL_ONE_MINUS_SRC_COLOR;
case 4: return GL_DST_COLOR;
case 5: return GL_ONE_MINUS_DST_COLOR;
case 6: return GL_SRC_ALPHA;
case 7: return GL_ONE_MINUS_SRC_ALPHA;
case 8: return GL_DST_ALPHA;
case 9: return GL_ONE_MINUS_DST_ALPHA;
case 10: return GL_CONSTANT_COLOR;
case 11: return GL_ONE_MINUS_CONSTANT_COLOR;
case 12: return GL_CONSTANT_ALPHA;
case 13: return GL_ONE_MINUS_CONSTANT_ALPHA;
case 14: return GL_SRC_ALPHA_SATURATE;
}
};

const std::array<const char*, 3> equations = {{
"GL_FUNC_ADD",
"GL_FUNC_SUBTRACT",
"GL_FUNC_REVERSE_SUBTRACT"
}};

auto mapEquation = [](int mode) {
switch (mode){
case 0: return GL_FUNC_ADD;
case 1: return GL_FUNC_SUBTRACT;
case 2: return GL_FUNC_REVERSE_SUBTRACT;
}
};

static int selectedSrcA = 0;
static int selectedSrcC = 0;
static int selectedEquation = 0;
static int selectedDstA = 0;
static int selectedDstC = 0;

static glm::vec4 blendColor;

ImGui::Begin("BminusF");

if (ImGui::Button("-##sa") && selectedSrcA > 0) selectedSrcA--; ImGui::SameLine();
if (ImGui::Button("+##sa") && selectedSrcA < blendModes.size()-1) selectedSrcA++; ImGui::SameLine();
ImGui::Combo("SRC A", &selectedSrcA, blendModes.data(), blendModes.size());


if (ImGui::Button("-##sc") && selectedSrcC > 0) selectedSrcC--; ImGui::SameLine();
if (ImGui::Button("+##sc") && selectedSrcC < blendModes.size()-1) selectedSrcC++; ImGui::SameLine();
ImGui::Combo("SRC C", &selectedSrcC, blendModes.data(), blendModes.size());

if (ImGui::Button("-##e") && selectedEquation > 0) selectedEquation--; ImGui::SameLine();
if (ImGui::Button("+##e") && selectedEquation < equations.size()-1) selectedEquation++; ImGui::SameLine();
ImGui::Combo("##equation", &selectedEquation, equations.data(), equations.size());

if (ImGui::Button("-##da") && selectedDstA > 0) selectedDstA--; ImGui::SameLine();
if (ImGui::Button("+##da") && selectedDstA < blendModes.size()-1) selectedDstA++; ImGui::SameLine();
ImGui::Combo("DST A", &selectedDstA, blendModes.data(), blendModes.size());

if (ImGui::Button("-##dc") && selectedDstC > 0) selectedDstC--; ImGui::SameLine();
if (ImGui::Button("+##dc") && selectedDstC < blendModes.size()-1) selectedDstC++; ImGui::SameLine();
ImGui::Combo("DST C", &selectedDstC, blendModes.data(), blendModes.size());

ImGui::ColorPicker4("Blend Color", glm::value_ptr(blendColor));

ImGui::End();
#endif

// Unbatched render
using Transparency = gpu::GP0_E1::SemiTransparency;

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if (transparency) {
glEnable(GL_BLEND);
} else {
glDisable(GL_BLEND);
}
for (size_t i = 0; i < buffer.size();) {
auto type = mapType(buffer[i].type);
int count = type == GL_TRIANGLES ? 3 : 2;

if (transparency && buffer[i].flags & gpu::Vertex::SemiTransparency) {
auto semi = static_cast<Transparency>((buffer[i].flags >> 5) & 3);
if (semi == Transparency::Bby2plusFby2) {
// Works ok, benchmark.exe
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// glBlendFuncSeparate(mapBlendMode(selectedSrcC), mapBlendMode(selectedDstC), mapBlendMode(selectedSrcA),
// mapBlendMode(selectedDstA)); glBlendEquation(mapEquation(selectedEquation)); glBlendColor(blendColor.r, blendColor.g,
// blendColor.b, blendColor.a );
} else if (semi == Transparency::BplusF) {
// Works ok (Tekken 3 Sword glow)
glBlendFunc(GL_DST_ALPHA, GL_ONE);
} else if (semi == Transparency::BminusF) {
// Ok on crash, black menu on Tekken3
// glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);

glBlendFunc(GL_ONE, GL_ONE);

// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} else if (semi == Transparency::BplusFby4) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
}
} else {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

if (lastType != buffer[i].type) count--;
glDrawArrays(mapType(lastType), begin, count);
glDrawArrays(type, i, count);

lastType = type;
begin = begin + count;
count = 1;
i += count;
}
lastPos = glm::vec2(gpu->displayAreaStartX, gpu->displayAreaStartY);

@@ -42,6 +42,7 @@ class OpenGL {
const int bufferSize = 100000;

bool hardwareRendering;
bool transparency;

std::unique_ptr<Program> renderShader;
std::unique_ptr<Buffer> renderBuffer;

0 comments on commit cf2c138

Please sign in to comment.
You can’t perform that action at this time.