这是我的代码:
sigTex = new Texture2D ((int)dims.x, (int)dims.y);
sigTex.ReadPixels (new Rect (new Vector2(0.0f, Screen.height - bot) , dims), 0, 0);
byte[] pngBytes = sigTex.EncodeToPNG ();
System.IO.BinaryWriter bw= new System.IO.BinaryWriter(new System.IO.FileStream(filename, System.IO.FileMode.Create));
bw.Write (pngBytes, 0, pngBytes.Length);
bw.Close ();
Run Code Online (Sandbox Code Playgroud)
问题是,在这段代码之后,当我尝试在 GUI 中使用它或在检查器中查看它时,我留下了一个空白纹理,它是统一的灰色。奇怪的是,生成的文件是正确的。
我发现还有相当数量的驱动程序不支持NPOT纹理所以我试图改造我的2D引擎(基于OpenTK,而后者又基于OpenGL),而不是支持Texture2D依赖于GL_ARB_texture_rectangle.作为其中的一部分,我强制所有NPOTS纹理位图分配额外的空间,直到下一个2的幂大小,这样它们就不会在这些驱动程序上造成错误.我的问题是,我是否真的需要调整实际位图和纹理的大小并分配所有额外的内存,或者是否有办法告诉OpenGL我想要2次幂大小的纹理,但我只会使用左上角的一部分?
现在我的电话看起来像这样:
GL.TexImage2D(texTarget, 0, PixelInternalFormat.Rgba8, bmpUse.Width, bmpUse.Height, 0, PixelFormat.Bgra, PixelType.UnsignedByte, bits.Scan0);
Run Code Online (Sandbox Code Playgroud)
这是在我使bmpUse成为我的真实纹理位图的副本后,在右侧和底部有额外的空间.
我目前正在与一块软件一起工作,该软件通过拍摄几张图像然后将它们拼接成游戏地图来生成游戏地图.现在我正在使用OpenGL来绘制这些地图.如您所知,在OpenGL中切换状态并进行多次绘制调用的成本很高.我决定实现一个纹理图集系统,它允许我在没有状态切换的单个绘图调用中绘制整个地图.但是,我在实现纹理图集方面遇到了问题.首先,将每个TILE存储在纹理图集或图像本身中会更好吗?其次,并非所有图像都保证是方形的,甚至是2的幂.我是否将它们填充到最接近的2,正方形或两者的功率?我担心的另一件事是图像可能变得非常大,我担心超出纹理的OpenGL大小限制,这会迫使我分割地图,破坏整个概念.
到目前为止,这是我的概念:
- 生成纹理
- 绑定纹理
- 生成足够大的图像来保存纹理(考虑填充?)
- 纹理?
-Upload subtexture为空白纹理,存储偏移量
- 取消纹理
我正在制作一个测试 xna 游戏作为学习练习,我有一个关于使用 2d 纹理的小问题。基本上,游戏是从文本地图文件中获取的不同“图块”的网格。我基本上只是在初始化关卡时解析文件并创建不同图块类型的矩阵。该关卡本质上是一桶墙砖和钉子。所以本质上,有很多墙砖和多个尖钉砖,然后还有很多空砖。然而,有四种类型的墙砖和钉状纹理来覆盖不同的方向。
我的问题是加载每个图块纹理的最佳方法是什么?我是否为每个图块加载单独的纹理?即当我创建一个图块时,向它传递一个texture2d,我可以同时绘制和加载纹理。这似乎是一个好方法,但是我必须单独加载每个图块纹理,这似乎很浪费。
我能想到的另一个选择是在图块结构中使用静态纹理,然后简单地将此纹理加载为具有不同墙壁和尖峰的图块图集。这样我只加载单个纹理,然后在绘制时我只需将一个矩形移动到精灵内适当图块的区域。
我不确定从性能角度来看,这些方法中哪一种是最佳的,或者是否有其他方法?
提前致谢
我一直在尝试将一些旧的 OpenGL 代码转换为使用着色器,但在让片段着色器在立方体上绘制纹理时遇到了问题。然而,我看到的只是一个灰色的立方体。我已经调试了我的 .obj 加载器代码,并且我知道 UV 正在正确加载,并且我知道纹理正在从磁盘加载并正确放置在 GPU 上。经过大量测试后,我发现我的 UV 值没有在每个三角形的面上进行插值。也就是说,看起来每个片段的 uv 值都为 0.0,0.0(这是我缓冲区中的第一个 uv 值)知道为什么吗?
这是我的片段着色器:
#version 430 core
in vec3 color;
in vec2 uv;
uniform sampler2D tex;
out vec3 frag_color;
void main()
{
//frag_color = color;
frag_color = texture(tex,uv).rgb;
}
Run Code Online (Sandbox Code Playgroud)
还有我的顶点着色器:
#version 430 core
layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 uv;
uniform mat4 mvMatrix;
uniform mat4 mvpMatrix;
attribute vec3 lightPos;
out vec3 color;
out vec2 uv_out;
void …Run Code Online (Sandbox Code Playgroud) 我正在使用 2D 纹理数组来存储一些数据。由于我经常想要绑定这个 2D 纹理数组的单层,因此我为每个层创建单独的GL_TEXTURE_2D纹理视图:
for(int l(0); l < m_layers; l++)
{
QOpenGLTexture * view_texture = m_texture.createTextureView(QOpenGLTexture::Target::Target2D,
m_texture_format,
0,0,
l,l);
view_texture->setMinMagFilters(QOpenGLTexture::Filter::Linear, QOpenGLTexture::Filter::Linear);
view_texture->setWrapMode(QOpenGLTexture::WrapMode::MirroredRepeat);
assert(view_texture != 0);
m_texture_views.push_back(view_texture);
}
Run Code Online (Sandbox Code Playgroud)
这些 2D 纹理视图工作得很好。但是,如果我想使用该纹理视图从 GPU 端检索 2D 纹理数据,则它不起作用。
换句话说,以下代码不复制任何数据(但不会引发 GL 错误):
glGetTexImage(GL_TEXTURE_2D, 0, m_pixel_format, m_pixel_type, (GLvoid*) m_raw_data[layer] )
Run Code Online (Sandbox Code Playgroud)
但是,检索整个GL_TEXTURE_2D_ARRAY确实有效:
glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, m_pixel_format, m_pixel_type, (GLvoid*) data );
Run Code Online (Sandbox Code Playgroud)
当仅修改单个层的数据时,如果我需要在 2D 纹理数组的所有层之间进行复制,显然会造成性能损失。
有没有办法将 GPU->CPU 仅复制GL_TEXTURE_2D_ARRAY的单层?我知道有相反的情况(即CPU->GPU),所以如果没有的话我会感到惊讶。