2016-07-25 3 views
1

저는 OpenGL을 처음 접했으므로 처음부터 시작했습니다. 내가 한 첫 번째 작업은 기존의 방식 (glBegin() 및 glEnd() 사용)을 사용하여 기본 2D 텍스처를 표시하는 것이 었습니다. 그런 다음 나중에 VBO와 VAO를 사용할 수 있도록 코드를 개선하려고 했으므로 Shaders를 사용해야했습니다. 색상이있는 쉐이더를 사용할 수는 있었지만 텍스처가 좋지 않습니다.Qt/OpenGL 2D 텍스처를 표시하려고합니다.

glwidget.h

#ifndef GLWIDGET_H 
#define GLWIDGET_H 

#include <QOpenGLWidget> 
#include <QOpenGLFunctions> 
#include <QOpenGLBuffer> 
#include <QDebug> 
#include <QOpenGLTexture> 
#include <GL/gl.h> 
#include <QGLFunctions> 
#include <QOpenGLShader> 
#include <QOpenGLShaderProgram> 



class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions 
{ 
    Q_OBJECT 
public: 
    explicit GLWidget(QWidget *parent = 0); 

    void initializeGL(); 
    void paintGL(); 
    void resizeGL(int w, int h); 
    void LoadGLTextures(); 

private : 

    QOpenGLShaderProgram *program; 
    GLuint tex; 


public slots: 



private slots: 



}; 

#endif // GLWIDGET_H 

glwidget.cpp

#include "glwidget.h" 


GLWidget::GLWidget(QWidget *parent) : 
     QOpenGLWidget(parent) 
{ 

} 

void GLWidget::LoadGLTextures(){ 

    QImage img; 

    if(!img.load("C:\\Users\\Adrien\\Desktop\\open3.bmp")){ 

     qDebug()<<"Image loading failed"; 
    } 

    QImage t = (img.convertToFormat(QImage::Format_RGBA8888)).mirrored(); 

    glGenTextures(1, &tex); 

    glBindTexture(GL_TEXTURE_2D, tex); 

     glTexImage2D(GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits()); 

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

    glBindTexture(GL_TEXTURE_2D, 0); 



} 

void GLWidget::initializeGL(){ 

    initializeOpenGLFunctions(); 

    glClear(GL_COLOR_BUFFER_BIT); 

    glEnable(GL_TEXTURE_2D); 
    LoadGLTextures(); 

    QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); 
    const char *vsrc = 
     "#version 150 core\n" 
     "in vec2 in_Vertex;\n" 
     "in vec2 vertTexCoord;\n" 
     "out vec2 fragTexCoord;\n" 
     "void main(void)\n" 
     "{\n" 
     " gl_Position = vec4(in_Vertex, 0.0, 1.0);\n" 
     " fragTexCoord = vertTexCoord;\n" 
     "}\n"; 
    vshader->compileSourceCode(vsrc); 

    QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); 
    const char *fsrc = 
      "#version 150 core\n" 
      "uniform sampler2D tex;\n" 
      "in vec2 fragTexCoord;\n" 
      "void main(void)\n" 
      "{\n" 
      " gl_FragColor = texture2D(tex,fragTexCoord);\n" 
      "}\n"; 
    fshader->compileSourceCode(fsrc); 

    program = new QOpenGLShaderProgram; 
    program->addShader(vshader); 
    program->addShader(fshader); 

    program->link(); 
    program->bind(); 
    program->setUniformValue("tex", tex); 

} 

void GLWidget::paintGL(){ 

    glClear(GL_COLOR_BUFFER_BIT); 

    program->bind(); 
    { 
     float vertices[] = {-1.0,-1.0, 1.0,-1.0, 1.0,1.0, -1.0,1.0}; 

     float coordTexture[] = {0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0}; 

     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices); 
     glEnableVertexAttribArray(0); 

     glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, coordTexture); 
     glEnableVertexAttribArray(2); 

     glBindTexture(GL_TEXTURE_2D, tex); 

     glDrawArrays(GL_QUADS, 0, 4); 

     glBindTexture(GL_TEXTURE_2D, 0); 

     glDisableVertexAttribArray(2); 
     glDisableVertexAttribArray(0); 


    } 
    program->release(); 

} 

void GLWidget::resizeGL(int w, int h){ 

    glViewport(0, 0, (GLint)w, (GLint)h); 

} 

내가 가진 모든 검은 화면입니다 :

여기 내 코드입니다. 모든 것이 2D입니다 (프로젝트에는 3D가 필요하지 않습니다). 저는 VBO와 VAO를 잠시 사용하지 않고 있습니다. 먼저 이것을 작동 시키려고합니다. LoadGLTexture()는 이전에 이미 사용했기 때문에 작동하는 것 같습니다. 버텍스 및 조각 쉐이더는 조각 쉐이더에서 색상을 사용하여 작업했습니다. 당신이 텍스처 유닛를 설정해야합니다 동안

감사

+1

gl 호출마다 glGetError를 호출하십시오. 오류가 발생하면 기록하십시오. 또한 셰이더 컴파일 오류를 확인하고 셰이더 컴파일러의 출력을 기록하십시오. 로그를 게시하십시오. – Dutow

답변

1

로 변경, 사용자의 위치와 TEXCOORD는 위치가 잘못 속성 :

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices); 
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, coordTexture); 

첫 번째 매개 변수는 위치입니다. 그것은 운전사에 의해 할당되고 당신은 그 위치가 유효하다는 것을 다만 추정하고있다. 이 문제를 해결하려면, 쉐이더에서 위치를 조회 :

GLint vertexLocation = glGetAttribLocation(shaderProgram, "in_Vertex"); 
GLint texcoordLocation = glGetAttribLocation(shaderProgram, "vertTexCoord"); 

그런 다음 glVertexAttribPointer의 첫 번째 매개 변수와 glEnableVertexAttribArray에 해당 값을 제공합니다.

+0

아, 그래, 좋은 전화. OP가 버전 3.1과 함께 가고 속성에 대한 명시 적 레이아웃을 사용하는 것이 현명 할 것입니다. – rwols

+0

고마워, 아래의 rwols에 의해 주어진 것과 함께이 수정 작업. 그리고 나는 그것을 더 잘 이해합니다. – Megatron300

1
program->setUniformValue("tex", tex); 

tex 변수는 텍스처에 핸들입니다. 답변과 의견에 언급 된 다른 문제 중

glActiveTexture(GL_TEXTURE0); 
program->setUniformValue("tex", 0); 
관련 문제