C# SFML OpenGl Multiple Texture problem
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);
开发者_StackOverflow中文版 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.
You're not talking about multitexturing; you're talking about using multiple textures in the same application.
Well, I see several problems.
Gl.glGenTextures(2, out iTexture); // Texture name, which is a number
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 expect glGenTextures
to write the texture object number to iTexture
.
There are two problems here. First, iTexture
is a single integer. But you told glGenTextures
that you were generating two textures in this function call, not one. That would require passing an array of integers for glGenTextures
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 single LoadTexture
call.
The other problem is that iTexture
is not returned from your LoadTexture
function. You don't store it anywhere. Indeed, when you call LoadTexture
, 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 like int
.
Your LoadTexture
function should return the OpenGL texture names (or store them somewhere), and the matching UseTexture
calls should get those particular names from them.
New code problems:
// Don't forget to destroy our texture
int tex = 0;
Gl.glDeleteTextures(1, ref tex);
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:
Gl.glBegin(Gl.GL_QUADS);
UseTexture(iTextures[0]);
You cannot call glBindTexture
(or most OpenGL functions) between glBegin
/glEnd
calls. UseTexture
should be called before beginning the quad. Also, UseTexture
should enable GL_TEXTURE_2D
. I know you use it elsewhere, but it's best to put commands where they actually matter. And you have to disable GL_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.
精彩评论