opengl - 只显示一个纹理

Posted

技术标签:

【中文标题】opengl - 只显示一个纹理【英文标题】:opengl - Only one texture displaying 【发布时间】:2015-02-06 06:10:55 【问题描述】:

我一直在尝试绘制一个小屋(作为顶部带有圆锥体的圆柱体),并在墙上添加砖纹理,在屋顶上添加屋顶瓦片纹理。但是,我只获得了我加载的第一个纹理(砖块)。

这是我的代码(请注意,我尝试使用 glActiveTexture 在纹理之间切换):

void drawCylinder()

int width, height;

unsigned char * data_for_wall = SOIL_load_image("./bricks.jpg", &width, &height, NULL, 0);

glDisable(GL_LIGHTING);

glGenTextures( 2, textures );

glActiveTexture(GL_TEXTURE0);

glEnable( GL_TEXTURE_2D );

glBindTexture(GL_TEXTURE_2D, textures[0]);

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

// Generate mipmaps, by the way.
glGenerateMipmap(GL_TEXTURE_2D);

gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, data_for_wall);
for(float theta = 0.0; theta <= 360.0; theta += 10.0 )

    //colors[k] = color4(0.69, 0.35, 0.0, 1.0); //This color is brown.
    tex_coords[global_index]=vec2(theta*DegreesToRadians, 0.0);
    float x = 0.15*sin(theta*DegreesToRadians);
    float y = 0.15*cos(theta*DegreesToRadians);
    points[global_index] = Translate(0.6, 0.0, 0.35)*point4(x, 0.0, y, 1.0);

     // This is the
    // bottom of the cylinder. The points are plotted in a full circle. The first three numbers are the x,y and z values
    // respectively. The last number (ie. 1.0) is not important - it just converts to homogeneous coordinates.
    ++global_index;
    tex_coords[global_index] = vec2(theta*DegreesToRadians, 0.25);
    points[global_index] = Translate(0.6, 0.0, 0.35)*point4(x, 0.25, y, 1.0);
    // This is the
    // top of the cylinder
    ++global_index;



//The roof of the hut
void drawCone()


int width, height;

unsigned char * data_for_roof = SOIL_load_image("./roof_tiles.jpg", &width, &height, NULL, 0);
glDisable(GL_TEXTURE_2D);


glActiveTexture(GL_TEXTURE1);


glBindTexture( GL_TEXTURE_2D, textures[1] );

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

// Generate mipmaps, by the way.
glGenerateMipmap(GL_TEXTURE_2D);

gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, data_for_roof);
int index = 0;
    int l = 0;
    for(float theta = 0.0; theta <= 360.0; theta += 10.0)
    
    tex_coords[global_index]=vec2(theta*DegreesToRadians, 0.25);

    points[global_index] = Translate(0.6, 0.0, 0.35)*point4(0.0, 0.5, 0.0, 1.0); // This is the top of the cone.
    ++global_index;

    tex_coords[global_index] = vec2(theta*DegreesToRadians, 0.5);

    points[global_index] = Translate(0.6, 0.0, 0.35)*point4(0.25*sin(theta*DegreesToRadians), 0.25, 0.25*cos(theta*DegreesToRadians), 1.0);
     // This is the
    // bottom of the cone.
    ++global_index;

    

这里是显示功能:

void
display( void )

mat4 mv = Translate(0.0, -0.065, -rad)*RotateX(Theta[0])*RotateY(Theta[1])*RotateZ(Theta[2]);
mat4 p = Perspective(10.0, aspectRatio, zNear, zFar);
glUniformMatrix4fv( matrix_loc, 1, GL_TRUE, mv );
glUniformMatrix4fv( projection_loc, 1, GL_TRUE, p );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glUniform3fv( theta, 1, Theta );

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glDrawArrays( GL_TRIANGLE_STRIP, 0, 74 );

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glDrawArrays( GL_TRIANGLE_STRIP, 74, 74);

glutSwapBuffers();

我不确定包含片段着色器是否重要,但无论如何我都会这样做: #版本 150

in  vec2 texCoord;

out vec4 fColor;

uniform sampler2D texture;

void main()

fColor = texture2D( texture, texCoord );

我已经努力了好几个小时才能做到这一点。有谁知道我做错了什么?

【问题讨论】:

【参考方案1】:

glActiveTexture() 用于设置在多重纹理(一次渲染多个纹理)时将纹理绑定到的纹理槽。例如,您可能有一个纹理用于​​纹理贴图,另一个用于法线贴图等等。

但是,您不是多纹理,因为您在单独的通道中渲染墙壁和圆锥体(即两次单独调用 glDrawArrays()),并且您的着色器每次通道仅使用一个纹理。因此,在每个通道中,您只渲染一个纹理,该纹理将位于插槽 0 中。

如果将活动纹理设置为 GL_TEXTURE1,然后调用 glBindTexture(),则纹理将绑定到插槽 1,而插槽 0 将保持不变。

因此,两次都将活动纹理槽设置为 0。从你的 display() 函数中删除这一行:

glActiveTexture(GL_TEXTURE1);

【讨论】:

另一种方法是将texture uniform 的值设置为第二次绘制调用的 1,以便使用绑定到单元 1 的纹理。 太棒了!谢谢你们!

以上是关于opengl - 只显示一个纹理的主要内容,如果未能解决你的问题,请参考以下文章

opengl 多个对象,纹理和非纹理,伪影

纹理不填充图形 - OpenGL

OpenGL:只模糊纹理的一部分;可以使用顶点着色器加速吗?

OpenGL 2D纹理无法正确显示c ++

OpenGL 纹理未按定义显示

OpenGL纹理随机未显示