2017-12-15 8 views
0

큰 프로젝트와 통합하기 위해 OpenGL 코드를 GLFW에서 Qt로 전송하려고합니다. 그러나 내가 시도한 것에 상관없이 나는 텍스쳐를 보여줄 수 없었고 나는 검은 스크린을 얻었습니다.OpenGL 코드는 GLFW에서 작동하지만 Qt OpenGL에서는 작동하지 않습니다.

Qt에서 프로그램은 오류없이 컴파일되며 텍스처를 삽입하기 전에 다중 색상 삼각형을 그립니다.

Qt OpenGL 객체를 셰이더, 셰이더 프로그램, 텍스처 용으로 사용해 보았지만 예제를 기반으로 코드를 다시 작성했지만 여전히 아무것도 사용하지 않았습니다.

다음은 텍스처를 표시하려고 시도하는 간단한 Qt 구현으로 검은 화면이됩니다. 정확한 GLFW에 해당 잘 작동 : QOpenGLWidget에 관한

CustomViewGL::CustomViewGL(QWidget *parent): QOpenGLWidget(parent) 
{ 
    QSurfaceFormat format; 

    format.setMajorVersion(3); 
    format.setMinorVersion(3); 
    format.setProfile(QSurfaceFormat::CoreProfile); 
    setFormat(format); 
} 

void CustomViewGL::initializeGL() 
{ 
    glewExperimental=true; 

    if (glewInit() != GLEW_OK) 
    { 
     qDebug() << "Failed to initialize GLEW"; 
    } 

    std::string vertexShaderSource = 
      " #version 330 core\n         " 
      "              " 
      " layout (location = 0) in vec3 aPos;     " 
      " layout (location = 1) in vec2 aTexCoord;   " 
      "              " 
      " out vec2 TexCoord;         " 
      "              " 
      " void main()           " 
      " {             " 
      "              " 
      " TexCoord = aTexCoord;        " 
      " gl_Position = vec4(aPos, 1.0);     " 
      "              " 
      " }\0             "; 

    std::string fragmentShaderSource = 
      " #version 330 core\n         " 
      "              " 
      " in vec2 TexCoord;         " 
      " out vec4 FragColor;         " 
      " uniform sampler2D tex;        " 
      " void main()           " 
      " {             " 
      "              " 
      " FragColor = texture(tex, TexCoord);     " 
      "              " 
      " }\0             "; 

    // Variables 
    unsigned int shaderVertex, shaderFragment, shaderProgram; 

    .... 
    .... 
    // Compile Shaders // 
    ... 
    ... 

    glUseProgram(shaderProgram); 

    // Vetrices 
    float rectangle[] = { 
     // positions   // texture coords 
     1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right 
     1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom right 
     -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left 
     -1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left 
    }; 

    unsigned int indices[] = { // note that we start from 0! 
     0, 1, 3, // first triangle 
     1, 2, 3 // second triangle 
    }; 

    QImage texture = QImage("wall.jpg").convertToFormat(QImage::Format_RGB888); 

    // Variables 
    unsigned int VAO, VBO, EBO, tex; 

    // VAO, VBO, Attributes Configuration 
    glGenVertexArrays(1, &VAO); 
    glBindVertexArray(VAO); 

    glGenBuffers(1, &VBO); 
    glBindBuffer(GL_ARRAY_BUFFER, VBO); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(rectangle), rectangle, GL_STATIC_DRAW); 


    glGenBuffers(1, &EBO); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); 
    glEnableVertexAttribArray(0); 

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); 
    glEnableVertexAttribArray(1); 

    // Texture 

    glGenTextures(1, &tex); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, tex); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); 

    float borderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; 
    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); 

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

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture.width(), texture.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, texture.bits()); 

    glGenerateMipmap(GL_TEXTURE_2D); 
} 

void CustomViewGL::paintGL() 
{ 
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*) 0); 
} 
+0

[mcve]에서 편집하십시오. – genpfault

+0

@genpfault OpenGL 코드입니다. 가능한 한 최소입니다. 가장 중요한 것만이 코드에 있습니다. 모든 것이 포함되고 검증 가능합니다. 복사하여 붙여 넣기하고 작동하는지 확인하십시오. 그것은 특별한 것은 없으며 텍스처를로드하고 화면에 표시합니다. – Manos

+0

사물의 "최소한"측면에서 조금 지나치게 컴파일되지 않습니다 :'# include's,'CustomViewGL' 선언,'wall.jpg' 누락. – genpfault

답변

0

, 나는이 질문에 대한 내 댓글에 기록 된대로, 내가 좋아하지 않는 첫 번째 동작은 버퍼 스왑 기능이없는 것입니다. Qt는 무의식적으로 물건을 그릴시기를 결정합니다. 이건 question에 명시되어 있듯이, 제가 확실히 원하지 않는 것입니다. 두 번째로 텍스처를 바인딩하고 텍스처 데이터를 설정하더라도 a) paintGL 함수에서 매번 바인딩하거나 b) TEXTURE0 데이터를 바인딩하고 설정 한 후 glActiveTexture (GL_TEXTURE1)를 호출하지 않는 한 화면에 표시되지 않습니다. 가장 이상한.

QGLWidget으로 전환하기로 결정 했으므로 the official Qt documentation recommends to avoid입니다. QGLWidget은 자동 스왑 버퍼를 사용하지 못하게하고, 스왑 버퍼 기능을 가지고 있으며, 질문에 언급 된 코드 (GLFW 기반 구현에서 직접 복사 한 것)로 제대로 작동하고 있습니다. 자동 버퍼 스왑을 비활성화의 OpenGL 버전을 선택하기 위해

설정 안티 앨리어싱 설정하고 공유 컨텍스트이 코드는 다음과 생성자로 사용됩니다

CustomViewGL::CustomViewGL(QWidget *parent, const QGLWidget *shareWidget): 
    QGLWidget(parent, shareWidget) // QGLWidget accepts as a second 
{         // constructor argument another QGLWidget 
    QGLFormat format;    // thus context sharing between this and 
            // the shareWidget is created 

    format.setVersion(3,3); // Set OpenGL version, here 3.3 
    format.setProfile(QGLFormat::CoreProfile); // Core Profile 
    format.setSamples(16); // Anti Alliasing 

    setFormat(format); 

    setAutoBufferSwap(false); // Prevents Qt from drawing whenever it wants 
} 

생성자의 헤더 파일 decleration은 다음과 같습니다

CustomViewGL(QWidget *parent = 0, const QGLWidget *shareWidget = 0); 

그런 다음 보호 된 함수 initializeGL()을 구현하고 초기화 코드를 입력하면 준비가 완료됩니다.