Compare commits

..

No commits in common. "f0e92638af0e477f32d3276e46b80e0b7b664b3b" and "4ab459d515d47d2c80097354e8340ef17056eafe" have entirely different histories.

7 changed files with 17 additions and 125 deletions

View File

@ -4,11 +4,10 @@ public class Test {
public static void main(String[] args) { public static void main(String[] args) {
var engine = new Engine(); var engine = new Engine();
var window = engine.openWindow(1280, 720, "Skunkworks"); var window = engine.openWindow(1280, 720, "Skunkworks");
var img2 = engine.loadImage("C:\\art\\pixel stuff.png");
var img = engine.loadImage("C:\\Users\\dani\\Videos\\Screenshot 2022-06-25 17-00-59.png"); var img = engine.loadImage("C:\\Users\\dani\\Videos\\Screenshot 2022-06-25 17-00-59.png");
var tex2 = window.loadTexture("C:\\art\\pixel stuff.png"); //var img = engine.loadImage("C:\\art\\kyoko.png");
//img.drawImage(img2, Vec2i.ZERO); var tex = window.loadTexture("C:\\Users\\dani\\Videos\\Screenshot 2022-06-25 17-00-59.png");
var tex = window.loadTexture(img); System.out.println(img.getPixel(new Vec2i(60, 60)));
while(!window.shouldClose()) { while(!window.shouldClose()) {
window.tick(); window.tick();
@ -18,13 +17,9 @@ public class Test {
// new Color(150, 200, 250) // new Color(150, 200, 250)
//); //);
renderContext.drawTextureRectangle( renderContext.drawTextureRectangle(
new Recti(0, 0, 1280, 720), new Recti(100, 100, 100, 100),
tex tex
); );
renderContext.drawTextureRectangle(
new Recti(new Vec2i(200, 100), tex2.getSize()),
tex2
);
window.renderFinish(renderContext); window.renderFinish(renderContext);
} }
} }

View File

@ -3,11 +3,6 @@ package com.danitheskunk.skunkworks;
import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL11.*;
public class GLRenderContext implements IRenderContext{ public class GLRenderContext implements IRenderContext{
private GLTextureAtlas atlas;
public GLRenderContext(GLTextureAtlas atlas) {
this.atlas = atlas;
}
@Override @Override
public void drawRectangle(Recti rect, Color color) { public void drawRectangle(Recti rect, Color color) {
var tl = rect.getTopLeft(); var tl = rect.getTopLeft();
@ -41,18 +36,11 @@ public class GLRenderContext implements IRenderContext{
@Override @Override
public void drawTextureRectangle(Recti rect, ITexture texture, Color color) { public void drawTextureRectangle(Recti rect, ITexture texture, Color color) {
var tex = (GLTexture)texture;
var tl = rect.getTopLeft(); var tl = rect.getTopLeft();
var tr = rect.getTopRight(); var tr = rect.getTopRight();
var bl = rect.getBottomLeft(); var bl = rect.getBottomLeft();
var br = rect.getBottomRight(); var br = rect.getBottomRight();
var ttl = Vec2i.divf(tex.getTexArea().getTopLeft(), atlas.getSize());
var ttr = Vec2i.divf(tex.getTexArea().getTopRight(), atlas.getSize());
var tbl = Vec2i.divf(tex.getTexArea().getBottomLeft(), atlas.getSize());
var tbr = Vec2i.divf(tex.getTexArea().getBottomRight(), atlas.getSize());
glColor4f( glColor4f(
color.getR() / 255.0f, color.getR() / 255.0f,
color.getG() / 255.0f, color.getG() / 255.0f,
@ -61,18 +49,18 @@ public class GLRenderContext implements IRenderContext{
); );
//counter clockwise triangles //counter clockwise triangles
glTexCoord2d(tbl.getX(), tbl.getY()); glTexCoord2f(0.0f, 1.0f);
glVertex2i(bl.getX(), bl.getY()); glVertex2i(bl.getX(), bl.getY());
glTexCoord2d(ttr.getX(), ttr.getY()); glTexCoord2f(1.0f, 0.0f);
glVertex2i(tr.getX(), tr.getY()); glVertex2i(tr.getX(), tr.getY());
glTexCoord2d(ttl.getX(), ttl.getY()); glTexCoord2f(0.0f, 0.0f);
glVertex2i(tl.getX(), tl.getY()); glVertex2i(tl.getX(), tl.getY());
glTexCoord2d(ttr.getX(), ttr.getY()); glTexCoord2f(1.0f, 0.0f);
glVertex2i(tr.getX(), tr.getY()); glVertex2i(tr.getX(), tr.getY());
glTexCoord2d(tbl.getX(), tbl.getY()); glTexCoord2f(0.0f, 1.0f);
glVertex2i(bl.getX(), bl.getY()); glVertex2i(bl.getX(), bl.getY());
glTexCoord2d(tbr.getX(), tbr.getY()); glTexCoord2f(1.0f, 1.0f);
glVertex2i(br.getX(), bl.getY()); glVertex2i(br.getX(), bl.getY());
} }
} }

View File

@ -2,22 +2,13 @@ package com.danitheskunk.skunkworks;
public class GLTexture implements ITexture { public class GLTexture implements ITexture {
private Recti texArea; private Recti texArea;
Image img; //for re-blitting onto texture atlas
GLTexture(Recti texArea, Image img) { GLTexture(Recti texArea) {
this.texArea = texArea; this.texArea = texArea;
this.img = img;
} }
//setters //setters
@Override
public Vec2i getSize() { return this.img.getSize(); }
void setTexArea(Recti texArea) { void setTexArea(Recti texArea) {
this.texArea = texArea; this.texArea = texArea;
} }
public Recti getTexArea() {
return texArea;
}
} }

View File

@ -1,12 +1,9 @@
package com.danitheskunk.skunkworks; package com.danitheskunk.skunkworks;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import org.lwjgl.stb.STBRPContext;
import org.lwjgl.stb.STBRectPack;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL11.*;
@ -29,63 +26,14 @@ class GLTextureAtlas {
ITexture addTexture(Image img) { ITexture addTexture(Image img) {
//todo: do the actual texture stuff //todo: do the actual texture stuff
//this.img = img; this.img = img;
var texture = new GLTexture(new Recti(new Vec2i(0, 0), img.getSize()), img); update();
var texture = new GLTexture(new Recti(new Vec2i(0, 0), img.getSize()));
textures.add(texture); textures.add(texture);
repack();
updateImage();
uploadToGpu();
return texture; return texture;
} }
void doubleAtlasSize() { void update() {
img = new Image(Vec2i.mul(img.getSize(), 2));
System.out.printf("Resized atlas to %dx%d\n", img.getSize().getX(), img.getSize().getY());
}
void repack() {
int x = 0;
int y = 0;
int height;
textures.sort(new TextureHeightComparator().reversed());
height = textures.get(0).img.getHeight();
for(var tex : textures) {
//texture larger than atlas? resize atlas and try again
if(tex.img.getHeight() > img.getHeight() || tex.img.getWidth() > img.getWidth()) {
doubleAtlasSize();
repack();
return;
}
//row full? start the next row
if(img.getWidth() - x < tex.img.getWidth()) {
x = 0;
y += height;
height = tex.img.getHeight();
//not enough space for new row? resize atlas and try again
if(y + height > tex.img.getHeight()) {
doubleAtlasSize();
repack();
return;
}
}
//take space, advance to right
tex.setTexArea(new Recti(new Vec2i(x, y), tex.img.getSize()));
x += tex.img.getWidth();
}
}
void updateImage() {
for(var tex : textures) {
img.drawImage(tex.img, tex.getTexArea().getPos());
}
}
void uploadToGpu() {
var buf = BufferUtils.createByteBuffer(img.getData().length); var buf = BufferUtils.createByteBuffer(img.getData().length);
buf.put(img.getData()); buf.put(img.getData());
buf.flip(); buf.flip();
@ -102,16 +50,4 @@ class GLTextureAtlas {
buf buf
); );
} }
public Vec2i getSize() {
return img.getSize();
} }
private class TextureHeightComparator implements Comparator<GLTexture> {
@Override
public int compare(GLTexture o1, GLTexture o2) {
return o1.img.getHeight() - o2.img.getHeight();
}
}
}

View File

@ -38,8 +38,8 @@ public class GLWindow implements IWindow {
glEnable(GL_COLOR); glEnable(GL_COLOR);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
renderContext = new GLRenderContext();
textureAtlas = new GLTextureAtlas(); textureAtlas = new GLTextureAtlas();
renderContext = new GLRenderContext(textureAtlas);
shouldClose = false; shouldClose = false;

View File

@ -1,5 +1,5 @@
package com.danitheskunk.skunkworks; package com.danitheskunk.skunkworks;
public interface ITexture { public interface ITexture {
Vec2i getSize();
} }

View File

@ -43,26 +43,8 @@ public final class Vec2i {
public static Vec2i mul(Vec2i a, int b) { public static Vec2i mul(Vec2i a, int b) {
return new Vec2i(a.x * b, a.y * b); return new Vec2i(a.x * b, a.y * b);
} }
public static Vec2i mul(Vec2i a, Vec2i b) {
return new Vec2i(a.x * b.x, a.y * b.y);
}
public static Vec2i div(Vec2i a, int b) { public static Vec2i div(Vec2i a, int b) {
return new Vec2i(a.x / b, a.y / b); return new Vec2i(a.x / b, a.y / b);
} }
public static Vec2i div(Vec2i a, Vec2i b) {
return new Vec2i(a.x / b.x, a.y / b.y);
}
public static Vec2f divf(Vec2i a, double b) {
return new Vec2f(a.x / b, a.y / b);
}
public static Vec2f divf(Vec2i a, Vec2f b) {
return new Vec2f(a.x / b.x, a.y / b.y);
}
public static Vec2f divf(Vec2i a, int b) {
return new Vec2f(a.x / (double)b, a.y / (double)b);
}
public static Vec2f divf(Vec2i a, Vec2i b) {
return new Vec2f(a.x / (double)b.x, a.y / (double)b.y);
}
} }