created filter system and ported scaler to it

This commit is contained in:
DaniTheSkunk 2022-12-12 09:54:00 +00:00
parent 68acfcad9d
commit 0f320d00ae
4 changed files with 200 additions and 151 deletions

View File

@ -0,0 +1,41 @@
package com.danitheskunk.skunkworks.backends.gl;
import com.danitheskunk.skunkworks.Vec2i;
public abstract class Filter {
private final boolean resizing;
protected Framebuffer input;
protected Framebuffer output;
public Filter(Framebuffer input, boolean resizing) {
this.resizing = resizing;
this.input = input;
output = new Framebuffer(input.getSize());
}
public void apply() {
output.bind();
input.bindTexture();
process();
}
public Framebuffer getOutput() {
return output;
}
protected abstract void process();
public void setInput(Framebuffer input) {
this.input = input;
if(resizing) {
output.setSize(input.getSize());
}
}
public void setOutputSize(Vec2i size) {
if(!resizing) {
throw new RuntimeException("this filter doesn't allow output resizing");
}
output.setSize(size);
}
}

View File

@ -36,12 +36,7 @@ public class Framebuffer {
public void setSize(Vec2i size) { public void setSize(Vec2i size) {
this.size = size; this.size = size;
if(framebuffer != 0) {
glDeleteFramebuffers(framebuffer);
}
if(framebufferTex != 0) {
glDeleteTextures(framebufferTex);
}
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glBindTexture(GL_TEXTURE_2D, framebufferTex); glBindTexture(GL_TEXTURE_2D, framebufferTex);
glTexImage2D(GL_TEXTURE_2D, glTexImage2D(GL_TEXTURE_2D,
@ -82,4 +77,23 @@ public class Framebuffer {
0 0
); );
} }
public void copyToScreen() {
unbind();
ProgramCopy.getInstance().use();
bindTexture();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
//counterclockwise triangles
glVertex2i(-1, 1);
glVertex2i( 1, -1);
glVertex2i(-1, -1);
glVertex2i( 1, -1);
glVertex2i(-1, 1);
glVertex2i( 1, 1);
glEnd();
}
} }

View File

@ -0,0 +1,132 @@
package com.danitheskunk.skunkworks.backends.gl;
import com.danitheskunk.skunkworks.WindowStretchMode;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.glVertexAttrib2f;
import static org.lwjgl.opengl.GL41.glProgramUniform2f;
public class Scaler extends Filter {
private static final String fragmentSource = """
#version 450
layout(location = 1) in vec2 texCoord;
layout(binding = 0) uniform sampler2D tex;
out vec4 color;
void main() {
//color = vec4(vec2(texCoord).x/1000.f, 0.2f, 0.7f, 1.0f);
vec4 col = texture(tex, texCoord);
if(col.a > 0.0) {
color = col;
}
//color = texelFetch(tex, ivec2(texCoord), 0);
//color = vec4(1.0, 1.0, 1.0, 1.0);
//color = vec4(texCoord.xy, 0.0, 1.0);
}
""";
private static final String vertexSource = """
#version 450
layout(location = 0) in vec2 pos;
layout(location = 1) in vec2 texCoord;
layout(location = 2) uniform vec2 windowSize;
layout(location = 1) out vec2 out_texCoord;
void main() {
gl_Position = vec4(pos / windowSize * vec2(2.0f, 2.0f) + vec2(-1.0f, -1.0f), 0.0f, 1.0f);
out_texCoord = texCoord;
}
""";
private final Program program;
private WindowStretchMode stretchMode;
public Scaler(Framebuffer input) {
super(input, true);
program = new Program(vertexSource, fragmentSource);
}
@Override
protected void process() {
var outputSize = output.getSize();
var inputSize = input.getSize();
glViewport(0, 0, outputSize.getX(), outputSize.getY());
program.use();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glProgramUniform2f(
program.getProgram(),
program.getUniformLocation("windowSize"),
outputSize.getX(),
outputSize.getY()
);
int tlx1 = 0;
int tly1 = 0;
int tlx2 = 0;
int tly2 = 0;
switch(stretchMode) {
case STRETCH -> {
tlx2 = outputSize.getX();
tly2 = outputSize.getY();
}
case ASPECT -> {
float scalex = (float) outputSize.getX() /
(float) inputSize.getX();
float scaley = (float) outputSize.getY() /
(float) inputSize.getY();
float scale = Math.min(scalex, scaley);
int xoff = (int) (
(outputSize.getX() - inputSize.getX() * scale) / 2
);
int yoff = (int) (
(outputSize.getY() - inputSize.getY() * scale) / 2
);
tlx1 = xoff;
tly1 = yoff;
tlx2 = (int) (xoff + inputSize.getX() * scale);
tly2 = (int) (yoff + inputSize.getY() * scale);
}
case INTEGER -> {
int scalex = outputSize.getX() / inputSize.getX();
int scaley = outputSize.getY() / inputSize.getY();
int scale = Math.max(1, Math.min(scalex, scaley));
int xoff = (outputSize.getX() - inputSize.getX() * scale) / 2;
int yoff = (outputSize.getY() - inputSize.getY() * scale) / 2;
tlx1 = xoff;
tly1 = yoff;
tlx2 = xoff + inputSize.getX() * scale;
tly2 = yoff + inputSize.getY() * scale;
}
}
var texCoordIndex = program.getAttribLocation("texCoord");
glBegin(GL_TRIANGLES);
//counterclockwise triangles
glVertexAttrib2f(texCoordIndex, 0, 1);
glVertex2i(tlx1, tly2);
glVertexAttrib2f(texCoordIndex, 1, 0);
glVertex2i(tlx2, tly1);
glVertexAttrib2f(texCoordIndex, 0, 0);
glVertex2i(tlx1, tly1);
glVertexAttrib2f(texCoordIndex, 1, 0);
glVertex2i(tlx2, tly1);
glVertexAttrib2f(texCoordIndex, 0, 1);
glVertex2i(tlx1, tly2);
glVertexAttrib2f(texCoordIndex, 1, 1);
glVertex2i(tlx2, tly2);
glEnd();
}
public void setStretchMode(WindowStretchMode stretchMode) {
this.stretchMode = stretchMode;
}
}

View File

@ -19,36 +19,8 @@ import static org.lwjgl.opengl.GL46.*;
import static org.lwjgl.system.MemoryUtil.NULL; import static org.lwjgl.system.MemoryUtil.NULL;
public class Window extends BaseWindow { public class Window extends BaseWindow {
private static final String fragmentSourceScaler = """
#version 450
layout(location = 1) in vec2 texCoord;
layout(binding = 0) uniform sampler2D tex;
out vec4 color;
void main() {
//color = vec4(vec2(texCoord).x/1000.f, 0.2f, 0.7f, 1.0f);
vec4 col = texture(tex, texCoord);
if(col.a > 0.0) {
color = col;
}
//color = texelFetch(tex, ivec2(texCoord), 0);
//color = vec4(1.0, 1.0, 1.0, 1.0);
//color = vec4(texCoord.xy, 0.0, 1.0);
}
""";
private static final String vertexSourceScaler = """
#version 450
layout(location = 0) in vec2 pos;
layout(location = 1) in vec2 texCoord;
layout(location = 2) uniform vec2 windowSize;
layout(location = 1) out vec2 out_texCoord;
void main() {
gl_Position = vec4(pos / windowSize * vec2(2.0f, 2.0f) + vec2(-1.0f, -1.0f), 0.0f, 1.0f);
out_texCoord = texCoord;
}
""";
private final Framebuffer framebuffer; private final Framebuffer framebuffer;
private final Framebuffer framebuffer2;
private final Program programScaler;
private final Vec2i size; private final Vec2i size;
private final boolean[] stateMouseClicked; private final boolean[] stateMouseClicked;
private final boolean[] stateMouseDown; private final boolean[] stateMouseDown;
@ -58,6 +30,7 @@ public class Window extends BaseWindow {
private Vec2i windowSize; private Vec2i windowSize;
private final Pipeline2D pipeline2D; private final Pipeline2D pipeline2D;
private final Pipeline3D pipeline3D; private final Pipeline3D pipeline3D;
private final Scaler scaler;
public Window(Vec2i size, String title, Engine engine) { public Window(Vec2i size, String title, Engine engine) {
super(engine); super(engine);
@ -93,19 +66,11 @@ public class Window extends BaseWindow {
glfwSetMouseButtonCallback(window, this::mouseButtonCallback); glfwSetMouseButtonCallback(window, this::mouseButtonCallback);
framebuffer = new Framebuffer(size); framebuffer = new Framebuffer(size);
framebuffer2 = new Framebuffer(size);
textureAtlas = new TextureAtlas(); textureAtlas = new TextureAtlas();
programScaler = new Program(vertexSourceScaler, fragmentSourceScaler);
pipeline2D = new Pipeline2D(framebuffer, textureAtlas); pipeline2D = new Pipeline2D(framebuffer, textureAtlas);
pipeline3D = new Pipeline3D(framebuffer, textureAtlas); pipeline3D = new Pipeline3D(framebuffer, textureAtlas);
scaler = new Scaler(framebuffer);
glProgramUniform2f(programScaler.getProgram(),
programScaler.getUniformLocation("windowSize"),
size.getX(),
size.getY()
);
shouldClose = false; shouldClose = false;
@ -235,113 +200,9 @@ public class Window extends BaseWindow {
@Override @Override
public void runScaler() { public void runScaler() {
//glEnd(); scaler.setStretchMode(stretchMode);
scaler.apply();
scaler.getOutput().copyToScreen();
//Framebuffer.unbind();
framebuffer2.bind();
glViewport(0, 0, windowSize.getX(), windowSize.getY());
programScaler.use();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
framebuffer.bindTexture();
glProgramUniform2f(programScaler.getProgram(),
programScaler.getUniformLocation("windowSize"),
windowSize.getX(),
windowSize.getY()
);
int tlx1 = 0;
int tly1 = 0;
int tlx2 = 0;
int tly2 = 0;
switch(stretchMode) {
case STRETCH -> {
tlx2 = windowSize.getX();
tly2 = windowSize.getY();
}
case ASPECT -> {
float scalex = (float) windowSize.getX() / (float) size.getX();
float scaley = (float) windowSize.getY() / (float) size.getY();
float scale = Math.min(scalex, scaley);
int xoff = (int) (
(windowSize.getX() - size.getX() * scale) / 2
);
int yoff = (int) (
(windowSize.getY() - size.getY() * scale) / 2
);
tlx1 = xoff;
tly1 = yoff;
tlx2 = (int) (xoff + size.getX() * scale);
tly2 = (int) (yoff + size.getY() * scale);
}
case INTEGER -> {
int scalex = windowSize.getX() / size.getX();
int scaley = windowSize.getY() / size.getY();
int scale = Math.max(1, Math.min(scalex, scaley));
int xoff = (windowSize.getX() - size.getX() * scale) / 2;
int yoff = (windowSize.getY() - size.getY() * scale) / 2;
tlx1 = xoff;
tly1 = yoff;
tlx2 = xoff + size.getX() * scale;
tly2 = yoff + size.getY() * scale;
}
}
var texCoordIndex = programScaler.getAttribLocation("texCoord");
glBegin(GL_TRIANGLES);
//counterclockwise triangles
glVertexAttrib2f(texCoordIndex, 0, 1);
glVertex2i(tlx1, tly2);
glVertexAttrib2f(texCoordIndex, 1, 0);
glVertex2i(tlx2, tly1);
glVertexAttrib2f(texCoordIndex, 0, 0);
glVertex2i(tlx1, tly1);
glVertexAttrib2f(texCoordIndex, 1, 0);
glVertex2i(tlx2, tly1);
glVertexAttrib2f(texCoordIndex, 0, 1);
glVertex2i(tlx1, tly2);
glVertexAttrib2f(texCoordIndex, 1, 1);
glVertex2i(tlx2, tly2);
glEnd();
Framebuffer.unbind();
framebuffer2.bindTexture();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
tlx1 = 0;
tly1 = 0;
tlx2 = windowSize.getX();
tly2 = windowSize.getY();
glBegin(GL_TRIANGLES);
//counterclockwise triangles
glVertexAttrib2f(texCoordIndex, 0, 1);
glVertex2i(tlx1, tly2);
glVertexAttrib2f(texCoordIndex, 1, 0);
glVertex2i(tlx2, tly1);
glVertexAttrib2f(texCoordIndex, 0, 0);
glVertex2i(tlx1, tly1);
glVertexAttrib2f(texCoordIndex, 1, 0);
glVertex2i(tlx2, tly1);
glVertexAttrib2f(texCoordIndex, 0, 1);
glVertex2i(tlx1, tly2);
glVertexAttrib2f(texCoordIndex, 1, 1);
glVertex2i(tlx2, tly2);
glEnd();
} }
@Override @Override
@ -379,5 +240,6 @@ public class Window extends BaseWindow {
System.out.printf("new window size %d x %d\n", width, height); System.out.printf("new window size %d x %d\n", width, height);
windowSize = new Vec2i(width, height); windowSize = new Vec2i(width, height);
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
scaler.setOutputSize(windowSize);
} }
} }