From 32c601b41f0c67e6ce1e11802645d7b6255b7c63 Mon Sep 17 00:00:00 2001 From: rexim Date: Thu, 7 Nov 2019 00:00:19 +0700 Subject: [PATCH 1/5] (#48) Make it zoom always towards the center fot he window --- src/boomer.nim | 11 +++++++---- src/vert.glsl | 5 ++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/boomer.nim b/src/boomer.nim index af84e10..57224c6 100644 --- a/src/boomer.nim +++ b/src/boomer.nim @@ -65,7 +65,8 @@ proc newShaderProgram(vertex, fragment: Shader): GLuint = glUseProgram(result) -proc draw(screenshot: Image, camera: var Camera, shader, vao, texture: GLuint) = +proc draw(screenshot: Image, camera: var Camera, shader, vao, texture: GLuint, + aspectRatio: Vec2f) = glClearColor(0.1, 0.1, 0.1, 1.0) glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT) @@ -73,6 +74,7 @@ proc draw(screenshot: Image, camera: var Camera, shader, vao, texture: GLuint) = glUniform2f(glGetUniformLocation(shader, "cameraPos".cstring), camera.position[0], camera.position[1]) glUniform1f(glGetUniformLocation(shader, "cameraScale".cstring), camera.scale) + glUniform2f(glGetUniformLocation(shader, "aspectRatio".cstring), aspectRatio.x, aspectRatio.y) glBindVertexArray(vao) glDrawElements(GL_TRIANGLES, count = 6, GL_UNSIGNED_INT, indices = nil) @@ -241,8 +243,6 @@ proc main() = glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER) - glViewport(0, 0, screenshot.width, screenshot.height) - var quitting = false camera = Camera(scale: 1.0) @@ -251,6 +251,7 @@ proc main() = while not quitting: var wa: TXWindowAttributes discard XGetWindowAttributes(display, win, addr wa) + glViewport(0, 0, wa.width, wa.height) var xev: TXEvent while XPending(display) > 0: @@ -315,7 +316,9 @@ proc main() = camera.update(config, 1.0 / config.fps.float, mouse, screenshot) - screenshot.draw(camera, shaderProgram, vao, texture) + screenshot.draw(camera, shaderProgram, vao, texture, + vec2(wa.width.float32 / screenshot.width.float32, + wa.height.float32 / screenshot.height.float32)) glXSwapBuffers(display, win) diff --git a/src/vert.glsl b/src/vert.glsl index 3e558db..0c80593 100644 --- a/src/vert.glsl +++ b/src/vert.glsl @@ -4,8 +4,11 @@ in vec2 aTexCoord; out vec2 texcoord; uniform vec2 cameraPos; uniform float cameraScale; +uniform vec2 aspectRatio; void main() { - gl_Position = vec4((aPos.x - cameraPos.x) * cameraScale, (aPos.y + cameraPos.y) * cameraScale, 0.0, 1.0); + gl_Position = vec4((aPos.x - cameraPos.x) * cameraScale / aspectRatio.x, + (aPos.y + cameraPos.y) * cameraScale / aspectRatio.y, + 0.0, 1.0); texcoord = aTexCoord; } From a6a5902996c4992e8c3682c140913a7a1fab682d Mon Sep 17 00:00:00 2001 From: rexim Date: Thu, 7 Nov 2019 00:42:59 +0700 Subject: [PATCH 2/5] (#48) Provide information about screenshot and window size to shader --- src/boomer.nim | 12 ++++++++---- src/vert.glsl | 12 +++++++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/boomer.nim b/src/boomer.nim index 57224c6..dd59efe 100644 --- a/src/boomer.nim +++ b/src/boomer.nim @@ -66,7 +66,7 @@ proc newShaderProgram(vertex, fragment: Shader): GLuint = glUseProgram(result) proc draw(screenshot: Image, camera: var Camera, shader, vao, texture: GLuint, - aspectRatio: Vec2f) = + windowSize: Vec2f) = glClearColor(0.1, 0.1, 0.1, 1.0) glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT) @@ -74,7 +74,12 @@ proc draw(screenshot: Image, camera: var Camera, shader, vao, texture: GLuint, glUniform2f(glGetUniformLocation(shader, "cameraPos".cstring), camera.position[0], camera.position[1]) glUniform1f(glGetUniformLocation(shader, "cameraScale".cstring), camera.scale) - glUniform2f(glGetUniformLocation(shader, "aspectRatio".cstring), aspectRatio.x, aspectRatio.y) + glUniform2f(glGetUniformLocation(shader, "screenshotSize".cstring), + screenshot.width.float32, + screenshot.height.float32) + glUniform2f(glGetUniformLocation(shader, "windowSize".cstring), + windowSize.x.float32, + windowSize.y.float32) glBindVertexArray(vao) glDrawElements(GL_TRIANGLES, count = 6, GL_UNSIGNED_INT, indices = nil) @@ -317,8 +322,7 @@ proc main() = camera.update(config, 1.0 / config.fps.float, mouse, screenshot) screenshot.draw(camera, shaderProgram, vao, texture, - vec2(wa.width.float32 / screenshot.width.float32, - wa.height.float32 / screenshot.height.float32)) + vec2(wa.width.float32, wa.height.float32)) glXSwapBuffers(display, win) diff --git a/src/vert.glsl b/src/vert.glsl index 0c80593..9ecda38 100644 --- a/src/vert.glsl +++ b/src/vert.glsl @@ -4,11 +4,17 @@ in vec2 aTexCoord; out vec2 texcoord; uniform vec2 cameraPos; uniform float cameraScale; -uniform vec2 aspectRatio; +uniform vec2 windowSize; +uniform vec2 screenshotSize; + +vec2 ratio = vec2( + windowSize.x / screenshotSize.x, + windowSize.y / screenshotSize.y); + void main() { - gl_Position = vec4((aPos.x - cameraPos.x) * cameraScale / aspectRatio.x, - (aPos.y + cameraPos.y) * cameraScale / aspectRatio.y, + gl_Position = vec4((aPos.x - cameraPos.x) * cameraScale / ratio.x, + (aPos.y + cameraPos.y) * cameraScale / ratio.y, 0.0, 1.0); texcoord = aTexCoord; } From 5e879f7adc358163b9243340fad81c2fb75ba678 Mon Sep 17 00:00:00 2001 From: rexim Date: Thu, 7 Nov 2019 02:43:07 +0700 Subject: [PATCH 3/5] (#48) Align the mesh with the screen coordinates --- src/boomer.nim | 24 +++++++++++++++--------- src/la.nim | 3 +++ src/navigation.nim | 8 ++------ src/vert.glsl | 17 +++++++++++------ 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/boomer.nim b/src/boomer.nim index dd59efe..59b4d09 100644 --- a/src/boomer.nim +++ b/src/boomer.nim @@ -66,7 +66,7 @@ proc newShaderProgram(vertex, fragment: Shader): GLuint = glUseProgram(result) proc draw(screenshot: Image, camera: var Camera, shader, vao, texture: GLuint, - windowSize: Vec2f) = + windowSize: Vec2f, mouse: Mouse) = glClearColor(0.1, 0.1, 0.1, 1.0) glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT) @@ -80,6 +80,9 @@ proc draw(screenshot: Image, camera: var Camera, shader, vao, texture: GLuint, glUniform2f(glGetUniformLocation(shader, "windowSize".cstring), windowSize.x.float32, windowSize.y.float32) + glUniform2f(glGetUniformLocation(shader, "cursorPos".cstring), + mouse.curr.x.float32, + mouse.curr.y.float32) glBindVertexArray(vao) glDrawElements(GL_TRIANGLES, count = 6, GL_UNSIGNED_INT, indices = nil) @@ -183,14 +186,16 @@ proc main() = var shaderProgram = newShaderProgram(vertexShader, fragmentShader) + let w = screenshot.width.float32 + let h = screenshot.height.float32 var vao, vbo, ebo: GLuint vertices = [ # Position Texture coords - [GLfloat 1.0, -1.0, 0.0, 1.0, 1.0], # Top right - [GLfloat 1.0, 1.0, 0.0, 1.0, 0.0], # Bottom right - [GLfloat -1.0, 1.0, 0.0, 0.0, 0.0], # Bottom left - [GLfloat -1.0, -1.0, 0.0, 0.0, 1.0] # Top left + [GLfloat w, 0, 0.0, 1.0, 1.0], # Top right + [GLfloat w, h, 0.0, 1.0, 0.0], # Bottom right + [GLfloat 0, h, 0.0, 0.0, 0.0], # Bottom left + [GLfloat 0, 0, 0.0, 0.0, 1.0] # Top left ] indices = [GLuint(0), 1, 3, 1, 2, 3] @@ -240,7 +245,6 @@ proc main() = glUniform1i(glGetUniformLocation(shaderProgram, "tex".cstring), 0) - glEnable(GL_TEXTURE_2D) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) @@ -270,10 +274,11 @@ proc main() = xev.xmotion.y.float32) if mouse.drag: - let delta = world(mouse.prev, screenshot, camera) - world(mouse.curr, screenshot, camera) + let delta = world(camera, mouse.prev) - world(camera, mouse.curr) camera.position += delta camera.velocity = delta * config.dragVelocityFactor - mouse.prev = mouse.curr + + mouse.prev = mouse.curr of ClientMessage: if cast[TAtom](xev.xclient.data.l[0]) == wmDeleteMessage: @@ -322,7 +327,8 @@ proc main() = camera.update(config, 1.0 / config.fps.float, mouse, screenshot) screenshot.draw(camera, shaderProgram, vao, texture, - vec2(wa.width.float32, wa.height.float32)) + vec2(wa.width.float32, wa.height.float32), + mouse) glXSwapBuffers(display, win) diff --git a/src/la.nim b/src/la.nim index b843fbf..85485a9 100644 --- a/src/la.nim +++ b/src/la.nim @@ -7,6 +7,9 @@ proc vec2*(x: float32, y: float32): Vec2f = (x, y) proc `*`*(a: Vec2f, s: float32): Vec2f = vec2(a.x * s, a.y * s) +proc `/`*(a: Vec2f, s: float32): Vec2f = + vec2(a.x / s, a.y / s) + proc `*`*(a: Vec2f, b: Vec2f): Vec2f = vec2(a.x * b.x, a.y * b.y) diff --git a/src/navigation.nim b/src/navigation.nim index 610ccee..5f21664 100644 --- a/src/navigation.nim +++ b/src/navigation.nim @@ -14,12 +14,8 @@ type Camera* = object scale*: float32 deltaScale*: float -proc world*(point: Vec2f, image: Image, camera: Camera): Vec2f = - let f = (camera.position + vec2(1.0f32, 1.0f32)) / vec2(2.0f32, 2.0f32) - let ps = vec2(image.width.float32 * camera.scale, image.height.float32 * camera.scale) * f - let ms = vec2(point.x.float32, point.y.float32) + ps - return vec2(ms.x / (image.width.float32 * camera.scale) * 2.0f32 - 1.0f32, - ms.y / (image.height.float32 * camera.scale) * 2.0f32 - 1.0f32) +proc world*(camera: Camera, v: Vec2f): Vec2f = + (camera.position + v) / camera.scale proc update*(camera: var Camera, config: Config, dt: float, mouse: Mouse, image: Image) = if abs(camera.deltaScale) > 0.5: diff --git a/src/vert.glsl b/src/vert.glsl index 9ecda38..7bfd45f 100644 --- a/src/vert.glsl +++ b/src/vert.glsl @@ -2,19 +2,24 @@ in vec3 aPos; in vec2 aTexCoord; out vec2 texcoord; + uniform vec2 cameraPos; uniform float cameraScale; uniform vec2 windowSize; uniform vec2 screenshotSize; +uniform vec2 cursorPos; -vec2 ratio = vec2( - windowSize.x / screenshotSize.x, - windowSize.y / screenshotSize.y); +vec3 to_world(vec3 v) { + vec2 ratio = vec2( + windowSize.x / screenshotSize.x, + windowSize.y / screenshotSize.y); + return vec3((v.x / screenshotSize.x * 2.0 - 1.0) / ratio.x, + (v.y / screenshotSize.y * 2.0 - 1.0) / ratio.y, + v.z); +} void main() { - gl_Position = vec4((aPos.x - cameraPos.x) * cameraScale / ratio.x, - (aPos.y + cameraPos.y) * cameraScale / ratio.y, - 0.0, 1.0); + gl_Position = vec4(to_world((aPos - vec3(cameraPos * vec2(1.0, -1.0), 0.0)) * cameraScale), 1.0); texcoord = aTexCoord; } From decd54cdbf1b124c6ea8e0afab2408f95df09382 Mon Sep 17 00:00:00 2001 From: rexim Date: Wed, 13 Nov 2019 23:34:33 +0700 Subject: [PATCH 4/5] (#48) Make it zoom towards the center of the screen --- src/vert.glsl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vert.glsl b/src/vert.glsl index 7bfd45f..d09eb4e 100644 --- a/src/vert.glsl +++ b/src/vert.glsl @@ -11,8 +11,8 @@ uniform vec2 cursorPos; vec3 to_world(vec3 v) { vec2 ratio = vec2( - windowSize.x / screenshotSize.x, - windowSize.y / screenshotSize.y); + windowSize.x / screenshotSize.x / cameraScale, + windowSize.y / screenshotSize.y / cameraScale); return vec3((v.x / screenshotSize.x * 2.0 - 1.0) / ratio.x, (v.y / screenshotSize.y * 2.0 - 1.0) / ratio.y, v.z); @@ -20,6 +20,6 @@ vec3 to_world(vec3 v) { void main() { - gl_Position = vec4(to_world((aPos - vec3(cameraPos * vec2(1.0, -1.0), 0.0)) * cameraScale), 1.0); + gl_Position = vec4(to_world((aPos - vec3(cameraPos * vec2(1.0, -1.0), 0.0))), 1.0); texcoord = aTexCoord; } From b31121d073ecf3ef030f978316a6175f8d374fea Mon Sep 17 00:00:00 2001 From: rexim Date: Wed, 13 Nov 2019 23:34:55 +0700 Subject: [PATCH 5/5] (#48) Increase the drag friction --- src/config.nim | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config.nim b/src/config.nim index c8c9dc7..ddd8db1 100644 --- a/src/config.nim +++ b/src/config.nim @@ -10,7 +10,8 @@ type Config* = object const defaultConfig* = Config( scrollSpeed: 1.0, dragVelocityFactor: 10.0, - dragFriction: 1.0, + # TODO: For a natual feel dragFriction probably should depend on velocity + dragFriction: 600.0, scaleFriction: 10.0, fps: 60 )