简体   繁体   English

opengl-仅显示一个纹理

[英]opengl - Only one texture displaying

I have been trying draw a hut (as a cylinder with a cone on top) and add a brick txture to the wall and a roof-tile texture to the roof. 我一直在尝试画一个小屋(顶部为圆锥形的圆柱体),在墙体上添加砖砌结构,在屋顶上添加屋顶平铺纹理。 However, I am only getting the first texture that I load (the bricks). 但是,我只得到加载的第一个纹理(砖)。

Here is my code (Please note that I have tried to switch between textures using glActiveTexture): 这是我的代码(请注意,我已尝试使用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;

    }
}

And here is the display function: 这是显示功能:

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();
}

I am not sure if it is important to include the fragment shader but I will do it anyways: #version 150 我不确定是否包括片段着色器是否很重要,但是无论如何我都会这样做:#version 150

in  vec2 texCoord;

out vec4 fColor;

uniform sampler2D texture;

void main()
{
fColor = texture2D( texture, texCoord );
}

I have been struggling for hours to get this right. 为了解决这个问题,我已经努力了几个小时。 Does anyone know what I have done wrong? 有人知道我做错了吗?

glActiveTexture() is used to set the texture slot that you are binding a texture to when multi-texturing (rendering more than one texture in a single pass). glActiveTexture()用于设置多纹理(单次渲染多个纹理)时将纹理绑定到的纹理插槽。 For example, you might have one texture for a texture map, another for normal map and so on. 例如,一个纹理贴图可能有一个纹理,法线贴图有另一个纹理,依此类推。

However, you are not multi-texturing, because you render the walls and the cone in separate passes (ie two separate calls to glDrawArrays()), and your shader only uses a single texture per pass. 但是,您不是多纹理的,因为您是在单独的通道中渲染墙壁和圆锥体(即两次单独调用glDrawArrays()),并且着色器每次使用仅使用一个纹理。 So within each pass you are only rendering a single texture, which will be in slot 0. 因此,在每遍中,您仅渲染一个纹理,该纹理将位于插槽0中。

If you set the active texture to GL_TEXTURE1 and then call glBindTexture() then the texture will be bound to slot 1, and slot 0 will remain unchanged. 如果将活动纹理设置为GL_TEXTURE1,然后调用glBindTexture(),则纹理将绑定到插槽1,插槽0将保持不变。

So, set the active texture slot to 0 both times. 因此,两次将活动纹理插槽设置为0。 Remove this line from your display() function: 从display()函数中删除以下行:

glActiveTexture(GL_TEXTURE1);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM