我想将矩形地球纹理映射到球体上。我可以加载“globe.jpg”纹理并将其显示在屏幕上。我想我需要在特定的纹理坐标处检索“globe.jpg”纹理的颜色,并使用它来着色地球上的特定点。
我想将右侧的地球地图映射到左侧的一个球体上(见图)
加载纹理代码:
int texture;
public Texture() {
texture = LoadTexture("Content/globe.jpg");
}
public int LoadTexture(string file) {
Bitmap bitmap = new Bitmap(file);
int tex;
GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
GL.GenTextures(1, out tex);
GL.BindTexture(TextureTarget.Texture2D, tex);
BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
bitmap.UnlockBits(data);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
//GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
//GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
return tex;
}
我还创建了一些代码,用于将球体上的点映射到我认为的纹理上的点上的点(使用https://www.cs.unc.edu/~rademach/xroads-RT/RTarticle.html上纹理映射球体部分中的代码)。
point
是光线与球体相交的Vector3
:
vn = new Vector3(0f, 1f, 0f); //should be north pole of sphere, but it isn't based on sphere's position, so I think it's incorrect
ve = new Vector3(1f, 0f, 0f); // should be a point on the equator
float phi = (float) Math.Acos(-1 * Vector3.Dot(vn, point));
float theta = (float) (Math.Acos(Vector3.Dot(point, ve) / Math.Sin(phi))) / (2 * (float) Math.PI);
float v = phi / (float) Math.PI;
float u = Vector3.Dot(Vector3.Cross(vn, ve), point) > 0 ? theta : 1 - theta;
我认为我现在可以在我加载的纹理上使用这个u和v坐标来找到那里的纹理颜色。但我不知道怎么做。我也认为北极和赤道矢量不正确。
答案 0 :(得分:2)
我不知道4个月后您是否仍然需要答案,但是:
如果您具有正确的uv信息(例如,使用Blender创建的obj文件)和正确的球体模型,则只需导入该模型(使用assimp或任何其他导入器)并在渲染过程中应用纹理即可。
您的问题有点含糊,因为我不知道您是否使用着色器。
我的方法是:
1:使用assimp库或任何其他导入库导入模型
2:实现顶点和片段着色器,并在片段着色器中包含用于纹理的sampler2D制服
3:在渲染过程中,选择着色器程序ID [GL.UseProgram(...)],然后将顶点,纹理uv和纹理像素(作为统一信息)上载到着色器。
4:使用像这样的标准顶点着色器:
#version 330
in vec3 aPosition;
in vec2 aTexture;
out vec2 vTexture;
uniform mat4 uModelViewProjectionMatrix;
void main()
{
vTexture = aTexture;
gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0);
}
5:使用像这样的标准片段着色器:
#version 330
in vec2 vTexture;
uniform sampler2D uTexture;
out vec4 fragcolor;
void main()
{
fragcolor = texture(uTexture, vTexture);
}
如果您需要有效的obj文件用于具有矩形uv映射的球体,请放下一行(或两行)。