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);
我在业余时间教授 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);