Skip to content

Commit cf2c138

Browse files
committed
opengl: fooling around with transparency in shader
1 parent e435c3c commit cf2c138

File tree

5 files changed

+147
-26
lines changed

5 files changed

+147
-26
lines changed

data/shader/render.shader

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,16 +149,18 @@ void main() {
149149
if (((fragFlags & SemiTransparency) == SemiTransparency)
150150
&& ((fragBitcount != BIT_NONE && color.a != 0.f) || (fragBitcount == BIT_NONE))) {
151151
uint transparency = (fragFlags & 0x60u) >> 5;
152-
if (transparency == Bby2plusFby2)
152+
if (transparency == Bby2plusFby2) {
153+
// Works ok, (benchmark.exe, not ok: skullmonkeys)
153154
color.a = 0.5f;
154-
else if (transparency == BplusF) {
155+
} else if (transparency == BplusF) {
156+
// Works ok (Tekken 3 Sword glow)
155157
color.a = 0.5f;
156158
} else if (transparency == BminusF) {
157-
color.r = -color.r;
158-
color.g = -color.g;
159-
color.b = -color.b;
160159
color.a = 0.5f;
161160
} else if (transparency == BplusFby4) {
161+
color.r = 0;
162+
color.g = 0;
163+
color.b = 1.f;
162164
color.a = 0.25f;
163165
}
164166
// color.a = 0.5f;

src/config.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ const json defaultConfig = {
152152
{"options", {
153153
{"graphics", {
154154
{"rendering_mode", RenderingMode::SOFTWARE},
155-
{"filtering", false},
155+
{"transparency", true},
156156
{"widescreen", false},
157157
{"forceWidescreen", false},
158158
{"resolution", {

src/platform/windows/gui/options.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,14 @@ void graphicsOptionsWindow() {
103103
}
104104
ImGui::PopItemWidth();
105105
}
106-
}
107106

108-
bool filtering = config["options"]["graphics"]["filtering"];
109-
if (ImGui::Checkbox("Filtering", &filtering)) {
110-
config["options"]["graphics"]["filtering"] = filtering;
111-
bus.notify(Event::Config::Graphics{});
107+
bool transparency = config["options"]["graphics"]["transparency"];
108+
if (ImGui::Checkbox("Transparency", &transparency)) {
109+
config["options"]["graphics"]["transparency"] = transparency;
110+
bus.notify(Event::Config::Graphics{});
111+
}
112112
}
113+
113114
bool widescreen = config["options"]["graphics"]["widescreen"];
114115
if (ImGui::Checkbox("Widescreen (16/9)", &widescreen)) {
115116
config["options"]["graphics"]["widescreen"] = widescreen;

src/renderer/opengl/opengl.cpp

Lines changed: 132 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
#include <SDL.h>
33
#include <algorithm>
44
#define STB_IMAGE_WRITE_IMPLEMENTATION
5+
#include <imgui.h>
56
#include <stb_image_write.h>
7+
#include <glm/gtc/type_ptr.hpp>
68
#include "config.h"
79
#include "utils/string.h"
810

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

96-
bool filtering = config["options"]["graphics"]["filtering"];
98+
transparency = config["options"]["graphics"]["transparency"];
9799

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

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

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

312-
// Render
313314
auto mapType = [](int type) {
314315
if (type == gpu::Vertex::Type::Line)
315316
return GL_LINES;
316317
else
317318
return GL_TRIANGLES;
318319
};
319-
int lastType = gpu::Vertex::Type::Polygon;
320-
int begin = 0;
321-
int count = 0;
322-
for (size_t i = 0; i < buffer.size(); i++) {
323-
++count;
324-
int type = buffer[i].type;
325320

326-
if (i == 0 || (lastType == type && i < buffer.size() - 1)) continue;
321+
#if 0
322+
const std::array<const char*, 15> blendModes= {{
323+
"GL_ZERO",
324+
"GL_ONE",
325+
"GL_SRC_COLOR",
326+
"GL_ONE_MINUS_SRC_COLOR",
327+
"GL_DST_COLOR",
328+
"GL_ONE_MINUS_DST_COLOR",
329+
"GL_SRC_ALPHA",
330+
"GL_ONE_MINUS_SRC_ALPHA",
331+
"GL_DST_ALPHA",
332+
"GL_ONE_MINUS_DST_ALPHA",
333+
"GL_CONSTANT_COLOR",
334+
"GL_ONE_MINUS_CONSTANT_COLOR",
335+
"GL_CONSTANT_ALPHA",
336+
"GL_ONE_MINUS_CONSTANT_ALPHA",
337+
"GL_SRC_ALPHA_SATURATE"
338+
}};
339+
340+
auto mapBlendMode = [](int mode) {
341+
switch (mode){
342+
case 0: return GL_ZERO;
343+
case 1: return GL_ONE;
344+
case 2: return GL_SRC_COLOR;
345+
case 3: return GL_ONE_MINUS_SRC_COLOR;
346+
case 4: return GL_DST_COLOR;
347+
case 5: return GL_ONE_MINUS_DST_COLOR;
348+
case 6: return GL_SRC_ALPHA;
349+
case 7: return GL_ONE_MINUS_SRC_ALPHA;
350+
case 8: return GL_DST_ALPHA;
351+
case 9: return GL_ONE_MINUS_DST_ALPHA;
352+
case 10: return GL_CONSTANT_COLOR;
353+
case 11: return GL_ONE_MINUS_CONSTANT_COLOR;
354+
case 12: return GL_CONSTANT_ALPHA;
355+
case 13: return GL_ONE_MINUS_CONSTANT_ALPHA;
356+
case 14: return GL_SRC_ALPHA_SATURATE;
357+
}
358+
};
359+
360+
const std::array<const char*, 3> equations = {{
361+
"GL_FUNC_ADD",
362+
"GL_FUNC_SUBTRACT",
363+
"GL_FUNC_REVERSE_SUBTRACT"
364+
}};
365+
366+
auto mapEquation = [](int mode) {
367+
switch (mode){
368+
case 0: return GL_FUNC_ADD;
369+
case 1: return GL_FUNC_SUBTRACT;
370+
case 2: return GL_FUNC_REVERSE_SUBTRACT;
371+
}
372+
};
373+
374+
static int selectedSrcA = 0;
375+
static int selectedSrcC = 0;
376+
static int selectedEquation = 0;
377+
static int selectedDstA = 0;
378+
static int selectedDstC = 0;
379+
380+
static glm::vec4 blendColor;
381+
382+
ImGui::Begin("BminusF");
383+
384+
if (ImGui::Button("-##sa") && selectedSrcA > 0) selectedSrcA--; ImGui::SameLine();
385+
if (ImGui::Button("+##sa") && selectedSrcA < blendModes.size()-1) selectedSrcA++; ImGui::SameLine();
386+
ImGui::Combo("SRC A", &selectedSrcA, blendModes.data(), blendModes.size());
387+
388+
389+
if (ImGui::Button("-##sc") && selectedSrcC > 0) selectedSrcC--; ImGui::SameLine();
390+
if (ImGui::Button("+##sc") && selectedSrcC < blendModes.size()-1) selectedSrcC++; ImGui::SameLine();
391+
ImGui::Combo("SRC C", &selectedSrcC, blendModes.data(), blendModes.size());
392+
393+
if (ImGui::Button("-##e") && selectedEquation > 0) selectedEquation--; ImGui::SameLine();
394+
if (ImGui::Button("+##e") && selectedEquation < equations.size()-1) selectedEquation++; ImGui::SameLine();
395+
ImGui::Combo("##equation", &selectedEquation, equations.data(), equations.size());
396+
397+
if (ImGui::Button("-##da") && selectedDstA > 0) selectedDstA--; ImGui::SameLine();
398+
if (ImGui::Button("+##da") && selectedDstA < blendModes.size()-1) selectedDstA++; ImGui::SameLine();
399+
ImGui::Combo("DST A", &selectedDstA, blendModes.data(), blendModes.size());
400+
401+
if (ImGui::Button("-##dc") && selectedDstC > 0) selectedDstC--; ImGui::SameLine();
402+
if (ImGui::Button("+##dc") && selectedDstC < blendModes.size()-1) selectedDstC++; ImGui::SameLine();
403+
ImGui::Combo("DST C", &selectedDstC, blendModes.data(), blendModes.size());
404+
405+
ImGui::ColorPicker4("Blend Color", glm::value_ptr(blendColor));
406+
407+
ImGui::End();
408+
#endif
409+
410+
// Unbatched render
411+
using Transparency = gpu::GP0_E1::SemiTransparency;
412+
413+
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
414+
if (transparency) {
415+
glEnable(GL_BLEND);
416+
} else {
417+
glDisable(GL_BLEND);
418+
}
419+
for (size_t i = 0; i < buffer.size();) {
420+
auto type = mapType(buffer[i].type);
421+
int count = type == GL_TRIANGLES ? 3 : 2;
422+
423+
if (transparency && buffer[i].flags & gpu::Vertex::SemiTransparency) {
424+
auto semi = static_cast<Transparency>((buffer[i].flags >> 5) & 3);
425+
if (semi == Transparency::Bby2plusFby2) {
426+
// Works ok, benchmark.exe
427+
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
428+
// glBlendFuncSeparate(mapBlendMode(selectedSrcC), mapBlendMode(selectedDstC), mapBlendMode(selectedSrcA),
429+
// mapBlendMode(selectedDstA)); glBlendEquation(mapEquation(selectedEquation)); glBlendColor(blendColor.r, blendColor.g,
430+
// blendColor.b, blendColor.a );
431+
} else if (semi == Transparency::BplusF) {
432+
// Works ok (Tekken 3 Sword glow)
433+
glBlendFunc(GL_DST_ALPHA, GL_ONE);
434+
} else if (semi == Transparency::BminusF) {
435+
// Ok on crash, black menu on Tekken3
436+
// glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
437+
438+
glBlendFunc(GL_ONE, GL_ONE);
439+
440+
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
441+
} else if (semi == Transparency::BplusFby4) {
442+
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
443+
}
444+
} else {
445+
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
446+
}
327447

328-
if (lastType != buffer[i].type) count--;
329-
glDrawArrays(mapType(lastType), begin, count);
448+
glDrawArrays(type, i, count);
330449

331-
lastType = type;
332-
begin = begin + count;
333-
count = 1;
450+
i += count;
334451
}
335452
lastPos = glm::vec2(gpu->displayAreaStartX, gpu->displayAreaStartY);
336453

src/renderer/opengl/opengl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class OpenGL {
4242
const int bufferSize = 100000;
4343

4444
bool hardwareRendering;
45+
bool transparency;
4546

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

0 commit comments

Comments
 (0)