opentk несколько текстур на кубе не работают
Так что в моей программе есть функция для рисования куба. Я использую C# с Monodevelop на Linux. Вот функция:
private int DrawCube(float x, float y, float z, float ori, int SideTexture, int TopTexture, int BottomTexture)
{
GL.PushMatrix();
GL.Translate(x, y, z);
GL.Rotate(ori, 0, 1, 0);
GL.BindTexture(TextureTarget.Texture2D, SideTexture);
GL.Begin(BeginMode.Quads);
GL.Color3(Color.White);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
//Top
//GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, TopTexture);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
//Bottom
GL.BindTexture(TextureTarget.Texture2D, BottomTexture);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, 0);
GL.BindTexture(TextureTarget.Texture2D, SideTexture);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 20, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 20, 0);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
GL.End();
GL.PopMatrix();
return 6; // Return number of faces drawn
}
Как вы уже догадались, эта функция рисует куб с положением x, y, z
, направление ori
и SideTexture по бокам, а также TopTexture и BottomTexture сверху и снизу. Теперь проблема в том, что он рисует куб только с одной текстурой! боковая текстура. Я не знаю в чем проблема. Должен ли я открепить текстуры? все остальное в коде работает отлично, как я уже говорил, что это связано с текстурами. Любая помощь приветствуется.
2 ответа
Вы не можете позвонить GL.BindTexture()
в пределах начальной области. Из документации:
Между glBegin и glEnd можно использовать только подмножество команд GL. Это команды glVertex, glColor, glSecondaryColor, glIndex, glNormal, glFogCoord, glTexCoord, glMultiTexCoord, glVertexAttrib, glEvalCoord, glEvalPoint, glArrayElement, glMaterial и glEdgeFlag. Также допустимо использовать glCallList или glCallLists для выполнения списков отображения, которые включают только предыдущие команды. Если между glBegin и glEnd выполняется какая-либо другая команда GL, устанавливается флаг ошибки, и команда игнорируется.
Если вы проверите GL.GetError()
вы увидите, что вы получаете ошибку InvalidOperation. по факту GL.GetError()
должна быть вашей первой реакцией, когда что-то не рендерится, как ожидается в OpenGL
Решение:
private int DrawCube(float x, float y, float z, float ori, int SideTexture, int TopTexture, int BottomTexture)
{
GL.PushMatrix();
GL.Translate(x, y, z);
GL.Rotate(ori, 0, 1, 0);
GL.BindTexture(TextureTarget.Texture2D, SideTexture);
GL.Begin(BeginMode.Quads);
GL.Color3(Color.White);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
GL.End();
//Top
GL.BindTexture(TextureTarget.Texture2D, TopTexture);
GL.Begin(BeginMode.Quads);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
GL.End();
//Bottom
GL.BindTexture(TextureTarget.Texture2D, BottomTexture);
GL.Begin(BeginMode.Quads);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, 0);
GL.End();
GL.BindTexture(TextureTarget.Texture2D, SideTexture);
GL.Begin(BeginMode.Quads);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 20, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 20, 0);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
GL.End();
GL.PopMatrix();
return 6; // Return number of faces drawn
}
О да, и для тех, кому это может быть полезно, я использовал неправильные стороны с текстурами. Текстура top была прикреплена к нижней части и т. Д. Вот рабочий код. Код для загрузки текстуры из пути:
static public int UploadTexture(string pathname)
{
// Create a new OpenGL texture object
int id = GL.GenTexture();
// Select the new texture
GL.BindTexture(TextureTarget.Texture2D, id);
// Load the image
Bitmap bmp = new Bitmap(pathname);
// Lock image data to allow direct access
BitmapData bmp_data = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// Import the image data into the OpenGL texture
GL.TexImage2D(TextureTarget.Texture2D,
0,
PixelInternalFormat.Rgba,
bmp_data.Width,
bmp_data.Height,
0,
OpenTK.Graphics.OpenGL.PixelFormat.Bgra,
OpenTK.Graphics.OpenGL.PixelType.UnsignedByte,
bmp_data.Scan0);
// Unlock the image data
bmp.UnlockBits(bmp_data);
// Configure minification and magnification filters
GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureMinFilter,
(int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureMagFilter,
(int)TextureMagFilter.Linear);
// Return the OpenGL object ID for use
return id;
}
и код для рисования куба с текстурами
private int DrawCube(float x, float y, float z, float ori, int TopTexture, int BottomTexture, params int[] SideTextures)
{
GL.PushMatrix();
GL.Translate(x, y, z);
GL.Rotate(ori, 0, 1, 0);
GL.BindTexture(TextureTarget.Texture2D, SideTextures[0]);
GL.Begin(BeginMode.Quads);
GL.Color3(Color.White);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
GL.End();
//Top
GL.BindTexture(TextureTarget.Texture2D, SideTextures[1]);
GL.Begin(BeginMode.Quads);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, 0);
GL.End();
//Bottom
GL.BindTexture(TextureTarget.Texture2D, BottomTexture);
GL.Begin(BeginMode.Quads);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 0, 0);
GL.End();
GL.BindTexture(TextureTarget.Texture2D, SideTextures[2]);
GL.Begin(BeginMode.Quads);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, 0);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, 0);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
GL.End();
GL.BindTexture(TextureTarget.Texture2D, TopTexture);
GL.Begin(BeginMode.Quads);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(0, 20, 0);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(20, 20, 0);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
GL.End();
GL.BindTexture(TextureTarget.Texture2D, SideTextures[3]);
GL.Begin(BeginMode.Quads);
GL.TexCoord2(0.0f, 1.0f - 0.0f); GL.Vertex3(20, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 0.0f); GL.Vertex3(0, 0, -20);
GL.TexCoord2(1.0f, 1.0f - 1.0f); GL.Vertex3(0, 20, -20);
GL.TexCoord2(0.0f, 1.0f - 1.0f); GL.Vertex3(20, 20, -20);
GL.End();
GL.PopMatrix();
return 6; // Return number of faces drawn
}
protected override void OnResize(EventArgs e)
{
int w = Width;
int h = Height;
float aspect = 1;
// Calculate aspect ratio, checking for divide by zero
if (h > 0)
{
aspect = (float)w / (float)h;
}
// Initialise the projection view matrix
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
// Setup a perspective view
float FOVradians = MathHelper.DegreesToRadians(45);
Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(FOVradians, aspect, 1, 4000);
GL.MultMatrix(ref perspective);
// Set the viewport to the whole window
GL.Viewport(0, 0, w, h);
}
и ссылки, которые вы должны будете использовать:
using System;
using System.Drawing;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;
РЕДАКТИРОВАТЬ: В более новой версии OpenTK я считаю, что вам придется использовать PrimitiveType.Quad вместо BeginMode.Quad