-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add View Bobbing to Camera #665
base: master
Are you sure you want to change the base?
Changes from 6 commits
86960eb
2ced078
81b8e6c
8a3efbd
f1b407a
955b0ed
40802d3
505bb4c
9d1ac23
9111b2b
3e63eb5
c9b0c24
bf826a6
27b7930
9041c69
1e7794d
eaee832
a9e8cf3
fc22875
67be310
ffd36e7
cc29de7
cc2dec6
862c982
ca0c4e8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -121,8 +121,7 @@ pub fn updateViewport(width: u31, height: u31, fov: f32) void { | |
worldFrameBuffer.unbind(); | ||
} | ||
|
||
pub fn render(playerPosition: Vec3d) void { | ||
// TODO: player bobbing | ||
pub fn render() void { | ||
if(game.world) |world| { | ||
// TODO: Handle colors and sun position in the world. | ||
var ambient: Vec3f = undefined; | ||
|
@@ -132,7 +131,7 @@ pub fn render(playerPosition: Vec3d) void { | |
const skyColor = vec.xyz(world.clearColor); | ||
game.fog.skyColor = skyColor; | ||
|
||
renderWorld(world, ambient, skyColor, playerPosition); | ||
renderWorld(world, ambient, skyColor); | ||
const startTime = std.time.milliTimestamp(); | ||
mesh_storage.updateMeshes(startTime + maximumMeshTime); | ||
} else { | ||
|
@@ -164,12 +163,27 @@ pub fn crosshairDirection(rotationMatrix: Mat4f, fovY: f32, width: u31, height: | |
return adjusted; | ||
} | ||
|
||
pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPos: Vec3d) void { // MARK: renderWorld() | ||
pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f) void { // MARK: renderWorld() | ||
worldFrameBuffer.bind(); | ||
c.glViewport(0, 0, lastWidth, lastHeight); | ||
gpu_performance_measuring.startQuery(.clear); | ||
worldFrameBuffer.clear(Vec4f{skyColor[0], skyColor[1], skyColor[2], 1}); | ||
gpu_performance_measuring.stopQuery(); | ||
|
||
const playerPos = game.Player.getEyePosBlocking(); | ||
const playerRot = game.camera.rotation; | ||
const cameraPos = game.Player.applyViewBobbingPosBlocking(playerPos); | ||
const cameraRot = game.Player.applyViewBobbingRotBlocking(playerRot); | ||
|
||
// Get view matrix before view bobbing is applied | ||
game.camera.updateViewMatrix(); | ||
const baseViewMatrix = game.camera.viewMatrix; | ||
|
||
const oldCameraRot = game.camera.rotation; | ||
defer game.camera.rotation = oldCameraRot; | ||
game.camera.rotation = cameraRot; | ||
|
||
// View matrix after view bobbing is applied | ||
game.camera.updateViewMatrix(); | ||
|
||
// Uses FrustumCulling on the chunks. | ||
|
@@ -181,10 +195,9 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo | |
gpu_performance_measuring.startQuery(.animation); | ||
blocks.meshes.preProcessAnimationData(time); | ||
gpu_performance_measuring.stopQuery(); | ||
|
||
|
||
// Update the uniforms. The uniforms are needed to render the replacement meshes. | ||
chunk_meshing.bindShaderAndUniforms(game.projectionMatrix, ambientLight, playerPos); | ||
chunk_meshing.bindShaderAndUniforms(game.projectionMatrix, ambientLight, cameraPos); | ||
|
||
c.glActiveTexture(c.GL_TEXTURE0); | ||
blocks.meshes.blockTextureArray.bind(); | ||
|
@@ -199,9 +212,9 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo | |
const meshes = mesh_storage.updateAndGetRenderChunks(world.conn, playerPos, settings.renderDistance); | ||
|
||
gpu_performance_measuring.startQuery(.chunk_rendering_preparation); | ||
const direction = crosshairDirection(game.camera.viewMatrix, lastFov, lastWidth, lastHeight); | ||
const direction = crosshairDirection(baseViewMatrix, lastFov, lastWidth, lastHeight); | ||
MeshSelection.select(playerPos, direction, game.Player.inventory__SEND_CHANGES_TO_SERVER.items[game.Player.selectedSlot]); | ||
MeshSelection.render(game.projectionMatrix, game.camera.viewMatrix, playerPos); | ||
MeshSelection.render(game.projectionMatrix, game.camera.viewMatrix, cameraPos); | ||
|
||
chunk_meshing.beginRender(); | ||
|
||
|
@@ -212,13 +225,13 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo | |
} | ||
gpu_performance_measuring.stopQuery(); | ||
if(chunkList.items.len != 0) { | ||
chunk_meshing.drawChunksIndirect(chunkList.items, game.projectionMatrix, ambientLight, playerPos, false); | ||
chunk_meshing.drawChunksIndirect(chunkList.items, game.projectionMatrix, ambientLight, cameraPos, false); | ||
} | ||
|
||
gpu_performance_measuring.startQuery(.entity_rendering); | ||
entity.ClientEntityManager.render(game.projectionMatrix, ambientLight, .{1, 0.5, 0.25}, playerPos); | ||
entity.ClientEntityManager.render(game.projectionMatrix, ambientLight, .{1, 0.5, 0.25}, cameraPos); | ||
|
||
itemdrop.ItemDropRenderer.renderItemDrops(game.projectionMatrix, ambientLight, playerPos, time); | ||
itemdrop.ItemDropRenderer.renderItemDrops(game.projectionMatrix, ambientLight, cameraPos, time); | ||
gpu_performance_measuring.stopQuery(); | ||
|
||
// Render transparent chunk meshes: | ||
|
@@ -237,11 +250,11 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo | |
while(true) { | ||
if(i == 0) break; | ||
i -= 1; | ||
meshes[i].prepareTransparentRendering(playerPos, &chunkList); | ||
meshes[i].prepareTransparentRendering(cameraPos, &chunkList); | ||
} | ||
gpu_performance_measuring.stopQuery(); | ||
if(chunkList.items.len != 0) { | ||
chunk_meshing.drawChunksIndirect(chunkList.items, game.projectionMatrix, ambientLight, playerPos, true); | ||
chunk_meshing.drawChunksIndirect(chunkList.items, game.projectionMatrix, ambientLight, cameraPos, true); | ||
} | ||
} | ||
c.glDepthMask(c.GL_TRUE); | ||
|
@@ -287,7 +300,7 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo | |
|
||
c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0); | ||
|
||
entity.ClientEntityManager.renderNames(game.projectionMatrix, playerPos); | ||
entity.ClientEntityManager.renderNames(game.projectionMatrix, cameraPos); | ||
gpu_performance_measuring.stopQuery(); | ||
} | ||
|
||
|
@@ -556,7 +569,7 @@ pub const MenuBackGround = struct { | |
// Draw to frame buffer. | ||
buffer.bind(); | ||
c.glClear(c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT | c.GL_COLOR_BUFFER_BIT); | ||
main.renderer.render(game.Player.getEyePosBlocking()); | ||
main.renderer.render(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that your method will now always apply bobbing to any render call. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not quite sure what you mean here in terms of background seams, but yes, view bobbing will apply to all render calls that also render the world, although shouldn't happen on the title screen as that's a different code path. The only thing I can think that could be done differently would be to let the camera store its own position, so no player-related data needs to be passed to the renderer, and then handle the special case of the block selection somehow as we don't want to have view bobbing affect it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, decoupling the player and the camera position might be a good idea generally, as it would allow for third person/spectator and other camera effects to be handled in some update loop instead of directly in the rendering code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Hard agree. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If you press Ctrl+print screen, then the game records a background image at your location. This is done by rendering the screen 4 times with a 90° angle in between. If your camera is angled from view bobbing, then this means that these 4 images are rotated, and don't fit together seamlessly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
// Copy the pixels directly from OpenGL | ||
buffer.bind(); | ||
c.glReadPixels(0, 0, size, size, c.GL_RGBA, c.GL_UNSIGNED_BYTE, pixels.ptr); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we are using
crosshairDirection
instead of justgame.camera.direction
?game.camera.direction
seems to do the same without having to extract the direction from the view matrix.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#323
Try moving the crosshair in menu mode. Check if block selection is still accurate after removing this code.