标签: texturing

OpenGL将纹理映射到球体

我有OpenGL程序,我想用地球的位图纹理球体.我在Blender中准备了网格并将其导出到OBJ文件中.程序正确加载适当的网格数据(顶点,uv和法线)和位图 - 我已经使用骨位图检查了纹理立方体.

我的程序是纹理球体,但不正确(或以我不指望的方式).此球体的每个三角形都包含此位图的变形副本.我检查了位图,uv似乎没问题.我尝试了很多尺寸的位图(2的幂,2的倍数等).

这是纹理:

地球纹理

我的程序的屏幕截图(就像它会忽略我的UV坐标):

在此输入图像描述

Blender中UV的映射我用这种方式完成:

在此输入图像描述

加载后的代码设置纹理(除了代码将纹理添加到VBO-我认为没关系):

  GLuint texID;
  glGenTextures(1,&texID);
  glBindTexture(GL_TEXTURE_2D,texID);
  glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0,GL_BGR,GL_UNSIGNED_BYTE,(GLvoid*)&data[0]);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
Run Code Online (Sandbox Code Playgroud)

是否需要任何额外的代码才能正确映射此纹理?

[编辑]初始化纹理(之前提供的代码在LoadTextureBMP_custom()函数中)

bool Program::InitTextures(string texturePath)
{
  textureID = LoadTextureBMP_custom(texturePath);
  GLuint TBO_ID;
  glGenBuffers(1,&TBO_ID);
  glBindBuffer(GL_ARRAY_BUFFER,TBO_ID);
  glBufferData(GL_ARRAY_BUFFER,uv.size()*sizeof(vec2),&uv[0],GL_STATIC_DRAW);
  return true;
}
Run Code Online (Sandbox Code Playgroud)

我的主循环:

bool Program::MainLoop()
{
  bool done = false;
  mat4 projectionMatrix;
  mat4 viewMatrix;
  mat4 modelMatrix;
  mat4 MVP;

  Camera camera;
  shader.SetShader(true);

  while(!done)
  {
    if( (glfwGetKey(GLFW_KEY_ESC)))
      done = true;
    if(!glfwGetWindowParam(GLFW_OPENED))
      done = true;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Tutaj przeksztalcenia macierzy
    camera.UpdateCamera();
    modelMatrix = mat4(1.0f);
    viewMatrix = camera.GetViewMatrix();
    projectionMatrix …
Run Code Online (Sandbox Code Playgroud)

c++ opengl texturing

7
推荐指数
1
解决办法
9395
查看次数

OpenGL,Shader Model 3.3纹理:黑色纹理?

我几个小时以来一直在反对这个问题,我确信这很简单,但我无法得到结果.我不得不稍微编辑这段代码,因为我已经构建了一个小的库来封装OpenGL调用,但以下是对事态的准确描述.

我正在使用以下顶点着色器:

#version 330
in vec4 position;
in vec2 uv;
out vec2 varying_uv;
void main(void)
{
    gl_Position = position;
    varying_uv = uv;
}
Run Code Online (Sandbox Code Playgroud)

以下片段着色器:

#version 330
in vec2 varying_uv;
uniform sampler2D base_texture;
out vec4 fragment_colour;
void main(void)
{
    fragment_colour = texture2D(base_texture, varying_uv);
}
Run Code Online (Sandbox Code Playgroud)

两个着色器都编译并且程序链接没有问题.

在我的init部分中,我加载了一个像这样的纹理:

// Check for errors.
kt::kits::open_gl::Core<QString>::throw_on_error();

// Load an image.
QImage image("G:/test_image.png");
image = image.convertToFormat(QImage::Format_RGB888);

if(!image.isNull())
{
    // Load up a single texture.
    glGenTextures(1, &Texture);
    glBindTexture(GL_TEXTURE_2D, Texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits()); …
Run Code Online (Sandbox Code Playgroud)

c++ opengl qt glsl texturing

6
推荐指数
1
解决办法
6124
查看次数

opengl 地图应用程序中的标签

精简版

如何在 OpenGL 映射应用程序中绘制短文本标签,而无需在用户放大和缩小时手动重新计算坐标?

长版

我有一个基于 OpenGL 的映射应用程序,我需要能够绘制最多约 250k 点的数据集。每个点都可以有一个简短的文本标签,通常长约 4 或 5 个字符。

目前,我使用包含所有字符的单个文本来执行此操作。对于每个点,我为其标签中的每个字符定义了一个四边形。因此,带有“Fred”标签的点将有四个与之关联的四边形,每个四边形使用纹理坐标到该单个纹理中以绘制其对应的字符。

当我绘制地图时,我在地图坐标(例如,经度/纬度)中绘制地图点本身。然后我计算屏幕坐标中每个点的位置,并再次更新屏幕坐标中每个点的标签四边形的四个角点。(例如,如果我确定该点是在屏幕点 100, 150 处绘制的,我可以将该点标签中第一个字符的四边形设置为从左上角 105, 155 开始且宽度为6 像素和 12 像素的高度,适合特定字符。然后第二个字符可能从 120、155 等开始。)然后一旦所有这些标签字符四边形都正确定位,我使用正交屏幕绘制它们投影。

问题是更新所有这些字符四边形坐标的过程很慢,对于具有 150k 点的特定测试数据集大约需要半秒(这意味着,由于每个标签大约有四个字符长,因此大约有 150k * [每个点 4 个字符] * [每个字符 4 个坐标对] 每次更新时需要设置的坐标对。

如果地图应用程序不涉及缩放,我就不需要在每次刷新时重新计算所有这些坐标。我可以只计算一次标签坐标,然后简单地移动我的查看矩形以显示正确的区域。但是通过缩放,我不知道如何在不进行坐标计算的情况下使其工作,因为否则字符会随着放大而变大而随着缩小而变小。

我想要的(以及我理解的 OpenGL 没有提供)是一种告诉 OpenGL 应该在固定屏幕坐标矩形中绘制四边形的方法,但是该矩形的左上角位置应该与地图坐标空间中的给定点。所以我想要一个原始层次结构(一个给定的地图点是它的标签字符四边形的父级)和在这个层次结构中混合两个不同坐标系的能力。

我试图了解是否有一些我可以设置的魔法变换矩阵可以完成所有这些形式,但我不知道该怎么做。

我考虑过的另一种替代方法是在每个点上使用着色器来处理计算该点的标签字符四边形坐标。我以前没有使用过着色器,我只是想了解 (a) 是否可以使用着色器来做到这一点,以及 (b) 计算着色器代码中的所有这些点是否实际上比我自己计算它们更能帮到我. (顺便说一下,我已经确认最大的瓶颈是计算四边形坐标,而不是将更新的坐标上传到 GPU。后者需要一些时间,但它是计算,更新坐标的绝对数量,占据了那半秒的大部分时间。)

(当然,另一种选择是首先更聪明地了解需要在给定视图中绘制哪些标签。但现在我想专注于假设需要绘制所有标签的解决方案。)

opengl rendering texturing labeling

5
推荐指数
1
解决办法
1468
查看次数

两种纹理的效率有多高效?

我正在使用Ffmpeg创建一个OpenGL视频播放器,我的所有视频都不是2的幂(因为它们是正常的视频分辨率).它使用我的nvidia卡以精细的fps运行,但我发现它不能在较旧的ATI卡上运行,因为它们不支持非二次幂纹理.

我只会在Nvidia卡上使用它,所以我并不太关心ATI问题,但我想知道如果textuers是2的幂,我会得到多少性能提升?是否值得填补它们?

此外,如果它值得,我如何将它们填充到最接近的较大的二次幂?

opengl textures texturing texture-mapping

5
推荐指数
1
解决办法
927
查看次数

OpenGL,GL_MODULATE和Multitexturing

我已经成功绘制了一个多纹理多边形,但不幸的是,只有整个纹理区域使用了重叠纹理的第一个像素.

这是纹理(GL_TEXTURE0和GL_TEXTURE1):

图标 覆盖

结果是这样的:

结果

仅使用顶部的红色像素.我试过在顶部只有一个1x1蓝色像素,我得到了与蓝色叠加相同的结果.

我的代码:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisableClientState(GL_COLOR_ARRAY);

const CGPoint vertices[] = {
    ccp(0,0),
    ccp(100,0),
    ccp(0,100),
    ccp(100,100),
};

// This will flip the image for us as well
const CGPoint coordinates[] = {
    ccp(0,1),
    ccp(1,1),
    ccp(0,0),
    ccp(1,0),
};

// Config multitextures
glClientActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, icon.name);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glEnable(GL_TEXTURE_2D);

glClientActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, overlay.name);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glEnable(GL_TEXTURE_2D);

GLubyte points = 4;

// Draw the square
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, …
Run Code Online (Sandbox Code Playgroud)

opengl-es texturing multitexturing

5
推荐指数
1
解决办法
5350
查看次数

GLSL:启用/禁用纹理+着色器

我正在寻找一种从着色器访问OpenGL状态的方法.该GLSL快速参考指南,一个真棒资源,无法真正帮助我在这一个.

在我正在研究的示例中,我有以下两个着色器:

顶点:

void    main()
{
    gl_FrontColor = gl_Color;
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = ftransform();
}
Run Code Online (Sandbox Code Playgroud)

分段:

uniform sampler2D   tex;
uniform float   flattening;

void main( void ) 
{
    vec4    texel;
    texel = texture2D(tex, gl_TexCoord[0].st);
    texel.r *= gl_Color.r;
    texel.g *= gl_Color.g;
    texel.b *= gl_Color.b;
    texel.a *= gl_Color.a;
    gl_FragColor = texel;
}
Run Code Online (Sandbox Code Playgroud)

当我渲染没有纹理的多边形时,它们的alpha值是正确的,但它们被指定为黑色.

1,我可以设置什么条件检查,以便vec4(1.0, 1.0, 1.0, 1.0)GL_TEXTURE_2D禁用时将变量'texel'设置为而不是从纹理中采样?

2,如果我为不同的纹理模式编写不同的着色器并在它们之间切换我将使用glEnable/ glDisable(GL_TEXTURE_2D),处理会更快吗?

opengl shader glsl texturing

3
推荐指数
1
解决办法
6166
查看次数

OpenGL - 同一对象的不同表面上的不同纹理

我正在尝试为我正在使用OpenGL制作的游戏画一辆车.car对象存储在带有.mtl文件的.obj文件中.

这款车有500多个顶点,100多个面,需要超过50种不同的纹理,使用我自己的顶点和片段着色器.我通过使用缓冲区对象来解决这个问题,缓冲区对象立即发送有关我的对象的所有信息.我的问题是尝试将不同的纹理应用于同一对象的不同表面.

我发现这个问题的答案是将纹理绑定到某个纹理编号(即GL_TEXTURE0,GL_TEXTURE1等等),并将Sampler2D传递给引用它的片段着色器.但是,我可以用这种方式存储50多个纹理吗?据我所知,它归于GL_TEXTURE32.

另外,我如何告诉着色器仅将纹理应用于汽车对象的某个面?

opengl textures texturing

3
推荐指数
1
解决办法
2899
查看次数

在OpenGL中绑定零纹理

在我的程序中,我使用2个纹理:t0和t1.t1是附加的,仅在某些情况下需要:

.....
glActiveTexture ( GL_TEXTURE1 );
if ( mDisplayMode == EDM_DEFAULT ){
    glBindTexture( GL_TEXTURE_2D, 0 ); // In this case I don't need t1
}else{
    glBindTexture( GL_TEXTURE_2D, mglDegreeTexture ); // In this case t1 will overlap t0
}
shader->setUniformValue( "textureId1", 1 );
Run Code Online (Sandbox Code Playgroud)

绘图着色器:

.....
vec4 c1 = texture( textureId0, uv );
vec4 c2 = texture( textureId1, gridUV );
float a = c2.a;
gl_FragColor = ( 1.0 - a )*c1 + a*c2;
Run Code Online (Sandbox Code Playgroud)

它工作正常:第二个纹理在需要时首先重叠.假设使用glBindTexture(..,0)返回零纹理(0,0,0,0),但在将NVidia驱动程序更新为314.07之后,我的代码生成黑屏,就像glBindTexture(..,0)返回(0,0) ,0,1)纹理.

我执行一些测试:使用着色器

....
vec4 c1 = texture( textureId0, …
Run Code Online (Sandbox Code Playgroud)

opengl texturing

3
推荐指数
1
解决办法
4204
查看次数

OpenGL GL_R8生成0x501,而GL_RGB8则不生成

这似乎是一个相当简单的问题(或至少尽可能接近).当我传递GL_RGB8,GL_RGBA8或大多数任何多通道内部格式时,下面的行不会产生错误.

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, fontImgSize, fontImgSize, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
Run Code Online (Sandbox Code Playgroud)

但是,当我传递GL_R8或任何8位单通道变量时,glGetError返回0x501(无效值).

glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, fontImgSize, fontImgSize, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
Run Code Online (Sandbox Code Playgroud)

知道这里发生了什么吗?我目前使用的计算机是相当过时和低功耗的,但如果这是问题我怀疑RGB8或RGBA8会工作.

对于那些好奇的,fontImgSize == 2048,我的计算机上的最大纹理大小.

编辑:看起来GL_RG8和2通道/ 16位格式也产生0x501

opengl texturing

3
推荐指数
1
解决办法
1213
查看次数

glTexImage2D与gluBuild2DMipmaps

非常基本的OpenGL纹理创建代码:

int width, height;
BYTE * data;
FILE * file;
// open texture data
file = fopen( filename, "rb" );
if ( file == NULL ) return 0;
// allocate buffer
width = 256;
height = 256;
data =(BYTE*) malloc( width * height * 3 );
// read texture data
fread( data, width * height * 3, 1, file );
fclose( file );
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
//gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width,   height, GL_RGB, GL_UNSIGNED_BYTE, data ); …
Run Code Online (Sandbox Code Playgroud)

opengl texturing glteximage2d mipmaps glu

3
推荐指数
1
解决办法
5049
查看次数

同一着色器中的GLSL textureCube和texture2D

我似乎无法能够兼得texture2D(),并textureCube()在一个着色器.当我这样做时,没有任何显示,也没有错误.我用自己的着色器加载器和Apple GLSL着色器构建器尝试了这一点,同样的事情发生了.即使我textureCube()在顶点着色器和texture2D()片段中也会发生这种情况.他们似乎自己工作得很好,但只要他们被召集在一起,无论以何种顺序,都没有出现.

opengl shader glsl texturing texture2d

2
推荐指数
1
解决办法
1813
查看次数

地形纹理

有没有办法以渐变的方式混合2个纹理?恩.第一个纹理从顶部开始,然后到达底部,第二个纹理从底部开始并向上移动.我想让它们像渐变中那样松散不透明,以创建平滑的连接.可能吗?

也许有其他方法来创建这样的纹理?问题是我的地形高度差异看起来不太好 - 在一个方形区域,一个三角形的纹理与另一个三角形不同.

opengl textures texturing texture-mapping

0
推荐指数
1
解决办法
677
查看次数