started 3d code
This commit is contained in:
parent
fe6625aa12
commit
7339ca69a7
|
@ -6,6 +6,7 @@ import com.danitheskunk.skunkworks.audio.nodes.Mixer;
|
||||||
import com.danitheskunk.skunkworks.audio.nodes.Node;
|
import com.danitheskunk.skunkworks.audio.nodes.Node;
|
||||||
import com.danitheskunk.skunkworks.audio.nodes.SamplePlayer;
|
import com.danitheskunk.skunkworks.audio.nodes.SamplePlayer;
|
||||||
import com.danitheskunk.skunkworks.gfx.IRenderContext;
|
import com.danitheskunk.skunkworks.gfx.IRenderContext;
|
||||||
|
import com.danitheskunk.skunkworks.gfx.IRenderContext3D;
|
||||||
import com.danitheskunk.skunkworks.gfx.ITexture;
|
import com.danitheskunk.skunkworks.gfx.ITexture;
|
||||||
import com.danitheskunk.skunkworks.gfx.font.IFont;
|
import com.danitheskunk.skunkworks.gfx.font.IFont;
|
||||||
import com.danitheskunk.skunkworks.nodes.NodeRoot;
|
import com.danitheskunk.skunkworks.nodes.NodeRoot;
|
||||||
|
@ -48,15 +49,23 @@ public abstract class BaseGame {
|
||||||
//todo: frame rate control
|
//todo: frame rate control
|
||||||
rootNode.tick();
|
rootNode.tick();
|
||||||
update(1.0 / 60.0);
|
update(1.0 / 60.0);
|
||||||
|
var rc3d = window.renderStart3D();
|
||||||
|
render3D(rc3d);
|
||||||
|
window.renderFinish3D(rc3d);
|
||||||
var rc = window.renderStart();
|
var rc = window.renderStart();
|
||||||
renderPre(rc);
|
renderPre(rc);
|
||||||
rootNode.render(rc);
|
rootNode.render(rc);
|
||||||
render(rc);
|
render(rc);
|
||||||
window.renderFinish(rc);
|
window.renderFinish(rc);
|
||||||
|
|
||||||
|
window.runScaler();
|
||||||
audioEngine.refill();
|
audioEngine.refill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void render3D(IRenderContext3D rc3d) {
|
||||||
|
}
|
||||||
|
|
||||||
protected void init() {
|
protected void init() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package com.danitheskunk.skunkworks;
|
package com.danitheskunk.skunkworks;
|
||||||
|
|
||||||
import com.danitheskunk.skunkworks.gfx.IRenderContext;
|
import com.danitheskunk.skunkworks.gfx.*;
|
||||||
import com.danitheskunk.skunkworks.gfx.ITexture;
|
|
||||||
import com.danitheskunk.skunkworks.gfx.Image;
|
|
||||||
import com.danitheskunk.skunkworks.gfx.NineSlice;
|
|
||||||
import com.danitheskunk.skunkworks.gfx.font.IFont;
|
import com.danitheskunk.skunkworks.gfx.font.IFont;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -31,6 +28,13 @@ public interface IWindow {
|
||||||
|
|
||||||
IRenderContext renderStart();
|
IRenderContext renderStart();
|
||||||
|
|
||||||
|
void renderFinish3D(IRenderContext3D context);
|
||||||
|
|
||||||
|
IRenderContext3D renderStart3D();
|
||||||
|
|
||||||
|
//needs to be run after rendering
|
||||||
|
void runScaler();
|
||||||
|
|
||||||
void setDebug(boolean on);
|
void setDebug(boolean on);
|
||||||
|
|
||||||
boolean shouldClose();
|
boolean shouldClose();
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.danitheskunk.skunkworks;
|
||||||
|
|
||||||
|
public final class Mat4f {
|
||||||
|
private final double[] data;
|
||||||
|
|
||||||
|
public Mat4f() {
|
||||||
|
data = new double[16];
|
||||||
|
set(0, 0, 1.0);
|
||||||
|
set(1, 1, 1.0);
|
||||||
|
set(2, 2, 1.0);
|
||||||
|
set(3, 3, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double get(int x, int y) {
|
||||||
|
return data[x + y * 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(int x, int y, double val) {
|
||||||
|
data[x + y * 4] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double[] asArray() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float[] asFloatArray() {
|
||||||
|
var arr = new float[16];
|
||||||
|
for(int i = 0; i < 16; ++i) {
|
||||||
|
arr[i] = (float)data[i];
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat4f perspective(
|
||||||
|
double fovy, double aspect, double zNear, double zFar
|
||||||
|
) {
|
||||||
|
/*
|
||||||
|
T const tanHalfFovy = tan(fovy / static_cast<T>(2));
|
||||||
|
|
||||||
|
mat<4, 4, T, defaultp> Result(static_cast<T>(0));
|
||||||
|
Result[0][0] = static_cast<T>(1) / (aspect * tanHalfFovy);
|
||||||
|
Result[1][1] = static_cast<T>(1) / (tanHalfFovy);
|
||||||
|
Result[2][2] = - (zFar + zNear) / (zFar - zNear);
|
||||||
|
Result[2][3] = - static_cast<T>(1);
|
||||||
|
Result[3][2] = - (static_cast<T>(2) * zFar * zNear) / (zFar - zNear);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Result[2][2] = zFar / (zFar - zNear);
|
||||||
|
Result[2][3] = static_cast<T>(1);
|
||||||
|
Result[3][2] = -(zFar * zNear) / (zFar - zNear);
|
||||||
|
*/
|
||||||
|
var mat = new Mat4f();
|
||||||
|
double tanHalfFovy = Math.tan(fovy / 2.0);
|
||||||
|
mat.set(0, 0, 1.0 / (aspect * tanHalfFovy));
|
||||||
|
mat.set(1, 1, 1.0 / tanHalfFovy);
|
||||||
|
/*
|
||||||
|
mat.set(2, 2, - (zFar + zNear) / (zFar - zNear));
|
||||||
|
mat.set(2, 3, -1.0);
|
||||||
|
mat.set(3, 2, -(2.0 * zFar * zNear) / (zFar - zNear));
|
||||||
|
*/
|
||||||
|
mat.set(2, 2, zFar / (zFar - zNear));
|
||||||
|
mat.set(2, 3, 1.0);
|
||||||
|
mat.set(3, 2, -(zFar * zNear) / (zFar - zNear));
|
||||||
|
//mat.set(3, 3, 0);
|
||||||
|
return mat;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.danitheskunk.skunkworks;
|
||||||
|
|
||||||
|
import com.danitheskunk.skunkworks.gfx.IRenderContext;
|
||||||
|
import com.danitheskunk.skunkworks.gfx.IRenderContext3D;
|
||||||
|
|
||||||
|
public class Test3D extends BaseGame {
|
||||||
|
public Test3D() {
|
||||||
|
super(new Vec2i(1920, 1080), "Skunkworks 3d test");
|
||||||
|
}
|
||||||
|
|
||||||
|
static public void main(String[] args) {
|
||||||
|
new Test3D().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void render3D(IRenderContext3D rc) {
|
||||||
|
rc.renderTriangle(new Vec3f(-10, -10, 0),
|
||||||
|
new Vec3f(10, -10, 0),
|
||||||
|
new Vec3f(10, 10, -1)
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.danitheskunk.skunkworks;
|
||||||
|
|
||||||
|
public final class Vec3f {
|
||||||
|
public static Vec3f ZERO = new Vec3f(0, 0, 0);
|
||||||
|
public static Vec3f ONE = new Vec3f(1, 1, 1);
|
||||||
|
private final double x, y, z;
|
||||||
|
|
||||||
|
public Vec3f(double x, double y, double z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getZ() {
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.danitheskunk.skunkworks.backends.gl;
|
||||||
|
|
||||||
|
import com.danitheskunk.skunkworks.Vec3f;
|
||||||
|
import com.danitheskunk.skunkworks.gfx.BaseRenderContext3D;
|
||||||
|
import static org.lwjgl.opengl.GL46.*;
|
||||||
|
|
||||||
|
public class RenderContext3D extends BaseRenderContext3D {
|
||||||
|
@Override
|
||||||
|
public void renderTriangle(Vec3f p1, Vec3f p2, Vec3f p3) {
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
|
||||||
|
glVertex3d(p1.getX(), p1.getY(), p1.getZ());
|
||||||
|
glVertex3d(p2.getX(), p2.getY(), p2.getZ());
|
||||||
|
glVertex3d(p3.getX(), p3.getY(), p3.getZ());
|
||||||
|
|
||||||
|
/*
|
||||||
|
glVertex3f((float) p1.getX(), (float) p1.getY(), (float) p1.getZ());
|
||||||
|
glVertex3f((float) p2.getX(), (float) p2.getY(), (float) p2.getZ());
|
||||||
|
glVertex3f((float) p3.getX(), (float) p3.getY(), (float) p3.getZ());
|
||||||
|
*/
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package com.danitheskunk.skunkworks.backends.gl;
|
||||||
|
|
||||||
import com.danitheskunk.skunkworks.*;
|
import com.danitheskunk.skunkworks.*;
|
||||||
import com.danitheskunk.skunkworks.gfx.IRenderContext;
|
import com.danitheskunk.skunkworks.gfx.IRenderContext;
|
||||||
|
import com.danitheskunk.skunkworks.gfx.IRenderContext3D;
|
||||||
import com.danitheskunk.skunkworks.gfx.ITexture;
|
import com.danitheskunk.skunkworks.gfx.ITexture;
|
||||||
import com.danitheskunk.skunkworks.gfx.Image;
|
import com.danitheskunk.skunkworks.gfx.Image;
|
||||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||||
|
@ -46,7 +47,28 @@ public class Window extends BaseWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""";
|
""";
|
||||||
|
private static String vertexSource3D = """
|
||||||
|
#version 450
|
||||||
|
layout(location = 0) in vec3 pos;
|
||||||
|
//layout(location = 1) in ivec2 texCoord;
|
||||||
|
layout(location = 2) uniform mat4 projection;
|
||||||
|
layout(location = 1) out vec2 out_texCoord;
|
||||||
|
void main() {
|
||||||
|
gl_Position = projection * vec4(pos, 1.0f);
|
||||||
|
out_texCoord.x = pos.z;
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
private static String fragmentSource3D = """
|
||||||
|
#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);
|
||||||
|
//color = texture(tex, texCoord);
|
||||||
|
color = vec4(1.0, texCoord.x / 2, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
""";
|
||||||
private static String vertexSourceScaler = """
|
private static String vertexSourceScaler = """
|
||||||
#version 450
|
#version 450
|
||||||
layout(location = 0) in vec2 pos;
|
layout(location = 0) in vec2 pos;
|
||||||
|
@ -75,8 +97,10 @@ public class Window extends BaseWindow {
|
||||||
}
|
}
|
||||||
""";
|
""";
|
||||||
private final Program program;
|
private final Program program;
|
||||||
|
private final Program program3D;
|
||||||
private final Program programScaler;
|
private final Program programScaler;
|
||||||
private final RenderContext renderContext;
|
private final RenderContext renderContext;
|
||||||
|
private final RenderContext3D renderContext3D;
|
||||||
private final Vec2i size;
|
private final Vec2i size;
|
||||||
private Vec2i windowSize;
|
private Vec2i windowSize;
|
||||||
private final TextureAtlas textureAtlas;
|
private final TextureAtlas textureAtlas;
|
||||||
|
@ -87,6 +111,7 @@ public class Window extends BaseWindow {
|
||||||
private final int framebufferTex;
|
private final int framebufferTex;
|
||||||
private boolean[] stateMouseClicked;
|
private boolean[] stateMouseClicked;
|
||||||
private boolean[] stateMouseDown;
|
private boolean[] stateMouseDown;
|
||||||
|
private Mat4f projection;
|
||||||
|
|
||||||
public Window(Vec2i size, String title, Engine engine) {
|
public Window(Vec2i size, String title, Engine engine) {
|
||||||
super(engine);
|
super(engine);
|
||||||
|
@ -113,7 +138,7 @@ public class Window extends BaseWindow {
|
||||||
GL.createCapabilities();
|
GL.createCapabilities();
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glOrtho(0.0f, size.getX(), size.getY(), 0.0f, 0.0f, 1.0f);
|
//glOrtho(0.0f, size.getX(), size.getY(), 0.0f, 0.0f, 1.0f);
|
||||||
glEnable(GL_COLOR);
|
glEnable(GL_COLOR);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
@ -148,8 +173,11 @@ public class Window extends BaseWindow {
|
||||||
|
|
||||||
textureAtlas = new TextureAtlas();
|
textureAtlas = new TextureAtlas();
|
||||||
program = new Program(vertexSource, fragmentSource);
|
program = new Program(vertexSource, fragmentSource);
|
||||||
|
program3D = new Program(vertexSource3D, fragmentSource3D);
|
||||||
programScaler = new Program(vertexSourceScaler, fragmentSourceScaler);
|
programScaler = new Program(vertexSourceScaler, fragmentSourceScaler);
|
||||||
|
|
||||||
|
projection = Mat4f.perspective(Math.PI / 2, 16.0 / 9.0, 0.1, 100.0);
|
||||||
|
|
||||||
renderContext = new RenderContext(size,
|
renderContext = new RenderContext(size,
|
||||||
textureAtlas,
|
textureAtlas,
|
||||||
program.getAttribLocation("texCoord"),
|
program.getAttribLocation("texCoord"),
|
||||||
|
@ -157,6 +185,9 @@ public class Window extends BaseWindow {
|
||||||
program.getUniformLocation("texSize"),
|
program.getUniformLocation("texSize"),
|
||||||
program.getUniformLocation("tint")
|
program.getUniformLocation("tint")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
renderContext3D = new RenderContext3D();
|
||||||
|
|
||||||
glProgramUniform2f(program.program,
|
glProgramUniform2f(program.program,
|
||||||
program.getUniformLocation("windowSize"),
|
program.getUniformLocation("windowSize"),
|
||||||
size.getX(),
|
size.getX(),
|
||||||
|
@ -235,6 +266,46 @@ public class Window extends BaseWindow {
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IRenderContext renderStart() {
|
||||||
|
program.use();
|
||||||
|
textureAtlas.bind();
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||||
|
glViewport(0, 0, size.getX(), size.getY());
|
||||||
|
textureAtlas.update();
|
||||||
|
glClearColor(0.f, 0.f, 0.f, 0.0f);
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
//glBegin(GL_TRIANGLES);
|
||||||
|
return renderContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void renderFinish3D(IRenderContext3D context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IRenderContext3D renderStart3D() {
|
||||||
|
program3D.use();
|
||||||
|
textureAtlas.bind();
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||||
|
glViewport(0, 0, size.getX(), size.getY());
|
||||||
|
textureAtlas.update();
|
||||||
|
glClearColor(0.f, 1.f, 0.f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
//glBegin(GL_TRIANGLES);
|
||||||
|
glUniformMatrix4fv(
|
||||||
|
program3D.getUniformLocation("projection"),
|
||||||
|
true,
|
||||||
|
projection.asFloatArray()
|
||||||
|
);
|
||||||
|
|
||||||
|
return renderContext3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runScaler() {
|
||||||
//glEnd();
|
//glEnd();
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
@ -320,19 +391,6 @@ public class Window extends BaseWindow {
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IRenderContext renderStart() {
|
|
||||||
program.use();
|
|
||||||
textureAtlas.bind();
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
|
||||||
glViewport(0, 0, size.getX(), size.getY());
|
|
||||||
textureAtlas.update();
|
|
||||||
glClearColor(0.f, 0.f, 0.f, 0.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
program.use();
|
|
||||||
//glBegin(GL_TRIANGLES);
|
|
||||||
return renderContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDebug(boolean on) {
|
public void setDebug(boolean on) {
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.danitheskunk.skunkworks.gfx;
|
||||||
|
|
||||||
|
import com.danitheskunk.skunkworks.Mat4f;
|
||||||
|
|
||||||
|
abstract public class BaseRenderContext3D implements IRenderContext3D {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.danitheskunk.skunkworks.gfx;
|
||||||
|
|
||||||
|
import com.danitheskunk.skunkworks.Vec3f;
|
||||||
|
|
||||||
|
public interface IRenderContext3D {
|
||||||
|
void renderTriangle(Vec3f p1, Vec3f p2, Vec3f p3);
|
||||||
|
}
|
Loading…
Reference in New Issue