From b5a2479c1674116a8e0c8d573a4db5c18c814f24 Mon Sep 17 00:00:00 2001 From: bloeys Date: Fri, 14 Oct 2022 07:55:48 +0400 Subject: [PATCH] Skybox demo --- assets/textures.go | 16 +++---- main.go | 92 ++++++++++++++++++++++++++++++-------- res/models/obj.obj | 46 ------------------- res/models/skybox-cube.obj | 38 ++++++++++++++++ res/shaders/skybox.glsl | 33 ++++++++++++++ 5 files changed, 153 insertions(+), 72 deletions(-) delete mode 100755 res/models/obj.obj create mode 100755 res/models/skybox-cube.obj create mode 100755 res/shaders/skybox.glsl diff --git a/assets/textures.go b/assets/textures.go index 9a1c70d..ac2d1ff 100755 --- a/assets/textures.go +++ b/assets/textures.go @@ -2,6 +2,7 @@ package assets import ( "bytes" + "fmt" "image" "image/color" "image/jpeg" @@ -259,7 +260,7 @@ func LoadCubemapTextures(rightTex, leftTex, topTex, botTex, frontTex, backTex st imgDecoder = png.Decode pixelDecoder = pixelsFromNrgbaPng } else { - panic("unknown image extension: " + ext) + return Cubemap{}, fmt.Errorf("unknown image extension: %s. Expected one of: .jpg, .jpeg, .png", ext) } cmap := Cubemap{ @@ -271,8 +272,12 @@ func LoadCubemapTextures(rightTex, leftTex, topTex, botTex, frontTex, backTex st BackPath: backTex, } + gl.GenTextures(1, &cmap.TexID) + gl.BindTexture(gl.TEXTURE_CUBE_MAP, cmap.TexID) + + // The order here matters texturePaths := []string{rightTex, leftTex, topTex, botTex, frontTex, backTex} - for i := 0; i < len(texturePaths); i++ { + for i := uint32(0); i < uint32(len(texturePaths)); i++ { fPath := texturePaths[i] @@ -289,12 +294,7 @@ func LoadCubemapTextures(rightTex, leftTex, topTex, botTex, frontTex, backTex st pixels, width, height := pixelDecoder(img) - //Prepare opengl stuff - gl.GenTextures(1, &cmap.TexID) - gl.BindTexture(gl.TEXTURE_CUBE_MAP, cmap.TexID) - - // load and generate the texture - gl.TexImage2D(gl.TEXTURE_CUBE_MAP, 0, gl.RGBA8, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&pixels[0])) + gl.TexImage2D(uint32(gl.TEXTURE_CUBE_MAP_POSITIVE_X)+i, 0, gl.RGBA8, int32(width), int32(height), 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&pixels[0])) } // set the texture wrapping/filtering options (on the currently bound texture object) diff --git a/main.go b/main.go index b12e520..625d845 100755 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ import ( "github.com/bloeys/nmage/renderer/rend3dgl" "github.com/bloeys/nmage/timing" nmageimgui "github.com/bloeys/nmage/ui/imgui" + "github.com/go-gl/gl/v4.1-core/gl" "github.com/inkyblackness/imgui-go/v4" "github.com/veandco/go-sdl2/sdl" ) @@ -47,15 +48,19 @@ var ( cam *camera.Camera simpleMat *materials.Material - cubeMesh *meshes.Mesh + skyboxMat *materials.Material + + chairMesh *meshes.Mesh + cubeMesh *meshes.Mesh + skyboxMesh *meshes.Mesh cubeModelMat = gglm.NewTrMatId() lightPos1 = gglm.NewVec3(-2, 0, 2) lightColor1 = gglm.NewVec3(1, 1, 1) - debugDrawDepthBuffer bool debugDepthMat *materials.Material + debugDrawDepthBuffer bool skyboxCmap assets.Cubemap ) @@ -153,16 +158,27 @@ func (g *OurGame) handleWindowEvents(e sdl.Event) { func (g *OurGame) Init() { + var err error + //Create materials simpleMat = materials.NewMaterial("Simple mat", "./res/shaders/simple.glsl") - debugDepthMat = materials.NewMaterial("Debug depth math", "./res/shaders/debug-depth.glsl") + debugDepthMat = materials.NewMaterial("Debug depth mat", "./res/shaders/debug-depth.glsl") + skyboxMat = materials.NewMaterial("Skybox mat", "./res/shaders/skybox.glsl") //Load meshes - var err error - cubeMesh, err = meshes.NewMesh("Cube", "./res/models/chair.fbx", 0) - // cubeMesh, err = meshes.NewMesh("Cube", "./res/models/tex-cube.fbx", 0) + cubeMesh, err = meshes.NewMesh("Cube", "./res/models/tex-cube.fbx", 0) if err != nil { - logging.ErrLog.Fatalln("Failed to load cube mesh. Err: ", err) + logging.ErrLog.Fatalln("Failed to load mesh. Err: ", err) + } + + chairMesh, err = meshes.NewMesh("Chair", "./res/models/chair.fbx", 0) + if err != nil { + logging.ErrLog.Fatalln("Failed to load mesh. Err: ", err) + } + + skyboxMesh, err = meshes.NewMesh("Skybox", "./res/models/skybox-cube.obj", 0) + if err != nil { + logging.ErrLog.Fatalln("Failed to load mesh. Err: ", err) } //Load textures @@ -171,16 +187,16 @@ func (g *OurGame) Init() { logging.ErrLog.Fatalln("Failed to load texture. Err: ", err) } - // skyboxCmap, err = assets.LoadCubemapTextures( - // "./res/textures/sb-right.jpg", "./res/textures/sb-left.jpg", - // "./res/textures/sb-top.jpg", "./res/textures/sb-bottom.jpg", - // "./res/textures/sb-front.jpg", "./res/textures/sb-back.jpg", - // ) - // if err != nil { - // logging.ErrLog.Fatalln("Failed to load cubemap. Err: ", err) - // } + skyboxCmap, err = assets.LoadCubemapTextures( + "./res/textures/sb-right.jpg", "./res/textures/sb-left.jpg", + "./res/textures/sb-top.jpg", "./res/textures/sb-bottom.jpg", + "./res/textures/sb-front.jpg", "./res/textures/sb-back.jpg", + ) + if err != nil { + logging.ErrLog.Fatalln("Failed to load cubemap. Err: ", err) + } - //Configure material + // Configure materials simpleMat.DiffuseTex = tex.TexID //Movement, scale and rotation @@ -249,6 +265,8 @@ func (g *OurGame) Update() { if input.KeyClicked(sdl.K_F4) { fmt.Printf("Pos: %s; Forward: %s; |Forward|: %f\n", cam.Pos.String(), cam.Forward.String(), cam.Forward.Mag()) } + + g.Win.SDLWin.SetTitle(fmt.Sprint("nMage (", timing.GetAvgFPS(), " fps)")) } func (g *OurGame) updateCameraLookAround() { @@ -322,13 +340,51 @@ func (g *OurGame) Render() { rowSize := 1 for y := 0; y < rowSize; y++ { for x := 0; x < rowSize; x++ { - tempModelMatrix.Translate(gglm.NewVec3(-1, 0, 0)) + tempModelMatrix.Translate(gglm.NewVec3(-6, 0, 0)) window.Rend.Draw(cubeMesh, tempModelMatrix, matToUse) } tempModelMatrix.Translate(gglm.NewVec3(float32(rowSize), -1, 0)) } - g.Win.SDLWin.SetTitle(fmt.Sprint("nMage (", timing.GetAvgFPS(), " fps)")) + g.DrawSkybox() +} + +func (g *OurGame) DrawSkybox() { + + // glDepthMask(GL_FALSE); + // skyboxShader.use(); + // // ... set view and projection matrix + // glBindVertexArray(skyboxVAO); + // glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture); + // glDrawArrays(GL_TRIANGLES, 0, 36); + // glDepthMask(GL_TRUE); + // // ... draw rest of the scene + + gl.Disable(gl.CULL_FACE) + gl.DepthFunc(gl.LEQUAL) + skyboxMesh.Buf.Bind() + skyboxMat.Bind() + gl.ActiveTexture(gl.TEXTURE0) + gl.BindTexture(gl.TEXTURE_CUBE_MAP, skyboxCmap.TexID) + + viewMat := cam.ViewMat.Clone() + viewMat.Set(0, 3, 0) + viewMat.Set(1, 3, 0) + viewMat.Set(2, 3, 0) + viewMat.Set(3, 0, 0) + viewMat.Set(3, 1, 0) + viewMat.Set(3, 2, 0) + viewMat.Set(3, 3, 0) + + skyboxMat.SetUnifMat4("viewMat", viewMat) + skyboxMat.SetUnifMat4("projMat", &cam.ProjMat) + // window.Rend.Draw(cubeMesh, gglm.NewTrMatId(), skyboxMat) + for i := 0; i < len(skyboxMesh.SubMeshes); i++ { + gl.DrawElementsBaseVertexWithOffset(gl.TRIANGLES, skyboxMesh.SubMeshes[i].IndexCount, gl.UNSIGNED_INT, uintptr(skyboxMesh.SubMeshes[i].BaseIndex), skyboxMesh.SubMeshes[i].BaseVertex) + } + + gl.DepthFunc(gl.LESS) + gl.Enable(gl.CULL_FACE) } func (g *OurGame) FrameEnd() { diff --git a/res/models/obj.obj b/res/models/obj.obj deleted file mode 100755 index 120d61f..0000000 --- a/res/models/obj.obj +++ /dev/null @@ -1,46 +0,0 @@ -# Blender v2.92.0 OBJ File: '' -# www.blender.org -mtllib obj.mtl -o Cube -v 2.275618 1.000000 0.349413 -v 3.520138 -1.000000 0.102233 -v 2.275618 1.000000 0.752820 -v 3.520138 -1.000000 1.000000 -v 0.244520 1.000000 0.349413 -v -1.000000 -1.000000 0.102233 -v 0.244520 1.000000 0.752820 -v -1.000000 -1.000000 1.000000 -vt 0.806168 0.568832 -vt 0.693832 0.681168 -vt 0.693832 0.568832 -vt 0.375000 1.000000 -vt 0.375000 0.750000 -vt 0.375000 0.000000 -vt 0.625000 0.250000 -vt 0.375000 0.250000 -vt 0.375000 0.500000 -vt 0.125000 0.750000 -vt 0.125000 0.500000 -vt 0.806168 0.681168 -vt 0.625000 0.931168 -vt 0.625000 0.068832 -vn 0.0000 1.0000 0.0000 -vn 0.0000 0.1227 0.9924 -vn -0.8490 0.5283 0.0000 -vn 0.0000 -1.0000 0.0000 -vn 0.8490 0.5283 0.0000 -vn 0.0000 0.1227 -0.9924 -usemtl Material -s off -f 5/1/1 3/2/1 1/3/1 -f 3/2/2 8/4/2 4/5/2 -f 8/6/3 5/7/3 6/8/3 -f 2/9/4 8/10/4 6/11/4 -f 1/3/5 4/5/5 2/9/5 -f 5/7/6 2/9/6 6/8/6 -f 5/1/1 7/12/1 3/2/1 -f 3/2/2 7/13/2 8/4/2 -f 8/6/3 7/14/3 5/7/3 -f 2/9/4 4/5/4 8/10/4 -f 1/3/5 3/2/5 4/5/5 -f 5/7/6 1/3/6 2/9/6 diff --git a/res/models/skybox-cube.obj b/res/models/skybox-cube.obj new file mode 100755 index 0000000..a6b3aec --- /dev/null +++ b/res/models/skybox-cube.obj @@ -0,0 +1,38 @@ +# Blender v2.92.0 OBJ File: 'chair.blend' +# www.blender.org +o Cube.002_Cube.005 +v -1.000000 -1.000000 1.000000 +v -1.000000 1.000000 1.000000 +v -1.000000 -1.000000 -1.000000 +v -1.000000 1.000000 -1.000000 +v 1.000000 -1.000000 1.000000 +v 1.000000 1.000000 1.000000 +v 1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 -1.000000 +vt 0.375000 0.000000 +vt 0.625000 0.000000 +vt 0.625000 0.250000 +vt 0.375000 0.250000 +vt 0.625000 0.500000 +vt 0.375000 0.500000 +vt 0.625000 0.750000 +vt 0.375000 0.750000 +vt 0.625000 1.000000 +vt 0.375000 1.000000 +vt 0.125000 0.500000 +vt 0.125000 0.750000 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/8/4 6/7/4 2/9/4 1/10/4 +f 3/11/5 7/6/5 5/8/5 1/12/5 +f 8/5/6 4/13/6 2/14/6 6/7/6 diff --git a/res/shaders/skybox.glsl b/res/shaders/skybox.glsl new file mode 100755 index 0000000..149825b --- /dev/null +++ b/res/shaders/skybox.glsl @@ -0,0 +1,33 @@ +//shader:vertex +#version 410 + +layout(location=0) in vec3 vertPosIn; +layout(location=1) in vec3 vertNormalIn; +layout(location=2) in vec2 vertUV0In; +layout(location=3) in vec3 vertColorIn; + +out vec3 vertUV0; + +uniform mat4 viewMat; +uniform mat4 projMat; + +void main() +{ + vertUV0 = vec3(vertPosIn.x, vertPosIn.y, -vertPosIn.z); + vec4 pos = projMat * viewMat * vec4(vertPosIn, 1.0); + gl_Position = pos.xyww; +} + +//shader:fragment +#version 410 + +in vec3 vertUV0; + +out vec4 fragColor; + +uniform samplerCube skybox; + +void main() +{ + fragColor = texture(skybox, vertUV0); +}