Using regl I'm trying to implement a very simple drawRect()
function that will eventually be able to pass an x, y, width, height in screen space (with origin 0,0 at top left corner of the screen)
Here's what I have so far:
https://codesandbox.io/s/nn9qvxom4l
const regl = require('regl')();
const mat4 = require('gl-mat4');
var drawRect = regl({
frag: `
precision mediump float;
uniform vec4 color;
void main() {
gl_FragColor = color;
}`,
vert: `
precision mediump float;
attribute vec2 position;
uniform vec2 offset;
uniform vec2 scale;
uniform float viewportWidth;
uniform float viewportHeight;
uniform mat4 projection;
void main() {
// windows ratio scaling factor.
float r = (viewportWidth) / (viewportHeight);
gl_Position = projection * vec4(position.xy * scale, 0, 1);
}`,
attributes: {
position: [
[-1, -1], //tri 1 bottom left
[1, 1],
[-1, 1],
[-1, -1],
[1, -1],
[1, 1]
]
},
uniforms: {
offset: regl.prop('offset'),
scale: regl.prop('scale'),
color: regl.prop('color'),
viewportWidth: regl.context('viewportWidth'),
viewportHeight: regl.context('viewportHeight'),
projection: ({ viewportWidth, viewportHeight }) => {
//glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
//ortho(out:mat4, left, right, bottom, top, near, far)
// this makes everything blank
var m = mat4.ortho(
[],
0,
viewportWidth,
0,
viewportHeight,
0.1,
100.0
);
console.log(m);
return m;
}
},
depth: {
enable: false
},
cull: {
enable: true
},
count: 6,
viewport: {
x: 0,
y: 0,
width: window.innerWidth,
height: window.innerHeight
}
});
regl.clear({
color: [0, 0, 0, 255],
depth: 1
});
// all these coordinates are in clip-space* right now (* I think)
// but I'd like to be able to pass in screen-space coordinates
drawRect([
{
offset: [0, 0],
scale: [0.002, 0.002],
color: [1, 0.2, 0.2, 1]
},
{
offset: [0, -0.2],
scale: [0.2, 0.05],
color: [1, 0.2, 1, 1]
},
{
offset: [0, 0],
scale: [0.5, 0.5],
color: [0.2, 0.2, 1, 1]
}
]);
Currently it draws a blank screen (I'm guessing due the projection matrix clipping or moving everything outside of the viewport). If you remove the projection from the vertex shader or use an identity matrix in the projection attribute then it renders a blue square again.
So my questions are:
- What am I doing wrong here? Why does my orthographic projection not work?
- How would I debug this in the future so I can "see" the resultant coordinates and how they're wrong?
I have read some SO questions, OpenGL books and blogs, but I'm stuck here because it seems like this should work.
Related resources:
https://unspecified.wordpress.com/2012/06/21/calculating-the-gluperspective-matrix-and-other-opengl-matrix-maths/ https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_model_view_projection https://webglfundamentals.org/webgl/lessons/webgl-2d-matrices.html WebGL Isometric projection Want an OpenGL 2D example (VC++, draw a rectangle) http://songho.ca/opengl/gl_transform.html
Edit: fixed viewportWidth being used twice in ortho projection. This fixes a blank screen, however origin is now bottom-left instead of top-left. Switching around parameters of ortho projection cause a blank screen again.