Ich habs jetzt einfach mal gemacht… Sorry das ich zu faul / zeitarm für ein kskb bin x.x
AAaaallso. Erst mal alles was dazu gehört:
alles was zur lib gehört…
package de.skysoldier.kskb;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
import de.skysoldier.kskb.AGLCaps.AGLDisplayCap;
import de.skysoldier.kskb.AGLCaps.AGLProjectionType;
import de.skysoldier.kskb.AGLCaps.AGLShaderType;
class AGL {
private static DisplayMode actualMode = null;
private static int genId;
public static void initRenderController() {
AGLRenderController.init();
}
public static void render() {
AGLRenderController.render();
}
public static AGLView createView(AGLShaderProgram shaderProgram,
String cameraUniformName, AGLProjectionType projectionType) {
shaderProgram.bind();
AGLCamera camera = new AGLCamera(projectionType);
camera.assignToUniform(new AGLGlslUniform.Mat4f(shaderProgram,
cameraUniformName));
camera.update();
AGLShaderProgram.unbind();
return new AGLView(shaderProgram, camera);
}
public static void unbindViews(AGLView... views) {
AGLRenderController.unbindViews(views);
}
public static void unbindViews() {
AGLRenderController.unbindViews();
}
public static void bindViews(AGLView... views) {
AGLRenderController.bindViews(views);
}
public static AGLShaderProgram createShaderProgram(
InputStream vertexInputStream, InputStream fragmentInputStream,
AGLGlslAttribute attributes[]) {
AGLShaderProgram program = new AGLShaderProgram();
program.load(vertexInputStream, fragmentInputStream, attributes);
return program;
}
public static int genId() {
return genId++;
}
public static boolean running() {
return !Display.isCloseRequested();
}
public static String getInputStreamContent(InputStream stream) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(stream));
String content = "";
String line = "";
try {
while ((line = reader.readLine()) != null) {
content += line + "
";
}
return content;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static InputStream getInputStreamFromRoot(Class<?> clazz,
String fileName) {
return clazz.getClassLoader().getResourceAsStream(fileName);
}
public static void createLwjglContext(AGLDisplayCap cap) {
DisplayMode mode = null;
if (cap == AGLDisplayCap.FULLSCREEN) {
try {
Display.setFullscreen(true);
} catch (LWJGLException e) {
e.printStackTrace();
}
mode = getFullscreenDisplayMode();
} else if (cap == AGLDisplayCap.NONE) {
mode = getDisplayMode(800, 600);
}
createLwjglContext(mode);
}
public static void createLwjglContext(int width, int height) {
createLwjglContext(getDisplayMode(width, height));
}
public static void createLwjglContext(DisplayMode mode) {
if (actualMode == null) {
try {
Display.setDisplayMode(mode);
Display.create();
actualMode = mode;
} catch (LWJGLException e) {
e.printStackTrace();
}
} else {
throw new AGLException("Lwjgl Context already created.");
}
}
public static DisplayMode getDisplayMode(int width, int height) {
return new DisplayMode(width, height);
}
public static DisplayMode getFullscreenDisplayMode() {
DisplayMode fullscreenMode = Display.getDesktopDisplayMode();
if (!fullscreenMode.isFullscreenCapable()) {
throw new AGLException("Screen does'nt support Fullscreen.");
}
return fullscreenMode;
}
private static DisplayMode getDisplayMode() {
if (actualMode == null) {
throw new AGLException("Lwjgl Context not created yet.");
}
return actualMode;
}
public static int getDisplayWidth() {
return getDisplayMode().getWidth();
}
public static int getDisplayHeight() {
return getDisplayMode().getHeight();
}
}
abstract class AGLAbstractMovableObject implements AGLMovable {
private float speedx, speedy, speedz;
public void setSpeedX(float speed) {
speedx = speed;
}
public void setSpeedY(float speed) {
speedy = speed;
}
public void setSpeedZ(float speed) {
speedz = speed;
}
public float getSpeedX() {
return speedx;
}
public float getSpeedY() {
return speedy;
}
public float getSpeedZ() {
return speedz;
}
public abstract void moveX(float delta);
public abstract void moveY(float delta);
public abstract void moveZ(float delta);
public abstract void update();
}
class AGLException extends RuntimeException {
public AGLException(String error) {
super(error);
}
}
class AGLCamera {
private Matrix4f camera;
private Matrix4f projection;
private AGLProjectionType type;
private AGLGlslUniform.Mat4f cameraUniform;
public AGLCamera(AGLProjectionType type) {
this.camera = placeOrigin();
this.type = type;
standardProjection();
}
public Matrix4f placeOrigin() {
return new Matrix4f();
}
public void standardProjection() {
setProjection(0.1f, 100.0f, 150f);
}
public void setProjection(float near, float far, float fov) {
projection = new Matrix4f();
float aspect = (float) Display.getWidth() / (float) Display.getHeight();
float top = (float) (Math.tan(Math.toRadians(fov) / 2));
float bottom = -top;
float right = top * aspect;
float left = -right;
if (type == AGLProjectionType.PERSPECTIVE) {
projection.m00 = (2 * near) / (right - left);
projection.m02 = (right + left) / (right - left);
projection.m11 = (2 * near) / (top - bottom);
projection.m12 = (top + bottom) / (top - bottom);
projection.m22 = -(far + near) / (far - near);
projection.m23 = -(2 * far * near) / (far - near);
projection.m32 = -1;
projection.m33 = 0;
} else if (type == AGLProjectionType.ORTHOGONAL) {
projection.m00 = 2 / (right - left);
projection.m03 = -(right + left) / (right - left);
projection.m11 = 2 / (top - bottom);
projection.m13 = -(top + bottom) / (top - bottom);
projection.m22 = -2 / (far - near);
}
}
public void assignToUniform(AGLGlslUniform.Mat4f uniform) {
this.cameraUniform = uniform;
}
public void update() {
cameraUniform.putData(Matrix4f.mul(projection, camera, new Matrix4f()));
cameraUniform.updateData();
}
public AGLProjectionType getType() {
return type;
}
}
class AGLFragmentShader extends AGLShader {
public AGLFragmentShader() {
type = AGLShaderType.FRAGMENT;
}
protected int getGLType() {
return GL20.GL_FRAGMENT_SHADER;
}
}
class AGLGlslAttribute {
private String name;
private int size;
private boolean normalized;
private int id;
public AGLGlslAttribute(String name, int size, boolean normalized, int id) {
this.name = name;
this.size = size;
this.normalized = normalized;
this.id = id;
}
protected String getName() {
return name;
}
protected int getSize() {
return size;
}
protected boolean isNormalized() {
return normalized;
}
protected int getId() {
return id;
}
public static AGLGlslAttribute createAttributeVec3(String name) {
return new AGLGlslAttribute(name, 3, false, AGL.genId());
}
}
abstract class AGLGlslUniform {
private int id;
private AGLShaderProgram shaderProgram;
private FloatBuffer data;
public AGLGlslUniform(AGLShaderProgram shaderProgram, String name) {
this.id = GL20.glGetUniformLocation(shaderProgram.getId(), name);
this.shaderProgram = shaderProgram;
data = BufferUtils.createFloatBuffer(getSize());
}
public void putData(float data[]) {
this.data.clear();
this.data.put(data);
this.data.flip();
}
protected int getId() {
return id;
}
protected AGLShaderProgram getShaderProgram() {
return shaderProgram;
}
protected abstract int getSize();
protected abstract void updateData();
public static class Mat4f extends AGLGlslUniform {
public Mat4f(AGLShaderProgram shaderProgram, String name) {
super(shaderProgram, name);
}
protected int getSize() {
return 16;
}
protected void putData(Matrix4f matrix) {
matrix.store(super.data);
super.data.flip();
}
protected void updateData() {
GL20.glUniformMatrix4(super.id, false, super.data);
}
}
public static class Vec3f extends AGLGlslUniform {
public Vec3f(AGLShaderProgram shaderProgram, String name) {
super(shaderProgram, name);
}
protected int getSize() {
return 3;
}
protected void updateData() {
GL20.glUniform3f(super.id, super.data.get(0), super.data.get(1),
super.data.get(2));
super.data.rewind();
}
}
}
class AGLMesh {
private AGLVao vao;
private AGLVbo vbo;
public AGLMesh(AGLVao vao, AGLVbo vbo) {
this.vao = vao;
this.vbo = vbo;
}
public AGLVao getVao() {
return vao;
}
public AGLVbo getVbo() {
return vbo;
}
}
interface AGLMovable {
public void setSpeedX(float speed);
public void setSpeedY(float speed);
public void setSpeedZ(float speed);
public float getSpeedX();
public float getSpeedY();
public float getSpeedZ();
public void moveX(float delta);
public void moveY(float delta);
public void moveZ(float delta);
public void update();
}
class AGLRenderController {
private static ArrayList<AGLView> activeViews = new ArrayList<>();
private static long lastFrame;
private static long thisFrame;
private static float delta;
private static float fps;
private AGLRenderController() {
}
public static void init() {
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
lastFrame = System.nanoTime();
}
public static void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
thisFrame = System.nanoTime();
delta = thisFrame - lastFrame;
lastFrame = thisFrame;
fps = (float) 1e9 / delta;
for (AGLView view : activeViews) {
view.render();
}
Display.update();
}
protected static ArrayList<AGLView> getActiveViews() {
return activeViews;
}
public static float getFps() {
return fps;
}
public static float getDelta() {
return delta;
}
public static float getDeltaMs() {
return (float) (delta / 1e6);
}
protected static void bindViews(AGLView... views) {
for (AGLView view : views) {
activeViews.add(view);
}
}
protected static void unbindViews(AGLView... views) {
for (AGLView view : views) {
activeViews.remove(view);
}
}
protected static void unbindViews() {
activeViews.clear();
}
}
class AGLRenderObject extends AGLAbstractMovableObject {
private AGLMesh mesh;
private Matrix4f model;
private AGLGlslUniform.Mat4f modelUniform;
private boolean waitingForUniformUpdate;
protected AGLRenderObject(AGLMesh mesh) {
this.mesh = mesh;
this.model = new Matrix4f();
this.waitingForUniformUpdate = false;
}
protected void render() {
mesh.getVao().bind();
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, mesh.getVbo().getRowCount());
}
protected void assignToUniform(AGLGlslUniform.Mat4f uniform) {
this.modelUniform = uniform;
}
public void requestUniformUpdate() {
waitingForUniformUpdate = true;
}
protected void setWaitingForUniformUpdate(boolean waitingForUniformUpdate) {
this.waitingForUniformUpdate = waitingForUniformUpdate;
}
protected void updateUniform() {
ArrayList<AGLView> views = AGLRenderController.getActiveViews();
for (AGLView view : views) {
if (view.getShaderProgram() == modelUniform.getShaderProgram()) {
modelUniform.putData(model);
modelUniform.updateData();
return;
}
}
}
public void update() {
}
public void moveX(float delta) {
model.translate(new Vector3f(getSpeedX() * delta, 0, 0));
}
public void moveY(float delta) {
model.translate(new Vector3f(0, getSpeedY() * delta, 0));
}
public void moveZ(float delta) {
model.translate(new Vector3f(0, 0, getSpeedZ() * delta));
}
protected boolean isWaitingForUniformUpdate() {
return waitingForUniformUpdate;
}
}
abstract class AGLShader {
private int id;
protected AGLShaderType type;
public AGLShader() {
}
public void load(InputStream stream) {
id = GL20.glCreateShader(getGLType());
loadFromFile(stream);
compile();
}
private void loadFromFile(InputStream stream) {
GL20.glShaderSource(id, AGL.getInputStreamContent(stream));
}
public void bind(int programId) {
GL20.glAttachShader(programId, id);
}
public void unbind(int programId) {
GL20.glDetachShader(programId, id);
}
private void compile() {
GL20.glCompileShader(id);
}
public AGLShaderType getType() {
return type;
}
public int getId() {
return id;
}
protected abstract int getGLType();
}
class AGLShaderProgram {
private int id;
private AGLGlslAttribute attributes[];
protected AGLShaderProgram() {
}
public void load(InputStream vertexInputStream,
InputStream fragmentInputStream, AGLGlslAttribute attributes[]) {
this.id = GL20.glCreateProgram();
AGLVertexShader vertexShader = new AGLVertexShader();
vertexShader.load(vertexInputStream);
vertexShader.bind(id);
AGLFragmentShader fragmentShader = new AGLFragmentShader();
fragmentShader.load(fragmentInputStream);
fragmentShader.bind(id);
if (attributes != null) {
for (int i = 0; i < attributes.length; i++) {
GL20.glBindAttribLocation(id, attributes**.getId(),
attributes**.getName());
}
}
GL20.glLinkProgram(id);
vertexShader.unbind(id);
fragmentShader.unbind(id);
this.attributes = attributes;
System.out.println("[AGLShaderProgram : Line 33] Compile Errors: "
+ GL20.glGetProgramInfoLog(id,
GL20.glGetProgrami(id, GL20.GL_INFO_LOG_LENGTH)));
}
protected AGLGlslAttribute[] getAttributes() {
return attributes;
}
protected int getId() {
return id;
}
public void bind() {
GL20.glUseProgram(id);
}
public static void unbind() {
GL20.glUseProgram(0);
}
}
class AGLTexture {
}
class AGLVao {
private int id;
public AGLVao() {
id = GL30.glGenVertexArrays();
}
public void bind() {
GL30.glBindVertexArray(id);
}
public static void unbind() {
GL30.glBindVertexArray(0);
}
}
class AGLVbo {
private int id;
private int rowSize;
private int rowCount;
private int totalSize;
public AGLVbo(float data[], AGLGlslAttribute attributes[]) {
id = GL15.glGenBuffers();
FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
buffer.put(data);
buffer.flip();
totalSize = data.length;
bind();
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
loadAttributes(attributes);
AGLVbo.unbind();
}
public void bind() {
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, id);
}
public static void unbind() {
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public void loadAttributes(AGLGlslAttribute[] attributes) {
int bufferSize = 0;
int rowSize = 0;
for (int i = 0; i < attributes.length; i++) {
rowSize += attributes**.getSize();
}
this.rowSize = rowSize;
rowCount = totalSize / rowSize;
rowSize = rowSize * Float.SIZE / 8;
for (int i = 0; i < attributes.length; i++) {
GL20.glEnableVertexAttribArray(attributes**.getId());
GL20.glVertexAttribPointer(attributes**.getId(),
attributes**.getSize(), GL11.GL_FLOAT,
attributes**.isNormalized(), rowSize, bufferSize
* Float.SIZE / 8);
bufferSize += attributes**.getSize();
}
}
public int getRowSize() {
return rowSize;
}
public int getRowCount() {
return rowCount;
}
public int getTotalSize() {
return totalSize;
}
}
class AGLVertexShader extends AGLShader {
public AGLVertexShader() {
type = AGLShaderType.VERTEX;
}
protected int getGLType() {
return GL20.GL_VERTEX_SHADER;
}
}
class AGLView {
private ArrayList<AGLRenderObject> renderObjects;
private AGLShaderProgram program;
private AGLCamera camera;
protected AGLView(AGLShaderProgram program, AGLCamera camera) {
renderObjects = new ArrayList<>();
this.program = program;
this.camera = camera;
}
protected void render() {
program.bind();
for (AGLRenderObject o : renderObjects) {
if (o.isWaitingForUniformUpdate()) {
o.setWaitingForUniformUpdate(false);
o.updateUniform();
}
o.render();
}
}
protected AGLShaderProgram getShaderProgram() {
return program;
}
public AGLRenderObject addRenderObject(InputStream vboInputStream,
String modelUniformName) {
String vboRaw[] = AGL.getInputStreamContent(vboInputStream)
.replaceAll("[\\s\ \
]", "").split(",");
float[] buffer = new float[vboRaw.length];
for (int i = 0; i < vboRaw.length; i++) {
buffer** = Float.parseFloat(vboRaw**);
}
AGLVao vao = new AGLVao();
vao.bind();
AGLVbo vbo = new AGLVbo(buffer, getShaderProgram().getAttributes());
AGLVao.unbind();
AGLRenderObject renderObject = new AGLRenderObject(
new AGLMesh(vao, vbo));
renderObject.assignToUniform(new AGLGlslUniform.Mat4f(program,
modelUniformName));
renderObject.update();
renderObjects.add(renderObject);
return renderObject;
}
}
das enum zur lib… (ging iwi nicht in der selben klasse o.O)
package de.skysoldier.kskb;
import org.lwjgl.util.vector.Vector3f;
public class AGLCaps {
public enum AGLDisplayCap {
FULLSCREEN,
NONE
}
public enum AGLShaderType {
VERTEX,
FRAGMENT
}
public enum AGLProjectionType {
PERSPECTIVE,
ORTHOGONAL
}
public enum AGLUniformType {
MAT_4,
VEC_3
}
public enum AGLAxis {
X(new Vector3f(1.0f, 0.0f, 0.0f)),
Y(new Vector3f(0.0f, 1.0f, 0.0f)),
Z(new Vector3f(0.0f, 0.0f, 1.0f));
Vector3f vector;
AGLAxis(Vector3f vector){
this.vector = vector;
}
public Vector3f getVector(){
return vector;
}
}
}
die Shader und die vbo datei, je eine datei…
//agl.frag
#version 120
varying vec4 color;
void main(void){
gl_FragColor = color;
}
//agl2.frag
#version 120
varying vec4 color;
void main(void){
gl_FragColor = vec4(1, 0, 0, 1);
}
//agl.vert
#version 120
attribute vec3 vert;
uniform mat4 camera;
uniform mat4 model;
varying vec4 color;
void main() {
color = vec4(0, 0, 1, 1);//c[0];
gl_Position = camera * model * vec4(vert, 1);
}
//triangle.vbo
0.0, 0.0, 0.0,
-1.0, -1.0, 0.0,
0.9, -0.9, 0.0
und das test programm:
package de.skysoldier.kskb;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import de.skysoldier.kskb.AGLCaps.AGLDisplayCap;
import de.skysoldier.kskb.AGLCaps.AGLProjectionType;
public class AglTest {
public AglTest(){
/**
* 1. Create Context
* 2. Create ShaderProgram
* 3. Create View
* 4. Add RenderObjects
* 5. Init RenderController
* 6. render ...
*/
AGLGlslAttribute attribs[] = new AGLGlslAttribute[]{
AGLGlslAttribute.createAttributeVec3("vec")
};
AGL.createLwjglContext(AGLDisplayCap.NONE);
AGLShaderProgram program = AGL.createShaderProgram(AGL.getInputStreamFromRoot(getClass(), "agl.vert"), AGL.getInputStreamFromRoot(getClass(), "agl.frag"), attribs);
AGLView view = AGL.createView(program, "camera", AGLProjectionType.ORTHOGONAL);
AGLRenderObject renderObject = view.addRenderObject(AGL.getInputStreamFromRoot(getClass(), "triangle.vbo"), "model");
AGLShaderProgram program2 = AGL.createShaderProgram(AGL.getInputStreamFromRoot(getClass(), "agl.vert"), AGL.getInputStreamFromRoot(getClass(), "agl2.frag"), attribs);
AGLView view2 = AGL.createView(program2, "camera", AGLProjectionType.ORTHOGONAL);
AGLRenderObject renderObject2 = view2.addRenderObject(AGL.getInputStreamFromRoot(getClass(), "triangle.vbo"), "model");
AGL.initRenderController();
int counter = 0;
Keyboard.enableRepeatEvents(true);
AGL.bindViews(view, view2);
Mouse.setGrabbed(true);
float speedx, speedy;
while(AGL.running()){
int dy = Mouse.getDY();
int dx = Mouse.getDX();
speedx = dx / (float) 1e3;
speedy = dy / (float) 1e3;
renderObject.setSpeedX(-speedx);
renderObject2.setSpeedX(speedx);
renderObject.setSpeedY(-speedy);
renderObject2.setSpeedY(speedy);
renderObject.moveX(AGLRenderController.getDeltaMs());
renderObject.moveY(AGLRenderController.getDeltaMs());
renderObject.requestUniformUpdate();
renderObject2.moveX(AGLRenderController.getDeltaMs());
renderObject2.moveY(AGLRenderController.getDeltaMs());
renderObject2.requestUniformUpdate();
System.out.println(AGLRenderController.getDeltaMs());
if(counter >= 1000){Display.setTitle("FPS: " + AGLRenderController.getFps()); counter = 0;}
counter++;
AGL.render();
}
}
public static void main(String[] args) {
new AglTest();
}
}
Ich muss jetzt off, wenn ich gleich noch ans handy oder so on kann poste ich noch die wichtigsten zeilenangaben… sry