mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
Fix item texture rendering. (It now includes the fog effect)
The background is not yet transparent, but I think it's good enough for now.
This commit is contained in:
parent
6269356a42
commit
86a5bdded5
@ -238,8 +238,6 @@ void main() {
|
||||
fragColor.rgb -= fogColor;
|
||||
blendColor.rgb = vec3(1);
|
||||
}
|
||||
//blendColor.rgb = vec3(0);
|
||||
//fragColor = vec4(1, 1, 1, 1);
|
||||
} else {
|
||||
if(emptyBackFace) {
|
||||
fragColor = vec4(0, 0, 0, 1);
|
||||
@ -250,9 +248,5 @@ void main() {
|
||||
fragColor.rgb += fogFactor*fogColor;
|
||||
}
|
||||
blendColor.rgb = vec3(1);
|
||||
|
||||
|
||||
//blendColor.rgb = vec3(0);
|
||||
//fragColor = vec4(1, 0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
18
assets/cubyz/shaders/item_texture_post.fs
Normal file
18
assets/cubyz/shaders/item_texture_post.fs
Normal file
@ -0,0 +1,18 @@
|
||||
#version 430
|
||||
out vec4 fragColor;
|
||||
|
||||
in vec2 texCoords;
|
||||
|
||||
uniform sampler2D color;
|
||||
uniform bool transparent;
|
||||
|
||||
void main() {
|
||||
fragColor = texture(color, texCoords);
|
||||
if(transparent) {
|
||||
fragColor.rgb /= fragColor.a;
|
||||
fragColor.a = 1;
|
||||
// TODO: Remove the background color. Somehow?
|
||||
}
|
||||
float maxColor = max(1.0, max(fragColor.r, max(fragColor.g, fragColor.b)));
|
||||
fragColor.rgb = fragColor.rgb/maxColor;
|
||||
}
|
10
assets/cubyz/shaders/item_texture_post.vs
Normal file
10
assets/cubyz/shaders/item_texture_post.vs
Normal file
@ -0,0 +1,10 @@
|
||||
#version 430
|
||||
|
||||
layout (location=0) in vec2 inTexCoords;
|
||||
|
||||
out vec2 texCoords;
|
||||
|
||||
void main() {
|
||||
texCoords = inTexCoords;
|
||||
gl_Position = vec4(inTexCoords*2 - vec2(1, 1), 0, 1);
|
||||
}
|
119
src/graphics.zig
119
src/graphics.zig
@ -6,6 +6,7 @@ const std = @import("std");
|
||||
const freetype = @import("freetype");
|
||||
const harfbuzz = @import("harfbuzz");
|
||||
|
||||
const Mat4f = @import("vec.zig").Mat4f;
|
||||
const Vec4i = @import("vec.zig").Vec4i;
|
||||
const Vec4f = @import("vec.zig").Vec4f;
|
||||
const Vec2f = @import("vec.zig").Vec2f;
|
||||
@ -1031,6 +1032,7 @@ pub fn init() !void {
|
||||
draw.initLine();
|
||||
draw.initRect();
|
||||
try TextRendering.init();
|
||||
try block_texture.init();
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
@ -1040,6 +1042,7 @@ pub fn deinit() void {
|
||||
draw.deinitLine();
|
||||
draw.deinitRect();
|
||||
TextRendering.deinit();
|
||||
block_texture.deinit();
|
||||
}
|
||||
|
||||
pub const Shader = struct {
|
||||
@ -1604,3 +1607,119 @@ pub const Fog = struct {
|
||||
color: Vec3f,
|
||||
density: f32,
|
||||
};
|
||||
|
||||
const block_texture = struct {
|
||||
var uniforms: struct {
|
||||
color: c_int,
|
||||
transparent: c_int,
|
||||
} = undefined;
|
||||
var shader: Shader = undefined;
|
||||
var depthTexture: Texture = undefined;
|
||||
const textureSize = 128;
|
||||
|
||||
fn init() !void {
|
||||
shader = try Shader.initAndGetUniforms("assets/cubyz/shaders/item_texture_post.vs", "assets/cubyz/shaders/item_texture_post.fs", &uniforms);
|
||||
depthTexture = Texture.init();
|
||||
depthTexture.bind();
|
||||
var data: [128*128]f32 = undefined;
|
||||
@memset(&data, main.renderer.zNear/132.0);
|
||||
c.glTexImage2D(c.GL_TEXTURE_2D, 0, c.GL_R32F, textureSize, textureSize, 0, c.GL_RED, c.GL_FLOAT, &data);
|
||||
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MIN_FILTER, c.GL_NEAREST);
|
||||
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MAG_FILTER, c.GL_NEAREST);
|
||||
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_WRAP_S, c.GL_REPEAT);
|
||||
c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_WRAP_T, c.GL_REPEAT);
|
||||
}
|
||||
fn deinit() void {
|
||||
shader.deinit();
|
||||
depthTexture.deinit();
|
||||
}
|
||||
};
|
||||
|
||||
pub fn generateBlockTexture(blockType: u16) !Texture {
|
||||
const block = main.blocks.Block{.typ = blockType, .data = 0}; // TODO: Use natural standard data.
|
||||
const textureSize = block_texture.textureSize;
|
||||
c.glViewport(0, 0, textureSize, textureSize);
|
||||
|
||||
var frameBuffer: FrameBuffer = undefined;
|
||||
const scissor = c.glIsEnabled(c.GL_SCISSOR_TEST);
|
||||
c.glDisable(c.GL_SCISSOR_TEST);
|
||||
defer if(scissor != 0) c.glEnable(c.GL_SCISSOR_TEST);
|
||||
const depthTest = c.glIsEnabled(c.GL_DEPTH_TEST);
|
||||
c.glDisable(c.GL_DEPTH_TEST);
|
||||
defer if(depthTest != 0) c.glEnable(c.GL_DEPTH_TEST);
|
||||
const cullFace = c.glIsEnabled(c.GL_CULL_FACE);
|
||||
c.glDisable(c.GL_CULL_FACE);
|
||||
defer if(cullFace != 0) c.glEnable(c.GL_CULL_FACE);
|
||||
|
||||
frameBuffer.init(false, c.GL_NEAREST, c.GL_REPEAT);
|
||||
defer frameBuffer.deinit();
|
||||
frameBuffer.updateSize(textureSize, textureSize, c.GL_RGBA16F);
|
||||
frameBuffer.bind();
|
||||
if(block.transparent()) {
|
||||
frameBuffer.clear(.{0.683421, 0.6854237, 0.685426, 1}); // TODO: Alpha must be 1 for fog!
|
||||
} else {
|
||||
frameBuffer.clear(.{0, 0, 0, 0});
|
||||
}
|
||||
|
||||
const projMatrix = Mat4f.perspective(0.013, 1, 64);
|
||||
const oldViewMatrix = main.game.camera.viewMatrix;
|
||||
main.game.camera.viewMatrix = Mat4f.rotationX(std.math.pi/4.0).mul(Mat4f.rotationY(-std.math.pi/4.0));
|
||||
defer main.game.camera.viewMatrix = oldViewMatrix;
|
||||
if(block.transparent()) {
|
||||
c.glBlendEquationSeparate(c.GL_FUNC_ADD, c.GL_FUNC_ADD);
|
||||
c.glBlendFuncSeparate(c.GL_DST_ALPHA, c.GL_SRC1_COLOR, c.GL_DST_ALPHA, c.GL_ZERO);
|
||||
main.chunk.meshing.bindTransparentShaderAndUniforms(projMatrix, .{1, 1, 1}, 0);
|
||||
} else {
|
||||
main.chunk.meshing.bindShaderAndUniforms(projMatrix, .{1, 1, 1}, 0);
|
||||
}
|
||||
const uniforms = if(block.transparent()) &main.chunk.meshing.transparentUniforms else &main.chunk.meshing.uniforms;
|
||||
|
||||
var faceData: [6]main.chunk.meshing.FaceData = undefined;
|
||||
var faces: u8 = 0;
|
||||
if(block.hasBackFace()) {
|
||||
faceData[2] = main.chunk.meshing.ChunkMesh.constructFaceData(block, main.chunk.Neighbors.dirPosX, 1, 1, 1, true);
|
||||
faceData[1] = main.chunk.meshing.ChunkMesh.constructFaceData(block, main.chunk.Neighbors.dirUp, 1, 1, 1, true);
|
||||
faceData[0] = main.chunk.meshing.ChunkMesh.constructFaceData(block, main.chunk.Neighbors.dirPosZ, 1, 1, 1, true);
|
||||
faces += 3;
|
||||
}
|
||||
faceData[faces + 0] = main.chunk.meshing.ChunkMesh.constructFaceData(block, main.chunk.Neighbors.dirPosX, 1+1, 1, 1, false);
|
||||
faceData[faces + 1] = main.chunk.meshing.ChunkMesh.constructFaceData(block, main.chunk.Neighbors.dirUp, 1, 1+1, 1, false);
|
||||
faceData[faces + 2] = main.chunk.meshing.ChunkMesh.constructFaceData(block, main.chunk.Neighbors.dirPosZ, 1, 1, 1+1, false);
|
||||
faces += 3;
|
||||
var allocation: LargeBuffer.Allocation = .{.start = 0, .len = 0};
|
||||
try main.chunk.meshing.faceBuffer.realloc(&allocation, faces*@sizeOf(main.chunk.meshing.FaceData));
|
||||
main.chunk.meshing.faceBuffer.bufferSubData(allocation.start, main.chunk.meshing.FaceData, faceData[0..faces]);
|
||||
|
||||
c.glUniform3f(uniforms.modelPosition, -65.5 - 1.5, -92.631 - 1.5, -65.5 - 1.5);
|
||||
c.glUniform1i(uniforms.visibilityMask, 0xff);
|
||||
c.glUniform1i(uniforms.voxelSize, 1);
|
||||
c.glActiveTexture(c.GL_TEXTURE0);
|
||||
main.blocks.meshes.blockTextureArray.bind();
|
||||
c.glActiveTexture(c.GL_TEXTURE1);
|
||||
main.blocks.meshes.emissionTextureArray.bind();
|
||||
block_texture.depthTexture.bindTo(3);
|
||||
c.glDrawElementsBaseVertex(c.GL_TRIANGLES, 6*faces, c.GL_UNSIGNED_INT, null, allocation.start/8*4);
|
||||
|
||||
var finalFrameBuffer: FrameBuffer = undefined;
|
||||
finalFrameBuffer.init(false, c.GL_NEAREST, c.GL_REPEAT);
|
||||
finalFrameBuffer.updateSize(textureSize, textureSize, c.GL_RGBA8);
|
||||
finalFrameBuffer.bind();
|
||||
var texture = Texture{.textureID = finalFrameBuffer.texture};
|
||||
defer c.glDeleteFramebuffers(1, &finalFrameBuffer.frameBuffer);
|
||||
block_texture.shader.bind();
|
||||
c.glUniform1i(block_texture.uniforms.transparent, if(block.transparent()) c.GL_TRUE else c.GL_FALSE);
|
||||
c.glUniform1i(block_texture.uniforms.color, 3);
|
||||
frameBuffer.bindTexture(c.GL_TEXTURE3);
|
||||
|
||||
c.glBindVertexArray(draw.rectVAO);
|
||||
c.glDisable(c.GL_BLEND);
|
||||
c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4);
|
||||
c.glEnable(c.GL_BLEND);
|
||||
|
||||
c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0);
|
||||
|
||||
try main.chunk.meshing.faceBuffer.free(allocation);
|
||||
c.glViewport(0, 0, main.Window.width, main.Window.height);
|
||||
c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
|
||||
return texture;
|
||||
}
|
@ -118,58 +118,10 @@ pub const BaseItem = struct {
|
||||
pub fn getTexture(self: *BaseItem) !graphics.Texture {
|
||||
if(self.texture == null) {
|
||||
if(self.block) |blockType| {
|
||||
const block = main.blocks.Block{.typ = blockType, .data = 0}; // TODO: Use natural standard data.
|
||||
const c = graphics.c;
|
||||
c.glViewport(0, 0, 128, 128);
|
||||
|
||||
var frameBuffer: graphics.FrameBuffer = undefined;
|
||||
const scissor = c.glIsEnabled(c.GL_SCISSOR_TEST);
|
||||
c.glDisable(c.GL_SCISSOR_TEST);
|
||||
defer if(scissor != 0) c.glEnable(c.GL_SCISSOR_TEST);
|
||||
const cullFace = c.glIsEnabled(c.GL_CULL_FACE);
|
||||
c.glEnable(c.GL_CULL_FACE);
|
||||
defer if(cullFace == 0) c.glDisable(c.GL_CULL_FACE);
|
||||
|
||||
frameBuffer.init(false, c.GL_NEAREST, c.GL_REPEAT);
|
||||
frameBuffer.updateSize(128, 128, c.GL_RGBA8);
|
||||
frameBuffer.bind();
|
||||
frameBuffer.clear(.{1, 1, 1, 0});
|
||||
self.texture = graphics.Texture{.textureID = frameBuffer.texture};
|
||||
defer c.glDeleteFramebuffers(1, &frameBuffer.frameBuffer);
|
||||
|
||||
const projMatrix = Mat4f.perspective(0.013, 1, 64);
|
||||
const oldViewMatrix = main.game.camera.viewMatrix;
|
||||
main.game.camera.viewMatrix = Mat4f.rotationX(std.math.pi/4.0).mul(Mat4f.rotationY(-std.math.pi/4.0));
|
||||
defer main.game.camera.viewMatrix = oldViewMatrix;
|
||||
if(block.transparent()) {
|
||||
c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_SRC1_COLOR);
|
||||
chunk.meshing.bindTransparentShaderAndUniforms(projMatrix, .{1, 1, 1}, 0);
|
||||
} else {
|
||||
chunk.meshing.bindShaderAndUniforms(projMatrix, .{1, 1, 1}, 0);
|
||||
}
|
||||
const uniforms = if(block.transparent()) &chunk.meshing.transparentUniforms else &chunk.meshing.uniforms;
|
||||
|
||||
var allocation: graphics.LargeBuffer.Allocation = .{.start = 0, .len = 0};
|
||||
try chunk.meshing.faceBuffer.realloc(&allocation, 3*@sizeOf(chunk.meshing.FaceData));
|
||||
var faceData: [3]chunk.meshing.FaceData = undefined;
|
||||
faceData[0] = chunk.meshing.ChunkMesh.constructFaceData(block, chunk.Neighbors.dirPosX, 1+1, 1, 1, false);
|
||||
faceData[1] = chunk.meshing.ChunkMesh.constructFaceData(block, chunk.Neighbors.dirUp, 1, 1+1, 1, false);
|
||||
faceData[2] = chunk.meshing.ChunkMesh.constructFaceData(block, chunk.Neighbors.dirPosZ, 1, 1, 1+1, false);
|
||||
// TODO: Add back faces for foggy blocks.
|
||||
chunk.meshing.faceBuffer.bufferSubData(allocation.start, chunk.meshing.FaceData, &faceData);
|
||||
|
||||
c.glUniform3f(uniforms.modelPosition, -65.5 - 1.5, -92.631 - 1.5, -65.5 - 1.5);
|
||||
c.glUniform1i(uniforms.visibilityMask, 0xff);
|
||||
c.glUniform1i(uniforms.voxelSize, 1);
|
||||
c.glActiveTexture(c.GL_TEXTURE0);
|
||||
main.blocks.meshes.blockTextureArray.bind();
|
||||
c.glActiveTexture(c.GL_TEXTURE1);
|
||||
main.blocks.meshes.emissionTextureArray.bind();
|
||||
c.glDrawElementsBaseVertex(c.GL_TRIANGLES, 18, c.GL_UNSIGNED_INT, null, allocation.start/8*4);
|
||||
|
||||
try chunk.meshing.faceBuffer.free(allocation);
|
||||
c.glViewport(0, 0, main.Window.width, main.Window.height);
|
||||
c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
|
||||
self.texture = try graphics.generateBlockTexture(blockType);
|
||||
var ret = self.texture.?;
|
||||
self.texture = null;
|
||||
return ret;
|
||||
} else {
|
||||
self.texture = graphics.Texture.init();
|
||||
try self.texture.?.generate(self.image);
|
||||
|
Loading…
x
Reference in New Issue
Block a user