简体   繁体   中英

GLSL 4.3 texture issue

I can't get my texture to work right. Here's my code below

static const char * codeVertexShade = "\
#version 430\n\
  attribute vec2 texCoor;\
  out vec2 texOut;\
  void main(){\
    gl_Position = ftransform();\
    texOut.x = texCoor.x; texOut.y = texCoor.y;\
  }\
";

static const char * codeFragmentShade = "\
#version 430\n\
  in vec4 col;\
  in vec2 texOut;\
  uniform sampler2D sampTex;\
  void main(){\
    gl_FragColor = texture(sampTex, texOut);\
  }\
";

#define CHECKGL if(!checkGL(__LINE__)){ throw std::exception(); }

bool checkGL(unsigned int line){
  switch(glGetError()){
  case GL_NO_ERROR:
    return true;
  case GL_INVALID_ENUM:
    std::cout<< "GL_INVALID_ENUM " << line << std::endl;
    break;
  case GL_INVALID_VALUE:
    std::cout<< "GL_INVALID_VALUE " << line << std::endl;
    break;
  case GL_INVALID_OPERATION:
    std::cout<< "GL_INVALID_OPERATION " << line << std::endl;
    break;
  case GL_INVALID_FRAMEBUFFER_OPERATION:
    std::cout<< "GL_INVALID_FRAMEBUFFER_OPERATION " << line << std::endl;
    break;
  case GL_OUT_OF_MEMORY:
    std::cout<< "GL_OUT_OF_MEMORY " << line << std::endl;
    break;
  }

  return false;
}

GLint createShader(const char *pCode, GLenum type){
  GLint id = glCreateShader(type);

  const char * arrCode[1] = { pCode };

  glShaderSource(id, 1, arrCode, NULL);
  glCompileShader(id);

  GLint status=0;
  glGetShaderiv(id, GL_COMPILE_STATUS, &status);
  if(status != GL_TRUE){
    GLchar info[1024];
    glGetShaderInfoLog(id, 1024, NULL, info);
    std::cout << info << std::endl;
    throw std::exception();
  }

  return id;
}

int main(void)
{
  testDeath die;

  try{
    int NumberOfExtensions=0;

    glGetIntegerv(GL_NUM_EXTENSIONS, &NumberOfExtensions);
    for(int i=0; i<NumberOfExtensions; i++) {
      const GLubyte *ccc=glGetStringi(GL_EXTENSIONS, i);
      std::cout << (const char*)ccc << std::endl;
    }

    int attrListDoubleBuff[] = {
      GLX_RGBA, GLX_DOUBLEBUFFER,
      None
    };

    int attrListSingleBuff[] = {
      GLX_RGBA,
      None
    };

    Bool    mDoubleBuffered;
    XEvent  mEvent;
    Atom    mDeleteMessage;

    Display *mDisplay = XOpenDisplay(0);
    int mScreen = DefaultScreen(mDisplay);
    XVisualInfo *vi = glXChooseVisual(mDisplay, mScreen, attrListDoubleBuff);

    if(vi == NULL){
      vi = glXChooseVisual(mDisplay, mScreen, attrListSingleBuff);
      mDoubleBuffered = False;
    }else{
      mDoubleBuffered = True;
    }

    GLXContext mContext = glXCreateContext(mDisplay, vi, 0, GL_TRUE);
    Colormap cmap = XCreateColormap(
      mDisplay,
      RootWindow(mDisplay, vi->screen),
      vi->visual,
      AllocNone
    );

    XSetWindowAttributes mWinAttr;
    mWinAttr.colormap = cmap;
    mWinAttr.border_pixel = 0;
    mWinAttr.event_mask = KeyPressMask | ButtonPressMask | StructureNotifyMask;

    Window mWindow = XCreateWindow(
      mDisplay,
      RootWindow(mDisplay, vi->screen),
      50, 50,
      200, 200,
      0,
      vi->depth,
      InputOutput,
      vi->visual,
      CWBorderPixel | CWColormap | CWEventMask,
      &mWinAttr
    );

    mDeleteMessage = XInternAtom(mDisplay, "WM_DELETE_WINDOW", True);
    XSetWMProtocols(mDisplay, mWindow, &mDeleteMessage, 1);

    XSetStandardProperties(
      mDisplay,
      mWindow,
      "test",
      "test",
      None,
      NULL,
      0,
      NULL
    );

    XMapRaised(mDisplay, mWindow);
    XFlush(mDisplay);
    glXMakeCurrent(mDisplay, mWindow, mContext);

    {
      const char* version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
      const char* vglsl = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
      std::cout  << "Version 1: " << std::endl
      << "OpenGL=" << (version == NULL ? "error" : version) << std::endl
      << "GLSL=" << (vglsl == NULL ? "error" : vglsl) << std::endl
      ;
    }

    glEnableClientState(GL_VERTEX_ARRAY);

    GLuint idShadeMain = glCreateProgram();
    if(idShadeMain==0){
      std::cout << "Shader program not made" << std::endl;
      throw std::exception();
    }

    GLint idVertShade = createShader(codeVertexShade, GL_VERTEX_SHADER);
    GLint idFragShade = createShader(codeFragmentShade, GL_FRAGMENT_SHADER);

    glAttachShader(idShadeMain, idVertShade);
    glAttachShader(idShadeMain, idFragShade);

    const GLfloat vbuff[]={
      -0.8,   0.8,  0,
       0.8,   0.8,  0,
       0.8,  -0.8,  0,
      -0.8,  -0.8,  0
    };

    const GLint ibuff[]={
      0, 1, 2,
      2, 3, 0
    };

    const GLfloat tbuff[]={
    //  au    av    bu    bv    cu    cv
      0.0f,  0.0f,  0.0f,  1.0f,  1.0f,  1.0f,
      0.0f,  0.0f,  0.0f,  1.0f,  1.0f,  1.0f
    };

    enum vertAtt{
      vertAtt_verts = 0,
      vertAtt_texcoor,
      vertAtt_MAX
    };

    GLuint bufferIDs[vertAtt_MAX];
    glGenBuffers(vertAtt_MAX, bufferIDs);

    glBindBuffer(GL_ARRAY_BUFFER, bufferIDs[vertAtt_verts]); CHECKGL;
    glEnableVertexAttribArray(vertAtt_verts); CHECKGL;
    glVertexAttribPointer(vertAtt_verts, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glBufferData(
      GL_ARRAY_BUFFER,
      sizeof(vbuff),
      vbuff,
      GL_STATIC_DRAW
    );  CHECKGL;

    glBindBuffer(GL_ARRAY_BUFFER, bufferIDs[vertAtt_texcoor]); CHECKGL;
    glBindAttribLocation(idShadeMain, vertAtt_texcoor, "texCoor"); CHECKGL;
    glEnableVertexAttribArray(vertAtt_texcoor); CHECKGL;
    glVertexAttribPointer(vertAtt_texcoor, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glBufferData(
      GL_ARRAY_BUFFER,
      sizeof(tbuff),
      tbuff,
      GL_STATIC_DRAW
    );  CHECKGL;

    GLuint buffidIndexs;
    glGenBuffers(1, &buffidIndexs);    // Generate 1 index buffer
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffidIndexs);
    glBufferData(
      GL_ELEMENT_ARRAY_BUFFER,
      sizeof(ibuff),
      ibuff,
      GL_STATIC_DRAW
    ); CHECKGL;

    GLuint idTex;
    glEnable(GL_TEXTURE_2D);
    glGenTextures(1, &idTex);
    if(glIsTexture(idTex)){
      std::cout << "Not Texture" << std::endl;
      throw std::exception();
    }
    glBindTexture(GL_TEXTURE_2D, idTex); CHECKGL;
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    GLbyte buffTex[32*32*4]; memset(buffTex, 150, 32*32*4);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffTex); CHECKGL;

    glBindTexture(GL_TEXTURE_2D, 0);

    {
      GLint status = 0;
      GLchar log[1024] = { 0 };

      glLinkProgram(idShadeMain);
      glGetProgramiv(idShadeMain, GL_LINK_STATUS, &status);
      if(status != GL_TRUE){
        glGetProgramInfoLog(idShadeMain, 1024, NULL, log);
        std::cout << log << std::endl;
        throw std::exception();
    }

    GLint idSample = glGetUniformLocation(idShadeMain, "sampTex"); CHECKGL;
    if(idSample == -1){
      std::cout<<"Bad sample"<<std::endl;
      throw std::exception();
    }

    const char* DestroyWindowAtomName = "WM_PROTOCOLS";
    const size_t AtomNameLen = strlen(DestroyWindowAtomName);

    GLuint texUnit = 0;
    bool keepLooping=true;
    GLfloat rotate = 0.0f;
    try{
      while(keepLooping){

        // X11 junk
        for(int run=0; run < 3 && XPending(mDisplay) > 0; ++run){
          XNextEvent(mDisplay, &mEvent);
          switch (mEvent.type){
          case DestroyNotify:
            keepLooping = false;
            break;

          case ConfigureNotify:
            glViewport(0, 0, mEvent.xconfigure.width, mEvent.xconfigure.height);
            break;

          default:
            break;
          }
        }

        glEnable(GL_TEXTURE_2D);
        glDisable(GL_DITHER);
        glFrontFace(GL_CW);
        glClearColor(0.8f, 0.8f, 0.8f, 0.0f);
        glClearDepth(1.0f);

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glShadeModel(GL_SMOOTH);

        glDepthFunc(GL_LEQUAL);
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUseProgram(idShadeMain);

        for(short b=vertAtt_verts; b != vertAtt_MAX; ++b)
          glBindBuffer(GL_ARRAY_BUFFER, bufferIDs[b]);

        glUniform1i(idSample, texUnit); CHECKGL;
        glActiveTexture( static_cast<GLenum>(GL_TEXTURE0 + texUnit) ); CHECKGL;
        glBindTexture(GL_TEXTURE_2D, idTex); CHECKGL;

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffidIndexs); CHECKGL;
        glDrawElements(GL_TRIANGLES, sizeof(ibuff) / sizeof(ibuff[0]), GL_UNSIGNED_INT, 0); CHECKGL;

        if(mDoubleBuffered)
          glXSwapBuffers(mDisplay, mWindow);
        else
          glFlush();

        usleep(10);
      }
    }catch(...){
    }

    glDetachShader(idShadeMain, idVertShade);
    glDeleteShader(idVertShade);
    glDetachShader(idShadeMain, idFragShade);
    glDeleteShader(idFragShade);
    glDeleteProgram(idShadeMain);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glDeleteBuffers(1, &buffidIndexs);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDeleteBuffers(vertAtt_MAX, bufferIDs);

    glBindTexture(GL_TEXTURE_2D, 0);
    glDeleteTextures(1, &idTex);

    if(mContext){
      (void)glXMakeCurrent(mDisplay, None, NULL);
      glXDestroyContext(mDisplay, mContext);
      mContext = NULL;
    }

    XCloseDisplay(mDisplay);

  }catch(std::exception &e){
    std::cout << e.what() << std::endl;
  }

  return 0;
}

But sadly all I get is this:

没有质地

My console output is:

Version 1:
OpenGL=4.2.12337 Compatibility Profile Context 13.101
GLSL=4.30

And I tried the following tests inside the fragment shader:

static const char * codeFragmentShade = "\
#version 430\n\
  in vec4 col;\
  in vec2 texOut;\
  uniform sampler2D sampTex;\
  void main(){\
    gl_FragColor = texture(sampTex, texOut); gl_FragColor.r=textureSize( sampTex, 0 )[0]/2.0;\
  }\
";

显示一些纹理信息

static const char * codeFragmentShade = "\
#version 430\n\
  in vec4 col;\
  in vec2 texOut;\
  uniform sampler2D sampTex;\
  void main(){\
    gl_FragColor = texture(sampTex, texOut); gl_FragColor.rg=texOut;\
  }\
";

显示纹理坐标

So it appears as though my mapping is there, but the width is 1 pixel wide or so. The height appears to be 0.

So what am I doing wrong?

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);

You are requesting mipmapping here, but your texture is not mipmap-complete (which means that your texture can't be sampled): you only specify level 0. You have several options:

  1. Disably the mipmapping, eg use minification filter GL_LINEAR
  2. Specify the complete set of mimpap levels manually.
  3. Use the automatic mipmap generation by calling glGenerateMipmap() after you specified the image data for level 0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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