Skip to content
This repository has been archived by the owner on May 16, 2024. It is now read-only.

Commit

Permalink
Stub out window, painter, and VertexArray, add malloc DataBuilder and…
Browse files Browse the repository at this point in the history
… DataSlice, add in BufferWriters
  • Loading branch information
falkreon committed Nov 28, 2022
1 parent 0d05c13 commit 7348d59
Show file tree
Hide file tree
Showing 8 changed files with 621 additions and 9 deletions.
133 changes: 133 additions & 0 deletions src/main/java/com/playsawdust/glow/gl/BufferWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package com.playsawdust.glow.gl;

import java.io.IOException;

import com.playsawdust.glow.io.DataBuilder;
import com.playsawdust.glow.vecmath.Vector2d;
import com.playsawdust.glow.vecmath.Vector3d;

public interface BufferWriter<T> {
static final int UBYTE_MAX = 0xFF;
static final int USHORT_MAX = 0xFFFF;

public void write(DataBuilder buf, T t) throws IOException;

/**
* Cast an Object to the type written by this BufferWriter, and write it to the buffer. Often the circumstances
* of writing a buffer mean that we don't get any type safety for our writes aside from the contract that any map of
* ShaderAttribute<T> : BufferWriter<T> use the same T for each key-value pair.
*/
@SuppressWarnings("unchecked")
public default void writeUnsafe(DataBuilder buf, Object data) throws IOException {
write(buf, (T)data);
}

public static BufferWriter<Vector3d> makeVec3Writer(BufferWriter<Double> writer) {
return (buf, vec) -> {
writer.write(buf, vec.x());
writer.write(buf, vec.y());
writer.write(buf, vec.z());
};
}

public static BufferWriter<Vector2d> makeVec2Writer(BufferWriter<Double> writer) {
return (buf, vec) -> {
writer.write(buf, vec.x());
writer.write(buf, vec.y());
};
}

public static BufferWriter<Integer> WRITE_INT_TO_INT = (buf, it) -> {
buf.writeI32s(it);
//buf.write((byte) ((it >> 24) & 0xFF));
//buf.write((byte) ((it >> 16) & 0xFF));
//buf.write((byte) ((it >> 8) & 0xFF));
//buf.write((byte) ((it >> 0) & 0xFF));
};

public static BufferWriter<Double> WRITE_DOUBLE_TO_HALF_FLOAT = (buf, it)->{
int FP16_SIGN_SHIFT = 15;
int FP16_EXPONENT_SHIFT = 10;
int FP16_EXPONENT_BIAS = 15;
int FP32_SIGN_SHIFT = 31;
int FP32_EXPONENT_SHIFT = 23;
int FP32_EXPONENT_MASK = 0xff;
int FP32_SIGNIFICAND_MASK = 0x7fffff;
int FP32_EXPONENT_BIAS = 127;

int bits = Float.floatToRawIntBits((float)it.doubleValue());
int s = (bits >>> FP32_SIGN_SHIFT);
int e = (bits >>> FP32_EXPONENT_SHIFT) & FP32_EXPONENT_MASK;
int m = (bits) & FP32_SIGNIFICAND_MASK;

int outE = 0;
int outM = 0;

if (e == 0xff) { // Infinite or NaN
outE = 0x1f;
outM = m != 0 ? 0x200 : 0;
} else {
e = e - FP32_EXPONENT_BIAS + FP16_EXPONENT_BIAS;
if (e >= 0x1f) { // Overflow
outE = 0x31;
} else if (e <= 0) { // Underflow
if (e < -10) {
// The absolute fp32 value is less than MIN_VALUE, flush to +/-0
} else {
// The fp32 value is a normalized float less than MIN_NORMAL,
// we convert to a denorm fp16
m = (m | 0x800000) >> (1 - e);
if ((m & 0x1000) != 0)
m += 0x2000;
outM = m >> 13;
}
} else {
outE = e;
outM = m >> 13;
if ((m & 0x1000) != 0) {
// Round to nearest "0.5" up
int out = (outE << FP16_EXPONENT_SHIFT) | outM;
out++;

short result = (short) (out | (s << FP16_SIGN_SHIFT));
buf.writeI16u(result);
return;
}
}
}

short result = (short) ((s << FP16_SIGN_SHIFT) | (outE << FP16_EXPONENT_SHIFT) | outM);
buf.writeI16u(result);
};

public static BufferWriter<Double> WRITE_DOUBLE_TO_BYTE_NORMALIZED = (buf, it)->{
double d = it.doubleValue()*Byte.MAX_VALUE;
buf.write((byte) d);
};

public static BufferWriter<Double> WRITE_DOUBLE_TO_UBYTE_NORMALIZED = (buf, it)->{
buf.write((int) (it*UBYTE_MAX));
};

public static BufferWriter<Double> WRITE_DOUBLE_TO_SHORT_NORMALIZED = (buf, it)->{
double d = it.doubleValue()*Short.MAX_VALUE;
buf.writeI16s((short)d);
};

public static BufferWriter<Double> WRITE_DOUBLE_TO_USHORT_NORMALIZED = (buf, it)->{
buf.writeI16u((int) (it*USHORT_MAX));
};

public static BufferWriter<Double> WRITE_DOUBLE_TO_BYTE = (buf, it)->{ buf.write((byte)it.intValue()); };
public static BufferWriter<Double> WRITE_DOUBLE_TO_SHORT = (buf, it)->{ buf.writeI16s((short)it.intValue()); };
public static BufferWriter<Double> WRITE_DOUBLE_TO_INT = (buf, it)->{ buf.writeI32s(it.intValue()); };
public static BufferWriter<Double> WRITE_DOUBLE_TO_FLOAT = (buf, it)->{ buf.writeF32s(it.floatValue()); };
public static BufferWriter<Double> WRITE_DOUBLE_TO_DOUBLE = (buf, it)->{ buf.writeF64s(it.doubleValue()); };

public static BufferWriter<Vector2d> WRITE_VEC2_TO_HALF_FLOATS = makeVec2Writer(WRITE_DOUBLE_TO_HALF_FLOAT);
public static BufferWriter<Vector2d> WRITE_VEC2_TO_FLOATS = makeVec2Writer(WRITE_DOUBLE_TO_FLOAT);

public static BufferWriter<Vector3d> WRITE_VEC3_TO_HALF_FLOATS = makeVec3Writer(WRITE_DOUBLE_TO_HALF_FLOAT);
public static BufferWriter<Vector3d> WRITE_VEC3_TO_FLOATS = makeVec3Writer(WRITE_DOUBLE_TO_FLOAT);
public static BufferWriter<Vector3d> WRITE_VEC3_TO_DOUBLES = makeVec3Writer(WRITE_DOUBLE_TO_DOUBLE);
}
82 changes: 73 additions & 9 deletions src/main/java/com/playsawdust/glow/gl/FramebufferPainter.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
package com.playsawdust.glow.gl;

import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;

import com.playsawdust.glow.image.ImageData;
import com.playsawdust.glow.image.color.BlendMode;
import com.playsawdust.glow.image.color.Colors;
import com.playsawdust.glow.image.color.RGBColor;
import com.playsawdust.glow.render.Painter;

public class FramebufferPainter implements Painter {


private int width;
private int height;

public FramebufferPainter() {

}

public void startPainting(int width, int height) {
//TODO: Attach shaders

this.width = width;
this.height = height;
}

@Override
public void drawImage(ImageData image, int destX, int destY, int srcX, int srcY, int width, int height, float opacity) {
for(int y = 0; y < height; y++) {
Expand All @@ -35,18 +54,63 @@ public void drawPixel(int x, int y, RGBColor color) {
//TODO: Implement - we're going to try clearing the screen or drawing a fullscreen quad with a scissor to the
//indicated pixel, and see how it performs.

/*
float[] screenQuad = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f

float[] quad = {
x, y, 0.0f,
x+1, y, 0.0f,
x+1, y+1, 0.0f,
x, y, 0.0f,
x+1, y+1, 0.0f,
x, y+1, 0.0f
};

int buf = GL20.glGenBuffers();
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, buf);
GL20.glBufferData(GL20.GL_ARRAY_BUFFER, buf, GL20.GL_STATIC_DRAW);
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);

int arr = GL30.glGenVertexArrays();
GL30.glBindVertexArray(arr);
/*
int vertexAttrib = GL30.glGetAttribLocation(program,"vertex")));
*/

GL20.glEnableVertexAttribArray(vertexAttrib);
glBindBuffer(GL_ARRAY_BUFFER,vBuffer);
glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0 );
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);

GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);*/
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 6);

GL30.glBindVertexArray(0);

GL30.glDeleteVertexArrays(arr);
GL20.glDeleteBuffers(buf);

}

@Override
public void clear(RGBColor color) {
GL11.glClearColor(
(float) Colors.linearElementToGamma(color.r()),
(float) Colors.linearElementToGamma(color.g()),
(float) Colors.linearElementToGamma(color.b()),
1f);

GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
}

@Override
public int getWidth() {
return width;
}

@Override
public int getHeight() {
return height;
}

}
28 changes: 28 additions & 0 deletions src/main/java/com/playsawdust/glow/gl/GLWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;

import com.playsawdust.glow.gl.offheap.GLResource;
import com.playsawdust.glow.render.Painter;
import com.playsawdust.glow.vecmath.Rect2d;
import com.playsawdust.glow.vecmath.Vector2d;

Expand All @@ -29,6 +32,7 @@ public class GLWindow implements GLResource {


private final long handle;
private final FramebufferPainter framebufferPainter;

public GLWindow(int width, int height, GLVersion version) {
GLFWErrorCallback.createPrint(System.out).set(); //System.out for now; callback later.
Expand Down Expand Up @@ -57,7 +61,11 @@ public GLWindow(int width, int height, GLVersion version) {
GLFW.glfwSetWindowShouldClose(window, true);
});

framebufferPainter = new FramebufferPainter();

GLFW.glfwMakeContextCurrent(handle);
GL.createCapabilities();
GL11.glClearColor(0,0,0,1);
//int profile = GLFW.glfwGetWindowAttrib(handle, GLFW.GLFW_OPENGL_PROFILE);
//if (profile == GLFW.GLFW_OPENGL_CORE_PROFILE) System.out.println("OPENGL Core Profile Obtained");
//else if (profile == GLFW.GLFW_OPENGL_COMPAT_PROFILE) System.out.println("OPENGL Compat Profile Obtained");
Expand Down Expand Up @@ -177,6 +185,26 @@ public void poll() {
GLFW.glfwPollEvents();
}

/**
* Returns a Painter that will paint immediately to the next frame's framebuffer for this window. Binds any shaders
* necessary to do this.
*/
public Painter startPainting() {
int width = 1;
int height = 1;

try (MemoryStack stack = MemoryStack.stackPush() ) {
IntBuffer xBuf = stack.mallocInt(1);
IntBuffer yBuf = stack.mallocInt(1);

GLFW.glfwGetFramebufferSize(handle, xBuf, yBuf);
width = xBuf.get();
height = yBuf.get();
}
framebufferPainter.startPainting(width, height);
return framebufferPainter;
}

public void swapBuffers() {
GLFW.glfwSwapBuffers(handle);
}
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/com/playsawdust/glow/gl/StandardShaders.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.playsawdust.glow.gl;

public class StandardShaders {
public static final String SIMPLE_VERTEX = """
#version 330 core
layout (location = 0) in vec3 position;
void main()
{
gl_Position = vec4(position.x, position.y, position.z, 1.0);
}
""";

public static final String SIMPLE_FRAGMENT = """
#version 330 core
out vec4 FragColor;
uniform vec4 diffuse_color;
void main()
{
FragColor = diffuse_color;
}
""";
}
Loading

0 comments on commit 7348d59

Please sign in to comment.