3D立方体边重叠

3D cube sides overlapping

我在业余时间教授 OpenGL。我在 C++ 上找到了一个很好的复杂课程。但由于我对 C# 的热爱无法克服,我决定重写他的所有代码。经过几个小时的折磨,一切都好起来了,但是立方体的边相互贴合并且显示不正确。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SFML.Graphics;
using SFML.Window;
using SFML.System;
using System.Timers;
//using CSharpGL;
using Tao.FreeGlut;
using Tao.OpenGl;
using Tao.FreeType;
using Tao.Platform;
using Tao.Sdl;
using static Tao.OpenGl.Gl;
using Tao;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace BlockWorld
{
    class Program
    {
        public static uint LoadTexture(string path)
        {
            uint[] texture = { 0 };
            Image image = new Image(path);
            Gl.glGenTextures(1, texture);
            //Convert.ToInt32(OpenGL.GL_TEXTURE_2D)
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture[0]);
            Gl.glTexImage2D(
                Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA,
                (int)image.Size.X, (int)image.Size.Y,
                0,
                Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, GetPixelsPtr(image.Pixels)
            );
            Gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            Gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
           // Gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
           // Gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            return texture[0];
        }

        static void Main(string[] args)
        {
            //Console.WriteLine(PercentFrom(100, 35).ToString());
            RenderWindow win = new RenderWindow(new VideoMode(800, 600), "BlockWorld");
            Stopwatch sw = Stopwatch.StartNew();
            SFML.Graphics.Texture t = new SFML.Graphics.Texture(@"res\skybox\skybox_front.bmp");
            Sprite background = new Sprite(t);
            background.Position = new SFML.System.Vector2f(1f, 1f);
            background.Scale = new SFML.System.Vector2f(1.4f, 1f);

            uint[] Box = { 0, 0, 0, 0, 0, 0 };

            Box[0] = LoadTexture(@"res\box.jpg");
            Box[1] = LoadTexture(@"res\box.jpg");
            Box[2] = LoadTexture(@"res\box.jpg");
            Box[3] = LoadTexture(@"res\box.jpg");
            Box[4] = LoadTexture(@"res\box.jpg");
            Box[5] = LoadTexture(@"res\box.jpg");


            glEnable(GL_DEPTH_TEST);           
            glDepthFunc(GL_LEQUAL);
            glDepthMask(GL_TRUE);
            glClearDepth(1.0f);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            Glu.gluPerspective(90.0f, 1.0f, 1.0f, 500.0f);
            //Glu.gluPerspective(45, (float)800/600, 0, 20);

            glEnable(GL_TEXTURE_2D);

            while (win.IsOpen)
            {
                Event sfml_event = new SFML.Window.Event();

                if (sfml_event.Type != EventType.Closed)
                    win.Close();

                float Time = sw.ElapsedMilliseconds/10;
                float size = 20.0f;

                win.PushGLStates();
                win.Draw(background);               
                win.PopGLStates();

                glClear(GL_DEPTH_BUFFER_BIT);
                glClearDepth(2.0f);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                glTranslatef(0, 0, -100);
                glRotatef(Time, 50, 50, 0);
                glFrontFace(GL_CW);
                //glEnable(GL_CULL_FACE);
                glCullFace(GL_BACK);
                glFrontFace(GL_CW);

                glBindTexture(GL_TEXTURE_2D, Box[0]);
                glBegin(GL_QUADS);
                //back
                glTexCoord2f(0, 0); glVertex3f(size, -size, -size);
                glTexCoord2f(1, 0); glVertex3f(-size, -size, -size);
                glTexCoord2f(1, 1); glVertex3f(-size, size, -size);
                glTexCoord2f(0, 1); glVertex3f(size, size, -size);
                glEnd();

                glBindTexture(GL_TEXTURE_2D, Box[1]);
                glBegin(GL_QUADS);
                //front
                glTexCoord2f(0, 0); glVertex3f(size, size, size);
                glTexCoord2f(1, 0); glVertex3f(-size, size, size);
                glTexCoord2f(1, 1); glVertex3f(-size, -size, size);
                glTexCoord2f(0, 1); glVertex3f(size, -size, size);
                glEnd();

                glBindTexture(GL_TEXTURE_2D, Box[2]);
                glBegin(GL_QUADS);
                //left               
                glTexCoord2f(0, 0); glVertex3f(-size, size, size);
                glTexCoord2f(1, 0); glVertex3f(-size, size, -size);
                glTexCoord2f(1, 1); glVertex3f(-size, -size, -size);
                glTexCoord2f(0, 1); glVertex3f(-size, -size, size);

                glBindTexture(GL_TEXTURE_2D, Box[3]);
                glBegin(GL_QUADS);
                //right
                glTexCoord2f(0, 0); glVertex3f(size, size, -size);
                glTexCoord2f(1, 0); glVertex3f(size, size, size);
                glTexCoord2f(1, 1); glVertex3f(size, -size, size);
                glTexCoord2f(0, 1); glVertex3f(size, -size, -size);
                glEnd();

                glBindTexture(GL_TEXTURE_2D, Box[4]);
                glBegin(GL_QUADS);
                //bottom
                glTexCoord2f(0, 0); glVertex3f(-size, -size, size);
                glTexCoord2f(1, 0); glVertex3f(size, -size, size);
                glTexCoord2f(1, 1); glVertex3f(size, -size, -size);
                glTexCoord2f(0, 1); glVertex3f(-size, -size, -size);
                glEnd();

                glBindTexture(GL_TEXTURE_2D, Box[5]);
                glBegin(GL_QUADS);
                //top
                glTexCoord2f(0, 0); glVertex3f(size, size, -size);
                glTexCoord2f(1, 0); glVertex3f(-size, size, -size);
                glTexCoord2f(1, 1); glVertex3f(-size, size, size);
                glTexCoord2f(0, 1); glVertex3f(size, size, size);
                glEnd();

                glFlush();

                win.Display();
            }

            //glDeleteTextures(1, GetPixelsPtr(image.Pixels));

        }


        public static IntPtr GetPixelsPtr(byte[] pixel)
        {
            GCHandle pinnedArray = GCHandle.Alloc(pixel, GCHandleType.Pinned);
            IntPtr pointer = pinnedArray.AddrOfPinnedObject();
            // Do your stuff...
            pinnedArray.Free();
            return pointer;
        }

    }
}

没有深度测试时,立方体看起来像这样。尽管启用了深度测试但没有进行深度测试的原因是默认情况下 SFML RenderWindow 不分配深度缓冲区。如果你需要一个,你必须传递一个 ContextSetting 实例并将 DepthBits 设置为非零值。

ContextSettings contextSettings = new ContextSettings();
contextSettings.DepthBits = 24;

RenderWindow win = new RenderWindow(new VideoMode(800, 600), "BlockWorld", contextSettings);