How do I get textures to work in OpenGL?

后端 未结 2 1373
忘掉有多难
忘掉有多难 2020-12-21 13:32

I\'m using the tutorials on http://arcsynthesis.org/gltut/ to learn OpenGL, it\'s required, I have to use it. Mostly I want to apply the textures from Tutorial 15 onto objec

相关标签:
2条回答
  • 2020-12-21 14:01

    Ok guys, I've worked on this whole thing, and did manage to somehow get it running. First off I had to add samplers:

    GLuint g_samplers;
    
    //Add Later
    void CreateSamplers()
    {
    glGenSamplers(1, &g_samplers);
    
        glSamplerParameteri(g_samplers, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glSamplerParameteri(g_samplers, GL_TEXTURE_WRAP_T, GL_REPEAT);
    
    //Linear mipmap Nearest
    glSamplerParameteri(g_samplers, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glSamplerParameteri(g_samplers, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    }
    

    I also added this to the file thing:

    glimg::OpenGLPixelTransferParams xfer = glimg::GetUploadFormatType(pImageSet->GetFormat(), 0);
    
    glimg::SingleImage image = pImageSet->GetImage(0, 0, 0);
    glimg::Dimensions dims = image.GetDimensions();
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dims.width, dims.height, 0, 
      xfer.format, xfer.type, image.GetImageData());
    

    The xfer variable does get the format and type adjusted to the dds. Also the render code got turned into this:

    //Added necessary 
    glActiveTexture(GL_TEXTURE0 + g_colorTexUnit);
    glBindTexture(GL_TEXTURE_2D,g_checkerTexture);
    glBindSampler(g_colorTexUnit, g_samplers);
    g_pLeftMesh->Render();
    glBindSampler(g_colorTexUnit, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    

    And of course at the end of init() I needed to add the CreateSamplers thing:

    //Added this later
    LoadCheckerTexture();
    CreateSamplers();
    

    I'm sorry for all the trouble with all this, but guess OpenGL really is just this confusing and it was just dumb luck that I got it right. Just posting this so that people know

    0 讨论(0)
  • 2020-12-21 14:14

    Your fail to add textures may be caused by:

    • Have you add texture coordinates to objects? (this is the most probable cause, because you are adding textures to non textured tutorial), add textures to VAO.
    • Did you add uniform textureunit (Sampler2D)? (it must be uniform, else texturing will not work properly)
    • Is your texture loaded,binded,enabled (GL_TEXTURE_2D) ?
    • Is your active texture unit - 0? if not change layout/multitexture coords or set active texture 0

    This two codes are simple texturing shaders (texture unit 0) no special things (like light,blend,bump,...):


    tm_l2g is transformation local obj space -> world space (Modelview)
    tm_g2s is transformation world space -> screen space (Projection)
    pos are vertex coordinates
    txt are texture coordinates
    col are colors

    Do not forget to change uniform names and layout locations to yours.

    Vertex:

    //------------------------------------------------------------------
    #version 420 core
    //------------------------------------------------------------------
    uniform mat4x4 tm_l2g;
    uniform mat4x4 tm_g2s;
    
    layout(location=0) in vec3 pos;
    layout(location=1) in vec4 col;
    layout(location=2) in vec2 txr;
    
    out smooth vec4 pixel_col;
    out smooth vec2 pixel_txr;
    //------------------------------------------------------------------
    void main(void)
        {
        vec4 p;
        p.xyz=pos;
        p.w=1.0;
        p=tm_l2g*p;
        p=tm_g2s*p;
        gl_Position=p;
        pixel_col=col;
        pixel_txr=txr;
        }
    //------------------------------------------------------------------
    

    fragment:

    //------------------------------------------------------------------
    #version 420 core
    //------------------------------------------------------------------
    in smooth vec4 pixel_col;
    in smooth vec2 pixel_txr;
    uniform sampler2D   txr_texture0;
    out layout(location=0) vec4 frag_col;
    //------------------------------------------------------------------
    void main(void)
        {
        vec4 col;
        col=texture(txr_texture0,pixel_txr.st);
        frag_col=col*pixel_col;
        }
    //------------------------------------------------------------------
    

    [edit1] CPU old style OpenGL render code (initializations are not included its only render code they can be found here)

    //------------------------------------------------------------------
    // set modelview,projection,textures,bind GLSL programs...
    GLfloat a=10.0,z=0.0;
    glColor3f(1.0,1.0,1.0);
    glBegin(GL_QUADS);
    // textured quad
    glTexCoord2f(0.0,0.0); glVertex3f(-a,-a,z);
    glTexCoord2f(0.0,1.0); glVertex3f(-a,+a,z);
    glTexCoord2f(1.0,1.0); glVertex3f(+a,+a,z);
    glTexCoord2f(1.0,0.0); glVertex3f(+a,-a,z);
    // reverse order quad to be shore that at least one passes by CULL_FACE
    glTexCoord2f(1.0,0.0); glVertex3f(+a,-a,z);
    glTexCoord2f(1.0,1.0); glVertex3f(+a,+a,z);
    glTexCoord2f(0.0,1.0); glVertex3f(-a,+a,z);
    glTexCoord2f(0.0,0.0); glVertex3f(-a,-a,z);
    glEnd();
    
    //------------------------------------------------------------------
    

    [edit2] ok here goes VAO/VBO render code,...

    //------------------------------------------------------------------------------
    // enum of VBO locations (it is also your layout location) I use enums for simple in code changes
    enum _vbo_enum
        {
        _vbo_pos=0,     // glVertex
        _vbo_col,       // glColor
        _vbo_tan,       // glNormal
        _vbo_unused0,   // unused (at least i dont see anything at this location in your code)
        _vbo_unused1,   // unused (at least i dont see anything at this location in your code)
        _vbo_txr,       // glTexCoord
        _vbos
        };
    //------------------------------------------------------------------------------
    // 'global' names and size for OpenGL mesh in VAO/VBO ... similar ot texture names/handles
    GLuint vao[1],vbo[_vbos],num_pnt=0;
    //------------------------------------------------------------------------------
    void VAO_init_cube()    // call this before VAO use,...but after OpenGL init !
        {
        //[1] first you need some model to render (mesh), here is a simple cube
        // size,position of cube - change it that it is visible in your scene
        const GLfloat a=1.0,x=0.0,y=0.0,z=0.0;
        // cube points 3f x,y,z
        GLfloat mesh_pos[]=
            {
            x-a,y-a,z-a,x-a,y+a,z-a,x+a,y+a,z-a,x+a,y-a,z-a,
            x-a,y-a,z+a,x-a,y+a,z+a,x+a,y+a,z+a,x+a,y-a,z+a,
            x-a,y-a,z-a,x-a,y-a,z+a,x+a,y-a,z+a,x+a,y-a,z-a,
            x-a,y+a,z-a,x-a,y+a,z+a,x+a,y+a,z+a,x+a,y+a,z-a,
            x-a,y-a,z-a,x-a,y+a,z-a,x-a,y+a,z+a,x-a,y-a,z+a,
            x+a,y-a,z-a,x+a,y+a,z-a,x+a,y+a,z+a,x+a,y-a,z+a,
            };
        // cube colors 3f r,g,b
        GLfloat mesh_col[]=
            {
            0.0,0.0,0.0,0.0,1.0,0.0,1.0,1.0,0.0,1.0,0.0,0.0,
            0.0,0.0,1.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,1.0,
            0.0,0.0,0.0,0.0,0.0,1.0,1.0,0.0,1.0,1.0,0.0,0.0,
            0.0,1.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.0,
            0.0,0.0,0.0,0.0,1.0,0.0,0.0,1.0,1.0,0.0,0.0,1.0,
            1.0,0.0,0.0,1.0,1.0,0.0,1.0,1.0,1.0,1.0,0.0,1.0,
            };
        // cube normals 3f x,y,z
        GLfloat mesh_tan[]=
            {
            -0.6,-0.6,-0.6,-0.6,+0.6,-0.6,+0.6,+0.6,-0.6,+0.6,-0.6,-0.6,
            -0.6,-0.6,+0.6,-0.6,+0.6,+0.6,+0.6,+0.6,+0.6,+0.6,-0.6,+0.6,
            -0.6,-0.6,-0.6,-0.6,-0.6,+0.6,+0.6,-0.6,+0.6,+0.6,-0.6,-0.6,
            -0.6,+0.6,-0.6,-0.6,+0.6,+0.6,+0.6,+0.6,+0.6,+0.6,+0.6,-0.6,
            -0.6,-0.6,-0.6,-0.6,+0.6,-0.6,-0.6,+0.6,+0.6,-0.6,-0.6,+0.6,
            +0.6,-0.6,-0.6,+0.6,+0.6,-0.6,+0.6,+0.6,+0.6,+0.6,-0.6,+0.6,
            };
        // cube texture coords 2f s,t
        GLfloat mesh_txr[]=
            {
            0.0,0.0,0.0,1.0,1.0,1.0,1.0,0.0,
            0.0,0.0,0.0,1.0,1.0,1.0,1.0,0.0,
            0.0,0.0,0.0,1.0,1.0,1.0,1.0,0.0,
            0.0,0.0,0.0,1.0,1.0,1.0,1.0,0.0,
            0.0,0.0,0.0,1.0,1.0,1.0,1.0,0.0,
            0.0,0.0,0.0,1.0,1.0,1.0,1.0,0.0,
            };
        // init VAO/VBO
        glGenVertexArrays(1,vao);   // allocate 1 x VAO
        glGenBuffers(_vbos,vbo);    // allocate _vbos x VBO
        // copy mesh to VAO/VBO ... after this you do not need the mesh anymore
        GLint i,sz,n;               // n = number of numbers per 1 entry
        glBindVertexArray(vao[0]);
        num_pnt=sizeof(mesh_pos)/(sizeof(GLfloat)*3);   // num of all points in mesh
    
        i=_OpenGLVAOgfx_pos; n=3; sz=sizeof(GLfloat)*n;
        glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
        glBufferData(GL_ARRAY_BUFFER,sz*num_pnt,mesh_pos,GL_STATIC_DRAW);
        glEnableVertexAttribArray(i);
        glVertexAttribPointer(i,n,GL_FLOAT,GL_FALSE,0,0);
    
        i=_OpenGLVAOgfx_col; n=3; sz=sizeof(GLfloat)*n;
        glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
        glBufferData(GL_ARRAY_BUFFER,sz*num_pnt,mesh_col,GL_STATIC_DRAW);
        glEnableVertexAttribArray(i);
        glVertexAttribPointer(i,n,GL_FLOAT,GL_FALSE,0,0);
    
        i=_OpenGLVAOgfx_tan; n=3; sz=sizeof(GLfloat)*n;
        glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
        glBufferData(GL_ARRAY_BUFFER,sz*num_pnt,mesh_tan,GL_STATIC_DRAW);
        glEnableVertexAttribArray(i);
        glVertexAttribPointer(i,n,GL_FLOAT,GL_FALSE,0,0);
    
        i=_OpenGLVAOgfx_txr; n=2; sz=sizeof(GLfloat)*n;
        glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
        glBufferData(GL_ARRAY_BUFFER,sz*num_pnt,mesh_txr,GL_STATIC_DRAW);
        glEnableVertexAttribArray(i);
        glVertexAttribPointer(i,n,GL_FLOAT,GL_FALSE,0,0);
    
        glBindVertexArray(0);
        }
    //------------------------------------------------------------------------------
    void VAO_draw() // call this to draw your mesh,... need to enable and bind textures,...  before use
        {
        glDisable(GL_CULL_FACE);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
    
        glBindVertexArray(vao[0]);
         glEnableVertexAttribArray(_vbo_pos);
         glEnableVertexAttribArray(_vbo_col);
         glEnableVertexAttribArray(_vbo_tan);
        glDisableVertexAttribArray(_vbo_unused0);
         glEnableVertexAttribArray(_vbo_txr);
    
        glDrawArrays(GL_QUADS,0,num_pnt);
    
        glDisableVertexAttribArray(_vbo_pos);
        glDisableVertexAttribArray(_vbo_col);
        glDisableVertexAttribArray(_vbo_tan);
        glDisableVertexAttribArray(_vbo_unused0);
        glDisableVertexAttribArray(_vbo_unused1);
        glDisableVertexAttribArray(_vbo_txr);
        glBindVertexArray(0);
        }
    //------------------------------------------------------------------------------
    void VAO_exit() // clean up ... call this when you do not need VAO/VBO anymore
        {
        glDisableVertexAttribArray(_vbo_pos);
        glDisableVertexAttribArray(_vbo_col);
        glDisableVertexAttribArray(_vbo_tan);
        glDisableVertexAttribArray(_vbo_unused0);
        glDisableVertexAttribArray(_vbo_unused1);
        glDisableVertexAttribArray(_vbo_txr);
        glBindVertexArray(0);
        glDeleteVertexArrays(1,vao);
        glDeleteBuffers(_vbos,vbo);
        }
    //------------------------------------------------------------------------------
    

    [edit3] if you are win32/64 user you can try my IDE for GLSL

    It is very simple and easy to use, but cannot change texture/attrib locations. Press [F1] for help,... [F9] for run [F10] for return to normal OpenGL mode. Also txt-editor is little buggy sometimes but it is enough for my purpose.

    • GLSL IDE
    0 讨论(0)
提交回复
热议问题