Texturing a vertex in OpenGL and GLSL



  • I'm trying to put a texture on a vertex using some tutorials i found on the internet, sadly none of those are showing the entire code (GLSL + Source code).

    Tutorials i have used:
    http://www.ozone3d.net/tutorials/glsl_texturing_p02.php#part_2 http://www.opengl.org/wiki/Sampler_(GLSL)#Binding_textures_to_samplers

    +'OpenGL Window Example', on which my code is based.

    Header:
    @#include <openglwindow.h>

    #include <QtGui/QGuiApplication>
    #include <QtGui/QMatrix4x4>
    #include <QtGui/QOpenGLShaderProgram>
    #include <QtGui/QScreen>

    #include <QtCore/qmath.h>

    class TestWindow : public OpenGLWindow
    {
    public:
    TestWindow();
    ~TestWindow();

    void initialize();
    void render();
    

    private:
    GLuint loadShader(GLenum type, const char *source);

    GLuint  m_posAttr;
    GLuint  m_colAttr;
    GLuint  m_matrixUniform;
    
    GLuint  m_colorMap;
    
    QOpenGLShaderProgram *m_program;
    int m_frame;
    
    GLuint tex;
    

    };@

    Code:
    @#include "testwindow.h"
    #include <QFileDialog>
    #include <QImage>

    #include <QtCore/QCoreApplication>

    #include <QtGui/QOpenGLContext>
    #include <QtGui/QOpenGLPaintDevice>
    #include <QtGui/QPainter>
    #include <GL/gl.h>

    #include <SimpleShaders.h>

    #define TEST_TEXTURE

    GLfloat TerrainVertices[]={
    1, 1,
    1, 0,
    0, 1,
    0, 0,
    -1, 1,
    -1, 0,
    };

    GLfloat TerrainColor[]={
    1, 0, 0,
    1, 0, 0,
    1, 0, 0,
    1, 0, 0,
    1, 0, 0,
    1, 0, 0,
    };

    TestWindow::TestWindow()
    : m_program(0)
    , m_frame(0)
    {
    }

    TestWindow::~TestWindow()
    {

    }

    GLuint TestWindow::loadShader(GLenum type, const char *source)
    {
    GLuint shader = glCreateShader(type);
    glShaderSource(shader, 1, &source, 0);
    glCompileShader(shader);
    return shader;
    }

    void TestWindow::initialize()
    {
    m_program = new QOpenGLShaderProgram(this);

    #ifndef TEST_TEXTURE
    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
    #else
    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, VS_TextureShader);
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, FS_TextureShader);
    #endif

    m_program->link();
    m_posAttr = m_program->attributeLocation("posAttr");
    

    #ifndef TEST_TEXTURE
    m_colAttr = m_program->attributeLocation("colAttr");
    #else
    m_colorMap = m_program->uniformLocation("colorMap");
    glEnable(GL_TEXTURE_2D);
    #endif

    m_matrixUniform = m_program->uniformLocation("matrix");
    

    }

    void TestWindow::render()
    {
    const qreal retinaScale = devicePixelRatio();
    glViewport(0, 0, width() * retinaScale, height() * retinaScale);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    m_program->bind();
    

    //Camera view
    QMatrix4x4 matrix;
    matrix.perspective(60, 4.0/3.0, 0.1, 100.0);
    matrix.translate(0, 0, -3);
    matrix.rotate(10.0f * m_frame / screen()->refreshRate(), 0, 1, 0);

    m_program->setUniformValue(m_matrixUniform, matrix);
    
    
    glEnableVertexAttribArray(m_colAttr);
    glEnableVertexAttribArray(m_posAttr);
    

    #ifndef TEST_TEXTURE
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, TerrainColor);
    #endif
    glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, TerrainVertices);

    #ifdef TEST_TEXTURE
    glUniform1i(m_colorMap, 0);
    glActiveTexture(GL_TEXTURE0+0);
    glBindTexture(GL_TEXTURE_2D,tex);
    GLuint sampler;
    glGenSamplers(1,&sampler);
    glBindSampler(0,sampler);

    uchar pixels[2*2*4]={255,000,000,255,   000,255,000,255,
                         000,000,255,255,   255,255,255,255};
    
    glTexImage2D(GL_TEXTURE_2D, 0, 4, 2, 2, 0, GL_RGBA,GL_UNSIGNED_BYTE, (const GLvoid *)pixels);
    

    #endif

    glDrawArrays(GL_QUAD_STRIP, 0, 6);
    

    #ifdef TEST_TEXTURE
    glDeleteSamplers(1,&sampler);
    glDeleteTextures(1,&tex);
    #endif

    glDisableVertexAttribArray(m_colAttr);
    glDisableVertexAttribArray(m_posAttr);
    
    m_program->release();
    
    ++m_frame;
    

    }@

    Shaders:
    @static const char* vertexShaderSource =
    "attribute highp vec4 posAttr;\n"
    "attribute lowp vec4 colAttr;\n"
    "varying lowp vec4 col;\n"
    "uniform highp mat4 matrix;\n"
    "void main() {\n"
    " col = colAttr;\n"
    " gl_Position = matrix * posAttr;\n"
    "}\n";

    static const char* fragmentShaderSource =
    "varying lowp vec4 col;\n"
    "void main() {\n"
    " gl_FragColor = col;\n"
    "}\n";

    static const char* VS_TextureShader =
    "attribute highp vec4 posAttr;\n"
    "uniform highp mat4 matrix;\n"
    "void main() {\n"
    " gl_TexCoord[0] = gl_MultiTexCoord0;\n"
    " gl_Position = matrix * posAttr;\n"
    "}\n";

    static const char* FS_TextureShader =
    "uniform sampler2D colorMap;\n"
    "void main (void){\n"
    "gl_FragColor = texture( colorMap, gl_TexCoord[0].st);}";@

    If i define TEST_TEXTURE (to switch from colors to textures) all i get is a black/empty window, while it works without a problem when using colors.

    What am i missing? Or is there a better approach to use OpenGL with Qt?

    If you want to test the code yourself, you have change the openglwindow, instead of inheriting from QOpenGLFunctions it has to be QOpenGLFunctions_4_0_Core.



  • I'm still facing the same problem:

    I've worked on my functions but it's doesn't work:

    @float texPos[8]={1,1, 0,1,
    0,0, 1,0};@

    Initialisation:
    @m_program = new QOpenGLShaderProgram(this);
    const char *vsrc =
    "attribute highp vec4 vertex;\n"
    "attribute mediump vec4 texCoord;\n"
    "varying mediump vec4 texc;\n"
    "uniform mediump mat4 matrix;\n"
    "void main(void)\n"
    "{\n"
    " gl_Position = matrix * vertex;\n"
    " texc = texCoord;\n"
    "}\n";

    const char *fsrc =
    "uniform sampler2D texture;\n"
    "varying mediump vec4 texc;\n"
    "void main(void)\n"
    "{\n"
    " gl_FragColor = texture2D(texture, texc.st);\n"
    "}\n";

    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex,vsrc);
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment,fsrc);
    m_program->link();
    m_posAttr = m_program->attributeLocation("vertex");
    m_texPos = m_program->attributeLocation("texCoord");

    m_program->setUniformValue("texture", 0);

    m_colorMap = QGLContext::fromOpenGLContext(m_context)->bindTexture(QPixmap(QString("skybox01.png")), GL_TEXTURE_2D);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);@

    Rendering:
    @const qreal retinaScale = devicePixelRatio();
    glViewport(0, 0, width() * retinaScale, height() * retinaScale);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    m_program->bind();

    //Camera view
    QMatrix4x4 matrix;
    matrix.perspective(60, 4.0/3.0, 0.1, 100.0);
    matrix.translate(0, 0, -3);
    matrix.rotate(10.0f * m_frame / screen()->refreshRate(), 0, 1, 0);

    m_program->setUniformValue(m_matrixUniform, matrix);
    glEnableVertexAttribArray(m_posAttr);
    glEnableVertexAttribArray(m_texPos);
    glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, TerrainVertices);
    glVertexAttribPointer(m_texPos, 2, GL_FLOAT, GL_FALSE, 0, texPos);

    glBindTexture(GL_TEXTURE_2D, m_colorMap);
    glDrawArrays(GL_QUAD_STRIP, 0, 6);

    glDisableVertexAttribArray(m_posAttr);
    glDisableVertexAttribArray(m_texPos);

    m_program->release();

    ++m_frame;@

    I still seem to be missing something.



  • Hi,

    your texture is never created because you never call glGenTextures() for TestWindow::tex. Your code is a bit complicated for what you're intending to do because of copy/pastes from the examples you found, so it is very difficult to read. You should remove the OpenGL samplers, you don't need them -- be careful, I'm speaking about the samplers in your c++ code, not in the GLSL -- and the call to glActiveTexture() -- which is only useful for multitexturing. glTexImage2D() should be called during initialization instead of rendering. When using GLSL, you should precise the version in your code, e.g. with "#version 440" for GLSL 4.4. I think this "link":http://open.gl/textures is a good tutorial you can read.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.