WebGL - Clip Space | Pixel Space?
// Renderer Beispiel
render(){
const s2 = new Square(300, 100, 70, [0, 1, 1, 1]);
s2.setup(this.context, this.program);
s2.render(this.program, this.context, deltaTime);
this.vertexManager.draw(3, 0, 4, 100, 100, 0, [0,0,1,1]);
}
//
export class Square extends Renderable {
constructor (x, y, size, color) {
super();
this.x = x;
this.y = y;
this.size = size;
this.color = color;
this.vertices = new Float32Array([
-size / 2, -size / 2,
size / 2, -size / 2,
size / 2, size / 2,
-size / 2, size / 2,
]);
this.vertexBuffer = null;
this.colorBuffer = null;
this.transformationMatrix = createIdentityMatrix3();
}
setup (gl, program) {
this.vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.STATIC_DRAW);
}
updateTransformationMatrix (x, y, scaleX, scaleY, angle) {
const translationMatrix = createTranslationMatrix(x, y);
const rotationMatrix = createRotationMatrix(angle);
const scalingMatrix = createScalingMatrix(scaleX, scaleY);
// Combine the matrices: translation * rotation * scaling
const combinedMatrix = multiplyMatrices(rotationMatrix, multiplyMatrices(translationMatrix, scalingMatrix));
// Save the transformation matrix
this.transformationMatrix = combinedMatrix;
}
render (program, gl, camera, deltaTime) {
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
// Re-enable the vertex attribute array
const positionLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
const colorLocation = gl.getUniformLocation(program, 'u_color');
gl.uniform4fv(colorLocation, this.color);
const matrixLocation = gl.getUniformLocation(program, 'u_matrix');
this.updateTransformationMatrix(this.x, this.y, 1.0, 1.0, 0);
gl.uniformMatrix3fv(matrixLocation, false, this.transformationMatrix);
gl.drawArrays(gl.TRIANGLE_FAN, 0, this.vertices.length / 2 + 1);
}
}
export default class VertexManager {
constructor (gl, program) {
this.gl = gl;
this.program = program;
this.buffers = new Map();
this.initBuffers();
}
initBuffers () {
this.createBuffer(BUFFER_TYPES.CIRCLE, createPolygonVertices(64, 1));
this.createBuffer(BUFFER_TYPES.SQUARE, new Float32Array([
-0.5, -0.5,
0.5, -0.5,
0.5, 0.5,
-0.5, 0.5,
]));
....
}
createBuffer (type, vertices) {
const buffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);
this.buffers.set(type, { buffer, vertexCount: vertices.length / 2 });
}
draw (type, x, y, scaleX, scaleY, rotation, color) {
const { buffer, vertexCount } = this.buffers.get(type);
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
// Re-enable the vertex attribute array
const positionLocation = this.gl.getAttribLocation(this.program, 'a_position');
this.gl.enableVertexAttribArray(positionLocation);
this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);
// Setup the color
const colorLocation = this.gl.getUniformLocation(this.program, 'u_color');
this.gl.uniform4fv(colorLocation, color);
const matrixLocation = this.gl.getUniformLocation(this.program, 'u_matrix');
// Create transformation matrices directly in pixel space
const translationMatrix = createTranslationMatrix(x, y);
const rotationMatrix = createRotationMatrix(rotation);
const scalingMatrix = createScalingMatrix(scaleX, scaleY);
// Combine them: translationMatrix * rotationMatrix * scalingMatrix
const combinedMatrix = multiplyMatrices(rotationMatrix, multiplyMatrices(translationMatrix, scalingMatrix));
// Pass the transformation matrix to the shader
this.gl.uniformMatrix3fv(matrixLocation, false, combinedMatrix);
this.gl.drawArrays(this.gl.TRIANGLE_FAN, 0, vertexCount);
}
}
Meine Frage ist, warum mein Quadrat korrekt im Pixel-Space gerendert wird, während die draw-Operation in meinem VertexManager Clip-Space zeichnet, obwohl beide denselben Shader verwenden. Ich habe das Problem schon seit Stunden versucht zu lösen. Hat jemand eine Lösung oder einen Hinweis, was ich möglicherweise falsch mache?
1 Antwort
Man sieht die Erstellung des VertexManagers nicht, es lässt sich so also nicht sagen, ob tatsächlich dasselbe Program und derselbe Context verwendet werden.
Was sich sonst unterscheidet wären die Buffer und evtl., was zum zeitpunkt des Programmflusses wo gebindet ist (ich sehe kein Unbind).
Was sich unterscheidet, aber keinen Einfluss haben solllte, soweit ich recherchiert habe, ist, wie du die Matrix übergibst, einmal als Klassenobjekt, einmal als lokale Variable.
In anderen Sprachen macht das einen Unterschied, hier sollte das aber in Ordnung sein. Kann man aber auch einmal prüfen, was da ankommt.
Außerdem unterscheidet sich der Vertexcount zwischen den Aufrufen. Beim einen addierst du 1.