mirror of
https://github.com/tsoding/boomer
synced 2024-11-18 09:28:37 +00:00
Merge pull request #51 from tsoding/48
(#48) Make it zoom towards the center of the screen
This commit is contained in:
commit
c2c574c778
@ -65,7 +65,8 @@ proc newShaderProgram(vertex, fragment: Shader): GLuint =
|
|||||||
|
|
||||||
glUseProgram(result)
|
glUseProgram(result)
|
||||||
|
|
||||||
proc draw(screenshot: Image, camera: var Camera, shader, vao, texture: GLuint) =
|
proc draw(screenshot: Image, camera: var Camera, shader, vao, texture: GLuint,
|
||||||
|
windowSize: Vec2f, mouse: Mouse) =
|
||||||
glClearColor(0.1, 0.1, 0.1, 1.0)
|
glClearColor(0.1, 0.1, 0.1, 1.0)
|
||||||
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
|
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
|
||||||
|
|
||||||
@ -73,6 +74,15 @@ proc draw(screenshot: Image, camera: var Camera, shader, vao, texture: GLuint) =
|
|||||||
|
|
||||||
glUniform2f(glGetUniformLocation(shader, "cameraPos".cstring), camera.position[0], camera.position[1])
|
glUniform2f(glGetUniformLocation(shader, "cameraPos".cstring), camera.position[0], camera.position[1])
|
||||||
glUniform1f(glGetUniformLocation(shader, "cameraScale".cstring), camera.scale)
|
glUniform1f(glGetUniformLocation(shader, "cameraScale".cstring), camera.scale)
|
||||||
|
glUniform2f(glGetUniformLocation(shader, "screenshotSize".cstring),
|
||||||
|
screenshot.width.float32,
|
||||||
|
screenshot.height.float32)
|
||||||
|
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)
|
glBindVertexArray(vao)
|
||||||
glDrawElements(GL_TRIANGLES, count = 6, GL_UNSIGNED_INT, indices = nil)
|
glDrawElements(GL_TRIANGLES, count = 6, GL_UNSIGNED_INT, indices = nil)
|
||||||
@ -176,14 +186,16 @@ proc main() =
|
|||||||
|
|
||||||
var shaderProgram = newShaderProgram(vertexShader, fragmentShader)
|
var shaderProgram = newShaderProgram(vertexShader, fragmentShader)
|
||||||
|
|
||||||
|
let w = screenshot.width.float32
|
||||||
|
let h = screenshot.height.float32
|
||||||
var
|
var
|
||||||
vao, vbo, ebo: GLuint
|
vao, vbo, ebo: GLuint
|
||||||
vertices = [
|
vertices = [
|
||||||
# Position Texture coords
|
# Position Texture coords
|
||||||
[GLfloat 1.0, -1.0, 0.0, 1.0, 1.0], # Top right
|
[GLfloat w, 0, 0.0, 1.0, 1.0], # Top right
|
||||||
[GLfloat 1.0, 1.0, 0.0, 1.0, 0.0], # Bottom right
|
[GLfloat w, h, 0.0, 1.0, 0.0], # Bottom right
|
||||||
[GLfloat -1.0, 1.0, 0.0, 0.0, 0.0], # Bottom left
|
[GLfloat 0, h, 0.0, 0.0, 0.0], # Bottom left
|
||||||
[GLfloat -1.0, -1.0, 0.0, 0.0, 1.0] # Top left
|
[GLfloat 0, 0, 0.0, 0.0, 1.0] # Top left
|
||||||
]
|
]
|
||||||
indices = [GLuint(0), 1, 3,
|
indices = [GLuint(0), 1, 3,
|
||||||
1, 2, 3]
|
1, 2, 3]
|
||||||
@ -233,7 +245,6 @@ proc main() =
|
|||||||
|
|
||||||
glUniform1i(glGetUniformLocation(shaderProgram, "tex".cstring), 0)
|
glUniform1i(glGetUniformLocation(shaderProgram, "tex".cstring), 0)
|
||||||
|
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D)
|
glEnable(GL_TEXTURE_2D)
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
|
||||||
@ -241,8 +252,6 @@ proc main() =
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
|
||||||
|
|
||||||
glViewport(0, 0, screenshot.width, screenshot.height)
|
|
||||||
|
|
||||||
var
|
var
|
||||||
quitting = false
|
quitting = false
|
||||||
camera = Camera(scale: 1.0)
|
camera = Camera(scale: 1.0)
|
||||||
@ -251,6 +260,7 @@ proc main() =
|
|||||||
while not quitting:
|
while not quitting:
|
||||||
var wa: TXWindowAttributes
|
var wa: TXWindowAttributes
|
||||||
discard XGetWindowAttributes(display, win, addr wa)
|
discard XGetWindowAttributes(display, win, addr wa)
|
||||||
|
glViewport(0, 0, wa.width, wa.height)
|
||||||
|
|
||||||
var xev: TXEvent
|
var xev: TXEvent
|
||||||
while XPending(display) > 0:
|
while XPending(display) > 0:
|
||||||
@ -264,10 +274,11 @@ proc main() =
|
|||||||
xev.xmotion.y.float32)
|
xev.xmotion.y.float32)
|
||||||
|
|
||||||
if mouse.drag:
|
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.position += delta
|
||||||
camera.velocity = delta * config.dragVelocityFactor
|
camera.velocity = delta * config.dragVelocityFactor
|
||||||
mouse.prev = mouse.curr
|
|
||||||
|
mouse.prev = mouse.curr
|
||||||
|
|
||||||
of ClientMessage:
|
of ClientMessage:
|
||||||
if cast[TAtom](xev.xclient.data.l[0]) == wmDeleteMessage:
|
if cast[TAtom](xev.xclient.data.l[0]) == wmDeleteMessage:
|
||||||
@ -315,7 +326,9 @@ proc main() =
|
|||||||
|
|
||||||
camera.update(config, 1.0 / config.fps.float, mouse, screenshot)
|
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, wa.height.float32),
|
||||||
|
mouse)
|
||||||
|
|
||||||
glXSwapBuffers(display, win)
|
glXSwapBuffers(display, win)
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@ type Config* = object
|
|||||||
const defaultConfig* = Config(
|
const defaultConfig* = Config(
|
||||||
scrollSpeed: 1.0,
|
scrollSpeed: 1.0,
|
||||||
dragVelocityFactor: 10.0,
|
dragVelocityFactor: 10.0,
|
||||||
dragFriction: 1.0,
|
# TODO: For a natual feel dragFriction probably should depend on velocity
|
||||||
|
dragFriction: 600.0,
|
||||||
scaleFriction: 10.0,
|
scaleFriction: 10.0,
|
||||||
fps: 60
|
fps: 60
|
||||||
)
|
)
|
||||||
|
@ -7,6 +7,9 @@ proc vec2*(x: float32, y: float32): Vec2f = (x, y)
|
|||||||
proc `*`*(a: Vec2f, s: float32): Vec2f =
|
proc `*`*(a: Vec2f, s: float32): Vec2f =
|
||||||
vec2(a.x * s, a.y * s)
|
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 =
|
proc `*`*(a: Vec2f, b: Vec2f): Vec2f =
|
||||||
vec2(a.x * b.x, a.y * b.y)
|
vec2(a.x * b.x, a.y * b.y)
|
||||||
|
|
||||||
|
@ -14,12 +14,8 @@ type Camera* = object
|
|||||||
scale*: float32
|
scale*: float32
|
||||||
deltaScale*: float
|
deltaScale*: float
|
||||||
|
|
||||||
proc world*(point: Vec2f, image: Image, camera: Camera): Vec2f =
|
proc world*(camera: Camera, v: Vec2f): Vec2f =
|
||||||
let f = (camera.position + vec2(1.0f32, 1.0f32)) / vec2(2.0f32, 2.0f32)
|
(camera.position + v) / camera.scale
|
||||||
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 update*(camera: var Camera, config: Config, dt: float, mouse: Mouse, image: Image) =
|
proc update*(camera: var Camera, config: Config, dt: float, mouse: Mouse, image: Image) =
|
||||||
if abs(camera.deltaScale) > 0.5:
|
if abs(camera.deltaScale) > 0.5:
|
||||||
|
@ -2,10 +2,24 @@
|
|||||||
in vec3 aPos;
|
in vec3 aPos;
|
||||||
in vec2 aTexCoord;
|
in vec2 aTexCoord;
|
||||||
out vec2 texcoord;
|
out vec2 texcoord;
|
||||||
|
|
||||||
uniform vec2 cameraPos;
|
uniform vec2 cameraPos;
|
||||||
uniform float cameraScale;
|
uniform float cameraScale;
|
||||||
|
uniform vec2 windowSize;
|
||||||
|
uniform vec2 screenshotSize;
|
||||||
|
uniform vec2 cursorPos;
|
||||||
|
|
||||||
|
vec3 to_world(vec3 v) {
|
||||||
|
vec2 ratio = vec2(
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = vec4((aPos.x - cameraPos.x) * cameraScale, (aPos.y + cameraPos.y) * cameraScale, 0.0, 1.0);
|
gl_Position = vec4(to_world((aPos - vec3(cameraPos * vec2(1.0, -1.0), 0.0))), 1.0);
|
||||||
texcoord = aTexCoord;
|
texcoord = aTexCoord;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user