Flackern trotz 1400 fps?!

Hey Leute.
Ich schreibe ja gerade an meine kleinen Lwjgl Lib.
Ich hab hier ein kleines Test Programm. Es sind 2 Views, also auch 2
Shader Programme die pro render vorgang abgewechselt werden. Jede View
hat ein Render Object, also eins der Dreiecke. Die Shader Programme unterscheiden
sich nur in der Farbgebung. (rot, blau).

Bewegt man die Maus bewegen sich die Dreiecke in entgegengesetzte richtungen, jedes
eine matrix -> model uniform.

Das Programm läuft bei mir mit durchschnittlich 1400 fps - aber irgendwie sieht es
aus als ob es trozdem flackern würde. Ist mein Bildschirm vielleicht schrott? Obwohl, 60 Hertz sind doch normal
oder nicht? Oder kann irgendwas am code falsch sein?

Bei bedarf werde ich die gebetenen Stellen posten.

Danke fürs ansehen…

http://www.file-upload.net/download-8715282/AGlTest.jar.html

Wie… will man denn bitte double buffering in lwjgl implementieren? O.o

*** Edit ***

Erster satz: lwjgl wiki

Tja, ohne Code kann man leider nicht viel sagen. Mach ein KSKB.

Das wird schwierig…
Hast du dieses empfinden denn auch? Das es flackert?
Vielleicht bin ich nur überempfindlich :x
Ein freund von mir meinte er saehe es bei sich nicht, ich testete es auf 3 computern und hatte es jedesmal so seltsam empfunden.

Ich bin grad nicht zuhause, mir kommt aber gerade ein verdacht auf. Mal sehn wenn ich zh bin…

Bei mir flackert da gar nichts (kein Wunder bei 6000 bis 9000 FPS). Durch den Code in dem Archiv (woran man mit JD-GUI kommt) kann ich mich leider nicht wirklich durchwuseln. Welche Klasse wird denn durch diesen Launcher dort gestartet?

Moin,

ich habe mir das Beispiel nicht angesehen. Meine Motivation unbekannte Closed-Source-Software irgendwo aus dem Internet auszuführen ist meistens nicht sonderlich hoch, sorry. Hinzu kommt, dass man um wirklich helfen zu können sowieso den Quellcode sehen müsste.

Allgemein gibt es aber mindestens 5 Punkte, die das Problem schwierig machen:

  1. der Mensch: Jeder nimmt Bewegungen unterschiedlich wahr. Besonders auffällig ist das beim herkömmlichen Kino. Während das auf einige vollkommen flüssig wirkt, nehmen andere Ungleichmäßigkeiten bei jeder Bewegung wahr.

  2. die Eingabeparameter: Hängt die Bewegung von Eingabeparametern ab, ist es entscheidend, wie diese verteilt sind. Stottern diese bereits, stottert auch die spätere Darstellung.

  3. die Zeit pro Frame: 1400 FPS sagt nichts über die Verteilung der Frames aus. Ein Beispiel:
    Frame 1 bis Frame 999 in jeweils einer Millisekunde und Frame 1000 in 100 Millisekunden macht zusammen 910 FPS und trotzdem werden Bewegungen nicht gleichmäßig erscheinen.

  4. die Latenz: Damit die Bewegung flüssig wahrgenommen wird, muss die Bewegung in Pixel pro Zeit auf dem Bildschirm gleichmäßig sein. Grafikkarten arbeiten aber asynchron, so das sich nicht vorhersagen lässt, wann das Bild auf dem Bildschirm sichtbar wird, dadurch lässt sich auch nicht berechnen wieweit sich das Objekt in genau diesem einem Frame bewegen muss.

  5. die Fensteranwendung: Ein streifenweises Darstellen der Einzelbilder, wie es bei Vollbildanwendungen ohne Vsync üblich ist, ist auf dem Desktop unüblich (hängt aber vom Betriebssystem und dem Treiber ab). Läuft der Desktop mit 60 FPS und die Fensteranwendung mit 1400 FPS berechnet OpenGL zwar 1400 FPS, die Desktopumgebung greift aus diesen 1400 Bildern aber wahllos 60 (Voll-)Bilder raus um diese darzustellen. Werden diese 60 Bilder nicht gleichmäßig ausgewählt, werden die Bewegungen auch nicht gleichmäßig.

Selbst bei einer korrekten OpenGL Anwendung ist es also schwierig, Bewegungen gleichmäßig darzustellen.

Poste ein KSKB, bei dem das Phänomen auftritt, dann kann man sehen, ob das Problem in der Anwendung selbst liegt oder ob es eine Kombination der obrigen Punkte ist. Und wie man das ggf. verbessern könnte.

Viele Grüße
Fancy

Gut. Also mein verdacht war das ich blödi vergessen hätte eine zeile zu löschen…
und somit RenderObject.size + 1 mal Display.update() “per Frame” machen würde. War aber doch nicht so.

Aber… tut mir echt leid, ich hab aber keine zeit und auch keine lust aus dem ganzen kram ein kskb zu machen ._.
ist es ok wenn ich einfach alle klassen zusammenschmeiße, und die wichtigsten stellen angebe? Vielleicht kannst du / könnt ihr dann
ja auch was zum gesamt system sagen.

Dann erwarte aber auch nicht, dass sich jemand die Zeit nimmt, deinen Code zu verstehen und dir dann zu helfen…

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 :confused:

Also bei mir flackert da nichts. Ich hatte auch erst an irgendwas mit VSync gedacht, wollte aber noch warten, ob Fancy das erwähnt, damit ich dann sagen kann: „Ich hatte auch erst an irgendwas mit VSync gedacht“ :smiley: Manchmal gibt’s ja (je nach Grafikkarte) irgendwelcher Einstellmöglichkeiten, bei NVIDIA sogar mit diesem fancy „Control Panel“, vielleicht da mal rumspielen…

badumm… tss xD

ja diese cp hab ich auch. Ich schau morgen mal rein.

Anscheinend bin ich nur überempfindlich.
Um es genau zu beschreiben, wahrscheinlich ist flackern die falsche bezeichnung:
Ich hab das gefühl das ich jedes der Dreiecke mehrere male auf dem bildschirm sehen würde.
Sind meine augen vielleicht kaputt? zu langsam? x.x ich trag ne brille, aber das wär ja ein sehr
seltsames phänomen xD

Versteht ihr ungefähr was ich meine?

und wie geht das nun, um deine genannten punkte zu beachten? ._.

Also diese AGLTest-Klasse hatte ich auch schon im Visier, aber darin fällt mir persönlich nichts auf, was flackern könnte, zumal beide Dreiecke stets zwischen zwei "Display.update()"s gerendert werden und somit beide Buffer stets beide Dreiecke beinhalten. Anders wäre es, wenn man zwischen 2 Updates nur immer eines der beiden Dreiecke zeichnet. In einem Buffer wäre dann nur das rote und in dem anderen nur das blaue zu sehen und darüber hinaus beide immer nur abwechselnd aber niemals zugleich und dann flackerts auch.

Edit: Und doppelte Dreiecke seh ich auch nicht… schlage vor, das du dir das morgen noch mal ansiehst, wenn du weniger getrunken hast… :lol: (kurz gesagt, ich bin ratlos).

XD ich bin anti alkoholiker :smiley:
Also nein nicht doppelt in dem sinne XD
ähmm… stell dir das so vor: Es gibt bei Windows diese Mauseinstellung… Mausspur zeigen.
Die Maus die gezeichnet wird verschwindet quasi also nicht beim wiederbewegen sondern etwas später ^^
Probiers einfach aus. Maus → Zeigeoprtionen → Mausspur

So ungefähr sieht für mich das ganze aus, aber halt nicht so extrem und… ja. nicht so krass, nur ein
wenig.

Vielleicht liegt es doch daran das die Pc’s nicht die neuesten sind… Ratlos, helfen könnt ihr mir wohl nicht -
meine Augen sind leider nicht serializable xD

Gute Nacht dann mal.
Vielleicht fällt jdem ja sonst noch iwas falsches auf, ansonsten versuch ichs einfach mal zu ignorieren :smiley:

Ändere mal Zeile 438 in deinem ersten Codeabschnitt (“AGLRenderController.render()”) wie folgt:
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);Das kann aber evtl. nur helfen, wenn du keine NVidia-Karte verwendest, z.B. ATI. Mir ist vor längerer Zeit mal aufgefallen, dass bei NVidia-Karten bereits gezeichnete Buffer gecleared werden, bevor sie erneut verwendet werden. Das war von X Jahren und da habe ich mal bei einer Anwendung dieses “glClear()” komplett vergessen. Während mir das auf meiner NVidia nicht auffiel, gabs bei 'nem Bekannten auf 'ner ATI nur kaudawelsch. Von daher nehme ich mal an, dass deine “Halluzinationen” darauf beruhen könnten, dass du die Buffer nicht korrekt löschst. Du vergisst halt den Tiefenpuffer und deswegen wird theoretisch nur eine Ebene im gesammten Puffer gelöscht, wodurch Dreiecke in anderen Ebenen sichtbar bleiben. Ist zwar ein sehr dünner Zweig, aber vllt. hilfts ja.

erstmal zu meinen system-specs

Board : ASUS Crosshair V Formula-Z 990FX
CPU : AMD FX-8350 AM3+ @ stock 8x 4,00GHz
Cooling : Corsair Hydro H80i
RAM : 2x Corsair Vengeance 8GB 10-10-10-27
Graphics : ASUS HD7870-DC2TG 2GB O.C. @ GPU 1100MHz / MEM 5000MHz
Driver : 13.251-131206a-165817C-ATI
Direct3D : 9.14.10.01001
OpenGL : 6.14.10.12618
PSU : Corsair H760
OS : Win 7 Ultimate SP1
Montor : ASUS VE248H @ HDMI
Case : CM Storm Trooper

gesamtkosten hardware (incl monitor und case) : 1288€

bei mir tritt ein noch sehr viel merkwürdigeres problem auf

grundsätzlich kommt bei mir erstmal in der console das hier

[AGLShaderProgram : Line 33] Compile Errors:
[AGLShaderProgram : Line 33] Compile Errors:

witziger weise aber ohne angabe irgendwelcher errors … einfach nur diese zeilen … was auch immer

dann läuft das ganze bei mir mit rund 11k-12k fps … hat dann aber immer mal wieder zwischen durch drops auf um die 4k
und bei diesen drops passiert es dann : die positionen … oder die bewegung an sich … wird total falsch berechnet und die dreiecke “springen” plötzlich ziemlich weit … zwar immer noch in die selbe richtung … aber es macht den anschein als ob sich halt die dreiecke während den “fehlenden” frames weiter bewegen … dies aber nicht dargestellt wird … sondern letzten endes nur das end-ergebnis …
die weite entfernung kann ich mir jetzt nur dadurch erklären das halt die berechnungen auf grund der fehlenden frames öfter ausgeführt werden und damit weiter sind … was zum falschen ergebnis führt (das müsste man sich mal in nem AAA-title vorstellen … man läuft ne gewisse strecke lang und BÄM … plötzlich alles total verzerrt)

was also bei dir “nur” laggen ist ist bei meinem system schon “quer durch die gegend springen”

und vor allem : die dreiecke bewegen sich extrem langsam und nur millimeter weise

so … und jetzt kommt das hüpfende komma : ich hab mir mal den spaß gemacht und fraps angeschmissen … 60fps eingestellt … und den frame-limiter dazu geschaltet
erstmal brechen die frames komplett in den keller auf genau 60.0 (macht ja auch sinn bei einem frame-limiter) … und plötzlich bewegen sich die dreiecke auch mit ner relativ guten geschwindigkeit … und dabei kommt es dann zum von dir beschrieben problem : die dreicke “laggen” hinter her … man sieht also schon das dreieck an der neuen position … gleichzeitig aber noch an der alten position wo es noch nicht vollständig ausm frame-buffer raus ist … halt das ganz normale verhalten von full-screen spielen ohne vsync … HL1 mit seinen 600FPS legt mir dann gerne mal “frames” vor die aufm monitor 4 oder 5 klar ekennbare leaks haben wo noch das vorherige frame zu sehen ist … bin ich DA aber gewohnt und sehe ich fast nicht mehr … sorgt aber halt für extrem viel mehr fps
hau ich da den limiter von fraps rein bleibts auch bei genau 60.0 und sieht “sauber” aus … auch ohne direktes vsync vom treiber
oder halt wenn ich die cvar fps_max auf 60 stelle

dann hab ich mal noch n test ohne frame-limiter gemacht … da lief das ganze mit um die 1000fps … und droppte immer mal wieder stark runter auf um die 200
auch hier ist dann dieses “springen” deutlich zu erkennen … und das sich die dreiecke bei deutlich höherer fps-zahl auch deutlich langsamer bewegen

was aber an der unterschiedlichen “geschwindigkeit” bei verschiedenen frame-rates zu erkennen ist : die berechnung scheint falsch zu sein

die uploads sind direkt unkomprimiert und mit fraps 3.5.99 build 15618 aufgenommen
YT haut natürlich was die quali angeht durch sein runterrechnen auf 30fps einiges dazwischen … man sieht den effekt aber trotzdem noch
müsste ich eigentlich mal auf meinen server laden damit ihr seht was bei mir abgeht

mit frame-lock : http://youtu.be/XVkBwu8Obf0
ohne frame-lock : http://youtu.be/pXNL_W0VwNM

fakt ist : ich kann das von TO beschriebene problem nachvollziehen … würde es aber eher auf falsch berechnung oder vielleicht andere fehler im code schieben

[QUOTE=mymaksimus]
ähmm… stell dir das so vor: Es gibt bei Windows diese Mauseinstellung… Mausspur zeigen.
Die Maus die gezeichnet wird verschwindet quasi also nicht beim wiederbewegen sondern etwas später ^^[/QUOTE]

So verrückt es klingt: DAS könnte (!) bis zu eine gewissen Grad tatsächlich am Monitor liegen. Wenn das ein scheiß-alter LCD ist: Die “leuchten ein bißchen nach”. Aber das ist jetzt auch nur ein ins blaue geratener Strohhalm, oder wie man da sagen soll…

[QUOTE=Unregistered]bei mir tritt ein noch sehr viel merkwürdigeres problem auf

grundsätzlich kommt bei mir erstmal in der console das hier

[AGLShaderProgram : Line 33] Compile Errors:
[AGLShaderProgram : Line 33] Compile Errors:

[/QUOTE]Das ist nicht merkwürdig, das ist so programmiert (1. Codeabschnitt des TO, Zeile 614). Diese Zeile wird immer ausgegeben, selbst wenn es beim kompilieren der Shader keine Fehler gab.

Und äehm… an einen sch…-alten LCD-Monitor hatte ich garnicht gedacht. Afaik leuchteten die sogar noch bei 25FPS nach (Nachleuchtzeiten oberhalb 30ms).

Puh, das weiss ich gar nicht…
Schau ich mal.

Danke unregistered fuer die ausgiebiege teszphase…
Das sie sich bei unterschiedlich vielen fps unterschiedlich schnell bewegen liegt daran das bei niedrigen fps delta viiel groesser ist, (logisch) und die bewegung zu viel schneller wird… ka wie man das berechnet, muss man mal schauennn

Die Geschwindigkeit deiner Animation hängt von den FPS ab? Das sollte aber nicht sein…