Compare commits
No commits in common. "0f320d00ae26a4d1dbdc075c71a75f8960f79efb" and "3102e1c909feb3830e3d0cb0a64e5e76bd119a9f" have entirely different histories.
0f320d00ae
...
3102e1c909
|
@ -1,41 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -36,7 +36,12 @@ 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,
|
||||||
|
@ -77,23 +82,4 @@ 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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
package com.danitheskunk.skunkworks.backends.gl;
|
|
||||||
|
|
||||||
public class ProgramCopy extends Program {
|
|
||||||
private static final String fragmentSource = """
|
|
||||||
#version 450
|
|
||||||
layout(location = 1) in vec2 texCoord;
|
|
||||||
layout(binding = 0) uniform sampler2D tex;
|
|
||||||
out vec4 color;
|
|
||||||
void main() {
|
|
||||||
vec4 col = texture(tex, texCoord);
|
|
||||||
if(col.a > 0.0) {
|
|
||||||
color = col;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
""";
|
|
||||||
private static final String vertexSource = """
|
|
||||||
#version 450
|
|
||||||
layout(location = 0) in vec2 pos;
|
|
||||||
layout(location = 1) out vec2 out_texCoord;
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(pos, 0.0f, 1.0f);
|
|
||||||
out_texCoord = vec2(pos.x * 0.5 + 0.5, pos.y * 0.5 + 0.5);
|
|
||||||
}
|
|
||||||
""";
|
|
||||||
private ProgramCopy() {
|
|
||||||
super(vertexSource, fragmentSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ProgramCopy instance;
|
|
||||||
|
|
||||||
public static ProgramCopy getInstance() {
|
|
||||||
if(instance == null) {
|
|
||||||
instance = new ProgramCopy();
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,8 +19,36 @@ 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;
|
||||||
|
@ -30,7 +58,6 @@ 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);
|
||||||
|
@ -66,11 +93,19 @@ 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;
|
||||||
|
|
||||||
|
@ -200,9 +235,113 @@ public class Window extends BaseWindow {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runScaler() {
|
public void runScaler() {
|
||||||
scaler.setStretchMode(stretchMode);
|
//glEnd();
|
||||||
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
|
||||||
|
@ -240,6 +379,5 @@ 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue