C# SFML OpenGL 多重纹理问题
编辑:好的,这段代码仍然不允许我在程序中使用两种不同的纹理。它的行为就像它应该工作一样,但是当我告诉它使用第一个纹理时,它与第二个纹理相同,这是最后加载的纹理。
private int[] iTextures = new int[3];
public void main()
{
Initialize();
LoadContent();
float Time = 0.0F;
// Start game loop
while (App.IsOpened())
{
// Process events
App.DispatchEvents();
// Clear the window
App.Clear();
App.Draw(Background);
Gl.glClear(Gl.GL_DEPTH_BUFFER_BIT);
// Transformations
Time += App.GetFrameTime();
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Gl.glTranslatef(0.0F, 0.0F, -200.0F);
Gl.glPushMatrix();
Gl.glScalef(10.0f, 50.0f, 10.0f);
DrawCube(50.0f, 50.0f, 50.0f, 0);
Gl.glPopMatrix();
//Gl.glRotatef(Time * 50, 1.0F, 0.0F, 0.0F);
//Gl.glRotatef(Time * 30, 0.0F, 1.0F, 0.0F);
//Gl.glRotatef(Time * 90, 0.0F, 0.0F, 1.0F);
/*Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(-50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F);
Gl.glVertex3f(50.0f, 50.0f, 50.0f);
Gl.glVertex3f(50.0f, 0.0f, 50.0f);
Gl.glVertex3f(0.0f, 0.0f, 50.0f);
Gl.glVertex3f(0.0f, 50.0f, 50.0f);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 10.0F, 50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, 10.0F, -50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, 10.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 10.0F, 50.0F);
Gl.glEnd();*/
Draw();
// Finally, display the rendered frame on screen
App.Display();
}
// Don't forget to destroy our texture
int tex = 0;
Gl.glDeleteTextures(1, ref tex);
}
public void Initialize()
{
// Create main window
App.PreserveOpenGLStates(true);
// Setup event handlers
App.Closed += new EventHandler(OnClosed);
App.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed);
App.Resized += new EventHandler<SizeEventArgs>(OnResized);
}
private void LoadContent()
{
BackgroundImage = new Image("background.jpg");
Background = new Sprite(BackgroundImage);
Text = new String2D("This is a cube");
Text.Position = new Vector2(0, 0);
Text.Color = Color.Black;
// Enable Z-buffer read and write
Gl.glEnable(Gl.GL_DEPTH_TEST);
Gl.glDepthMask(Gl.GL_TRUE);
Gl.glClearDepth(1.0F);
// Setup a perspective projection
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluPerspective(90.0F, 1.0F, 1.0F, 500.0F); // I assume this is setting up the camera
LoadTexture(new Image("texture.jpg"), 0);
LoadTexture(new Image("Otexture.jpg"), 1);
}
private void Draw()
{
App.Draw(Text);
}
private void LoadTexture(Image Texture, int texNum)
{
using (Image TempImage = Texture)
{
Gl.glGenTextures(1, out iTextures[texNum]); // Texture name, which is a number
Gl.glBindTexture(Gl.GL_TEXTURE_2D, iTextures[texNum]); // Start using the texture
Console.WriteLine(texNum + "");
// Texture options and filters and stuff
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
Glu.gluBuild2DMipmaps(Gl.GL_TEXTURE_2D, Gl.GL_RGBA, (int)TempImage.Width, (int)TempImage.Height, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, TempImage.Pixels);
//Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, (int)TempImage.Width, (int)TempImage.Height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, TempImage.Pixels);
}
Gl.glEnable(Gl.GL_TEXTURE_2D);
}
private void UseTexture(int iTexture)
{
// Bind our texture for use
//Gl.glEnable(Gl.GL_TEXTURE_2D); // Start using the 2D texture
Gl.glBindTexture(Gl.GL_TEXTURE_2D, iTexture); // Bind our texture for current use
Gl.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); // Set color to..white, I think.
}
void DrawCube(float xPos, float yPos, float zPos, int texture)
{
Gl.glPushMatrix();
//UseTexture(1);
Gl.glBegin(Gl.GL_QUADS);
UseTexture(iTextures[0]);
//Gl.glEnable(Gl.GL_TEXTURE_2D);
/* This is the top face*/
Gl.glVertex3f(0.0f, 0.0f, 0.0f);
Gl.glVertex3f(0.0f, 0.0f, -1.0f);
Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
Gl.glVertex3f(-1.0f, 0.0f, 0.0f);
/* This is the front face*/
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(0.0f, 0.0f, 0.0f);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-1.0f, 0.0f, 0.0f);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(-1.0f, -1.0f, 0.0f);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(0.0f, -1.0f, 0.0f);
/* This is the right face*/
Gl.glVertex3f(0.0f, 0.0f, 0.0f);
Gl.glVertex3f(0.0f, -1.0f, 0.0f);
Gl.glVertex3f(0.0f, -1.0f, -1.0f);
Gl.glVertex3f(0.0f, 0.0f, -1.0f);
/* This is the left face*/
Gl.glVertex3f(-1.0f, 0.0f, 0.0f);
Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
Gl.glVertex3f(-1.0f, -1.0f, 0.0f);
/* This is the bottom face*/
Gl.glVertex3f(0.0f, 0.0f, 0.0f);
Gl.glVertex3f(0.0f, -1.0f, -1.0f);
Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
Gl.glVertex3f(-1.0f, -1.0f, 0.0f);
/* This is the back face*/
Gl.glVertex3f(0.0f, 0.0f, 0.0f);
Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
Gl.glVertex3f(0.0f, -1.0f, -1.0f);
Gl.glEnd();
Gl.glPopMatrix();
}
任何帮助都会很棒。
Edit: Okay, this code still doesn't allow me to use two different textures in the program. It acts like it should work, but when I tell it to use the first texture, it's the same as the second texture, which is the last texture that's loaded.
private int[] iTextures = new int[3];
public void main()
{
Initialize();
LoadContent();
float Time = 0.0F;
// Start game loop
while (App.IsOpened())
{
// Process events
App.DispatchEvents();
// Clear the window
App.Clear();
App.Draw(Background);
Gl.glClear(Gl.GL_DEPTH_BUFFER_BIT);
// Transformations
Time += App.GetFrameTime();
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Gl.glTranslatef(0.0F, 0.0F, -200.0F);
Gl.glPushMatrix();
Gl.glScalef(10.0f, 50.0f, 10.0f);
DrawCube(50.0f, 50.0f, 50.0f, 0);
Gl.glPopMatrix();
//Gl.glRotatef(Time * 50, 1.0F, 0.0F, 0.0F);
//Gl.glRotatef(Time * 30, 0.0F, 1.0F, 0.0F);
//Gl.glRotatef(Time * 90, 0.0F, 0.0F, 1.0F);
/*Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(-50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, -50.0F, 50.0F);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, 50.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F);
Gl.glVertex3f(50.0f, 50.0f, 50.0f);
Gl.glVertex3f(50.0f, 0.0f, 50.0f);
Gl.glVertex3f(0.0f, 0.0f, 50.0f);
Gl.glVertex3f(0.0f, 50.0f, 50.0f);
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 10.0F, 50.0F);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, 10.0F, -50.0F);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, 10.0F, -50.0F);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 10.0F, 50.0F);
Gl.glEnd();*/
Draw();
// Finally, display the rendered frame on screen
App.Display();
}
// Don't forget to destroy our texture
int tex = 0;
Gl.glDeleteTextures(1, ref tex);
}
public void Initialize()
{
// Create main window
App.PreserveOpenGLStates(true);
// Setup event handlers
App.Closed += new EventHandler(OnClosed);
App.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed);
App.Resized += new EventHandler<SizeEventArgs>(OnResized);
}
private void LoadContent()
{
BackgroundImage = new Image("background.jpg");
Background = new Sprite(BackgroundImage);
Text = new String2D("This is a cube");
Text.Position = new Vector2(0, 0);
Text.Color = Color.Black;
// Enable Z-buffer read and write
Gl.glEnable(Gl.GL_DEPTH_TEST);
Gl.glDepthMask(Gl.GL_TRUE);
Gl.glClearDepth(1.0F);
// Setup a perspective projection
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluPerspective(90.0F, 1.0F, 1.0F, 500.0F); // I assume this is setting up the camera
LoadTexture(new Image("texture.jpg"), 0);
LoadTexture(new Image("Otexture.jpg"), 1);
}
private void Draw()
{
App.Draw(Text);
}
private void LoadTexture(Image Texture, int texNum)
{
using (Image TempImage = Texture)
{
Gl.glGenTextures(1, out iTextures[texNum]); // Texture name, which is a number
Gl.glBindTexture(Gl.GL_TEXTURE_2D, iTextures[texNum]); // Start using the texture
Console.WriteLine(texNum + "");
// Texture options and filters and stuff
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
Glu.gluBuild2DMipmaps(Gl.GL_TEXTURE_2D, Gl.GL_RGBA, (int)TempImage.Width, (int)TempImage.Height, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, TempImage.Pixels);
//Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, (int)TempImage.Width, (int)TempImage.Height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, TempImage.Pixels);
}
Gl.glEnable(Gl.GL_TEXTURE_2D);
}
private void UseTexture(int iTexture)
{
// Bind our texture for use
//Gl.glEnable(Gl.GL_TEXTURE_2D); // Start using the 2D texture
Gl.glBindTexture(Gl.GL_TEXTURE_2D, iTexture); // Bind our texture for current use
Gl.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); // Set color to..white, I think.
}
void DrawCube(float xPos, float yPos, float zPos, int texture)
{
Gl.glPushMatrix();
//UseTexture(1);
Gl.glBegin(Gl.GL_QUADS);
UseTexture(iTextures[0]);
//Gl.glEnable(Gl.GL_TEXTURE_2D);
/* This is the top face*/
Gl.glVertex3f(0.0f, 0.0f, 0.0f);
Gl.glVertex3f(0.0f, 0.0f, -1.0f);
Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
Gl.glVertex3f(-1.0f, 0.0f, 0.0f);
/* This is the front face*/
Gl.glTexCoord2f(0, 1); Gl.glVertex3f(0.0f, 0.0f, 0.0f);
Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-1.0f, 0.0f, 0.0f);
Gl.glTexCoord2f(1, 0); Gl.glVertex3f(-1.0f, -1.0f, 0.0f);
Gl.glTexCoord2f(1, 1); Gl.glVertex3f(0.0f, -1.0f, 0.0f);
/* This is the right face*/
Gl.glVertex3f(0.0f, 0.0f, 0.0f);
Gl.glVertex3f(0.0f, -1.0f, 0.0f);
Gl.glVertex3f(0.0f, -1.0f, -1.0f);
Gl.glVertex3f(0.0f, 0.0f, -1.0f);
/* This is the left face*/
Gl.glVertex3f(-1.0f, 0.0f, 0.0f);
Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
Gl.glVertex3f(-1.0f, -1.0f, 0.0f);
/* This is the bottom face*/
Gl.glVertex3f(0.0f, 0.0f, 0.0f);
Gl.glVertex3f(0.0f, -1.0f, -1.0f);
Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
Gl.glVertex3f(-1.0f, -1.0f, 0.0f);
/* This is the back face*/
Gl.glVertex3f(0.0f, 0.0f, 0.0f);
Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
Gl.glVertex3f(0.0f, -1.0f, -1.0f);
Gl.glEnd();
Gl.glPopMatrix();
}
Any help would be awesome.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你不是在谈论多重纹理;而是在谈论多重纹理。您正在谈论在同一应用程序中使用多个纹理。
嗯,我看到了几个问题。
我承认我并不是 100% 熟悉 C# 的语法,因此我假设
out
的工作原理与 C/C++ 中传递指针类似。因此,您希望glGenTextures
将纹理对象编号写入iTexture
。这里有两个问题。首先,
iTexture
是一个整数。但是您告诉glGenTextures
您在此函数调用中生成了两个 纹理,而不是一个。这需要传递一个整数数组供glGenTextures
写入。所以你冒着毁掉……堆栈的风险?我不知道您如何将这些调用编组到 C++,但无论您如何执行,glGenTextures
都可能会写入随机内存。你很幸运没有发生车祸。每次调用
LoadTexture
都应该创建一个 OpenGL 纹理对象。因此,您不应尝试通过单个LoadTexture
调用创建两个纹理。另一个问题是
iTexture
没有从LoadTexture
函数返回。你不把它存储在任何地方。事实上,当您调用LoadTexture
时,您甚至没有给它一个输出变量;而是给它一个输出变量。你给它一个数字文字。再说一次,我不是 C# 专家,但我很确定您需要一些特殊的语法来使用参数作为函数输出,特别是对于像int
这样的基本类型。您的 LoadTexture 函数应返回 OpenGL 纹理名称(或将它们存储在某处),并且匹配的 UseTexture 调用应从中获取这些特定名称。
新的代码问题:
您无法删除纹理 0。这就是为什么人们通常不使用纹理 0 来存储实际纹理的原因;它通常被视为“不存在的纹理”,如 NULL。
至于您的实际绘图代码:
您无法在
glBegin
/glEnd
调用之间调用glBindTexture
(或大多数 OpenGL 函数)。UseTexture
应在开始四边形之前调用。此外,UseTexture
应启用GL_TEXTURE_2D
。我知道您在其他地方使用它,但最好将命令放在真正重要的地方。如果你想进行无纹理渲染,你必须禁用GL_TEXTURE_2D
。另外,当您只给出一个四边形纹理坐标时,您期望发生什么?您期望其他四边形是什么样子?因为如果您认为这些四边形将是无纹理的,那您就错了。
You're not talking about multitexturing; you're talking about using multiple textures in the same application.
Well, I see several problems.
I admit that I'm not 100% familiar with C#'s syntax, so I'm assuming that the
out
works rather like passing a pointer in C/C++. So you expectglGenTextures
to write the texture object number toiTexture
.There are two problems here. First,
iTexture
is a single integer. But you toldglGenTextures
that you were generating two textures in this function call, not one. That would require passing an array of integers forglGenTextures
to write into. So you're risking trashing the... stack? I have no idea how you're marshalling these calls to C++, but however you're doing it,glGenTextures
is likely writing over random memory. You were lucky not to get a crash.Each call to
LoadTexture
is supposed to create a single OpenGL texture object. Therefore, you should not be trying to create two from a singleLoadTexture
call.The other problem is that
iTexture
is not returned from yourLoadTexture
function. You don't store it anywhere. Indeed, when you callLoadTexture
, you don't even give it an output variable; you give it a number literal. Again, I'm not a C# expert, but I'm pretty sure you would need some special syntax to use an argument as a function output, particularly for a basic type likeint
.Your
LoadTexture
function should return the OpenGL texture names (or store them somewhere), and the matchingUseTexture
calls should get those particular names from them.New code problems:
You cannot delete texture 0. That's generally why people don't use texture 0 to store actual textures in; it is generally treated as a "texture that doesn't exist", like NULL.
As to your actual drawing code:
You cannot call
glBindTexture
(or most OpenGL functions) betweenglBegin
/glEnd
calls.UseTexture
should be called before beginning the quad. Also,UseTexture
should enableGL_TEXTURE_2D
. I know you use it elsewhere, but it's best to put commands where they actually matter. And you have to disableGL_TEXTURE_2D
if you want to do untextured rendering.Also, what do you expect to happen when you only give one quad texture coordinates? What do you expect the other quads to look like? Because if you think that those quads will be untextures, you're wrong.