所以在我的程序中有一个绘制立方体的功能。我在linux上使用c#和monodevelop。这是功能:
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。
现在的问题是它只用一个纹理绘制立方体!侧面纹理。
我不知道是什么问题。我必须解开纹理吗?
代码中的其他一切工作正常,就像我说已经有纹理的麻烦。任何帮助表示赞赏。
答案 0 :(得分:3)
您无法在开始端区域内呼叫GL.BindTexture()
。 From the documentation:
只能在glBegin和glEnd之间使用GL命令的子集。 命令是glVertex,glColor,glSecondaryColor,glIndex, glNormal,glFogCoord,glTexCoord,glMultiTexCoord,glVertexAttrib, glEvalCoord,glEvalPoint,glArrayElement,glMaterial和glEdgeFlag。 此外,可以使用glCallList或glCallLists来执行 显示仅包含上述命令的列表。 如果有的话 GL命令在glBegin和glEnd之间执行,错误标志是 设置并忽略该命令。
如果您选中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
}
答案 1 :(得分:1)
哦,是的,对于那些可能有用的人我实际上使用了纹理的错误边。 topTexture真的附在底部,e.t.c。这是工作代码。 从路径上传纹理的代码:
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