QOpenGLWidget and Setviewport to QGraphicsView are not working with glsl
-
Hi. there
I'm working on drawing image(texture) to QGraphicsView
and I want to put on some QGraphicsItem(rect or etc...) to QGraphicsView
I already use the follow codes applied to my code
CGraphicsView *view = new CGraphicsView(); //subclassed by QGraphicsView CGraphicsScene *scene = new CGraphicsScene();//subclassed by QGraphicsScene view->setScene(scene); view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); view->setViewport(new QOpenGLWidget()); view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); view->setFrameStyle(0); view->showFullScreen();
generally on my pc (QT 5.5.1 msvc 2012 32bit) it is working
but to my android phone(opengl es 3.0, glsl es 3.00)
screen was simply filled by blue color which i was cleared like below.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);but QGraphicsItem is working fine.
i think shader is not working so texture is not on screen.
please help me. thanks ;)
following codes are rendering part of my code and called like below
void CGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect)
{
painter->beginNativePainting();
if(false == m_pRenderer->IsGLReady())
m_pRenderer->init();
m_pRenderer->renderA(rect.width(), rect.height());
}// CPP /////////////////////////////////////////// #include <QMessageBox> #include <QFile> #include "GLRenderer.h" CGLRenderer::CGLRenderer(void) { m_bIsInitialized = false; } CGLRenderer::~CGLRenderer(void) { } void CGLRenderer::init() { //initializeGLFunctions(); initializeOpenGLFunctions(); m_pImage = new QImage(); *m_pImage = QGLWidget::convertToGLFormat(QImage(":/test.jpg", "JPG")); int m_dWidth = m_pImage->width(); int m_dHeight = m_pImage->height(); m_VertHandle = initShaderObj(":/vshader.glsl", GL_VERTEX_SHADER); m_FragHandle = initShaderObj(":/fshader.glsl", GL_FRAGMENT_SHADER); m_dProgramHandle = glCreateProgram(); if(!m_dProgramHandle) { QMessageBox::warning(this, tr(""),tr("shader program error"),QMessageBox::Cancel,QMessageBox::Save); exit(EXIT_FAILURE); } VertexData vertices[] = { {QVector2D(0.0, 0.0), QVector2D(0.0, 0.0)}, // v0 {QVector2D(m_dWidth, 0.0), QVector2D(1.0, 0.0)}, // v1 {QVector2D(0.0, m_dHeight), QVector2D(0.0, 1.0)}, // v2 {QVector2D(m_dWidth, m_dHeight), QVector2D(1.0, 1.0)}, // v3 }; GLushort indices[] = { 0, 1, 2, 3 }; glGenBuffers(2, gbo); // Transfer vertex data to VBO 0 glBindBuffer(GL_ARRAY_BUFFER, gbo[0]); glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(VertexData), vertices, GL_STATIC_DRAW); // Transfer index data to VBO 1 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gbo[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLushort), indices, GL_STATIC_DRAW); m_dTexObj = init2DTex(m_pImage); m_bIsInitialized = true; } GLuint CGLRenderer::initShaderObj(const GLchar* srcfile, GLenum shaderType) { setlocale(LC_NUMERIC, "C"); QFile file(srcfile); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox::warning(this, tr(""),tr("shader error"),QMessageBox::Cancel,QMessageBox::Save); return 0; } QByteArray shaderCode; while(!file.atEnd()) { shaderCode.push_back(file.readLine()); } GLuint shader = glCreateShader(shaderType); if(!shader) { glGetError(); QMessageBox::warning(this, tr(""),tr("vertex shader error"),QMessageBox::Cancel,QMessageBox::Save); } const GLchar *codeArray[] = {shaderCode.data()}; // codeArray[shaderCode.size()] = '\0'; glShaderSource(shader, 1, codeArray, NULL); glCompileShader(shader); setlocale(LC_ALL, ""); return shader; } GLuint CGLRenderer::init2DTex(QImage *image) { GLuint dTex; glGenTextures(1, &dTex); glBindTexture(GL_TEXTURE_2D, dTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->width(), image->height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image->bits()); return dTex; } void CGLRenderer::linkShader(GLuint shaderPgm, GLuint newVertHandle, GLuint newFragHandle) { const GLsizei maxCount = 2; GLsizei count; GLuint shaders[maxCount]; glGetAttachedShaders(shaderPgm, maxCount, &count, shaders); for(int i=0; i<count; i++) glDetachShader(shaderPgm, shaders[i]); glAttachShader(shaderPgm, newVertHandle); glAttachShader(shaderPgm, newFragHandle); glLinkProgram(shaderPgm); } #include <qgl.h> #include <QGLWidget> #include <qopengl.h> #include <qopenglfunctions.h> void CGLRenderer::renderA(int dWidth, int dHeight) { QRect rect = QRect(0, 0, dWidth, dHeight); if(dWidth == 0 || dHeight == 0) return; int BmpWidth = WIDTHBYTES(m_pImage->width() * 8); int BmpHeight = m_pImage->height(); if((rect.width() - BmpWidth) <= (rect.height() - BmpHeight)) { rect.setTop(rect.top() + (rect.height() - (rect.width() * BmpHeight ) / BmpWidth) / 2); rect.setBottom(rect.top() + (rect.width() * BmpHeight ) / BmpWidth); }else{ rect.setLeft(rect.left() + (rect.width() - (rect.height() * BmpWidth ) / BmpHeight) / 2); rect.setRight(rect.left() + (rect.height() * BmpWidth ) / BmpHeight); } glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //initVBO(); glEnable(GL_DEPTH_TEST); glViewport(rect.left(), rect.top(), rect.width(), rect.height()); linkShader(m_dProgramHandle, m_VertHandle, m_FragHandle); glUseProgram(m_dProgramHandle); GLint TexLoc = glGetUniformLocation(m_dProgramHandle, "texture"); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, m_dTexObj); glUniform1i(TexLoc, 1); projection.setToIdentity(); projection.ortho(-0.0f, (GLfloat)m_pImage->width(), -0.0f, (GLfloat)m_pImage->height(), -32768.0f, 32767.0f); GLint MatrixLoc = glGetUniformLocation(m_dProgramHandle, "mvp_matrix"); glUniformMatrix4fv(MatrixLoc, 1, GL_FALSE, projection.data()); ////////////////////////////////////////////////////////////////////////// // Tell OpenGL which VBOs to use glBindBuffer(GL_ARRAY_BUFFER, gbo[0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gbo[1]); // Offset for position quintptr offset = 0; // Tell OpenGL programmable pipeline how to locate vertex position data int vertexLocation = glGetAttribLocation(m_dProgramHandle, "a_position"); glEnableVertexAttribArray(vertexLocation); glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void *)offset); // Offset for texture coordinate offset += sizeof(QVector2D); // Tell OpenGL programmable pipeline how to locate vertex texture coordinate data int texcoordLocation = glGetAttribLocation(m_dProgramHandle, "a_texcoord"); glEnableVertexAttribArray(texcoordLocation); glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void *)offset); // Draw cube geometry using indices from VBO 1 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0); // CPP /////////////////////////////////////////// #include <QMessageBox> #include <QFile> #include "GLRenderer.h" CGLRenderer::CGLRenderer(void) { m_bIsInitialized = false; } CGLRenderer::~CGLRenderer(void) { } void CGLRenderer::init() { //initializeGLFunctions(); initializeOpenGLFunctions(); m_pImage = new QImage(); *m_pImage = QGLWidget::convertToGLFormat(QImage(":/test.jpg", "JPG")); int m_dWidth = m_pImage->width(); int m_dHeight = m_pImage->height(); m_VertHandle = initShaderObj(":/vshader.glsl", GL_VERTEX_SHADER); m_FragHandle = initShaderObj(":/fshader.glsl", GL_FRAGMENT_SHADER); m_dProgramHandle = glCreateProgram(); if(!m_dProgramHandle) { QMessageBox::warning(this, tr(""),tr("shader program error"),QMessageBox::Cancel,QMessageBox::Save); exit(EXIT_FAILURE); } VertexData vertices[] = { {QVector2D(0.0, 0.0), QVector2D(0.0, 0.0)}, // v0 {QVector2D(m_dWidth, 0.0), QVector2D(1.0, 0.0)}, // v1 {QVector2D(0.0, m_dHeight), QVector2D(0.0, 1.0)}, // v2 {QVector2D(m_dWidth, m_dHeight), QVector2D(1.0, 1.0)}, // v3 }; GLushort indices[] = { 0, 1, 2, 3 }; glGenBuffers(2, gbo); // Transfer vertex data to VBO 0 glBindBuffer(GL_ARRAY_BUFFER, gbo[0]); glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(VertexData), vertices, GL_STATIC_DRAW); // Transfer index data to VBO 1 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gbo[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLushort), indices, GL_STATIC_DRAW); m_dTexObj = init2DTex(m_pImage); m_bIsInitialized = true; } GLuint CGLRenderer::initShaderObj(const GLchar* srcfile, GLenum shaderType) { setlocale(LC_NUMERIC, "C"); QFile file(srcfile); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox::warning(this, tr(""),tr("shader error"),QMessageBox::Cancel,QMessageBox::Save); return 0; } QByteArray shaderCode; while(!file.atEnd()) { shaderCode.push_back(file.readLine()); } GLuint shader = glCreateShader(shaderType); if(!shader) { glGetError(); QMessageBox::warning(this, tr(""),tr("vertex shader error"),QMessageBox::Cancel,QMessageBox::Save); } const GLchar *codeArray[] = {shaderCode.data()}; // codeArray[shaderCode.size()] = '\0'; glShaderSource(shader, 1, codeArray, NULL); glCompileShader(shader); setlocale(LC_ALL, ""); return shader; } GLuint CGLRenderer::init2DTex(QImage *image) { GLuint dTex; glGenTextures(1, &dTex); glBindTexture(GL_TEXTURE_2D, dTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->width(), image->height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image->bits()); return dTex; } void CGLRenderer::linkShader(GLuint shaderPgm, GLuint newVertHandle, GLuint newFragHandle) { const GLsizei maxCount = 2; GLsizei count; GLuint shaders[maxCount]; glGetAttachedShaders(shaderPgm, maxCount, &count, shaders); for(int i=0; i<count; i++) glDetachShader(shaderPgm, shaders[i]); glAttachShader(shaderPgm, newVertHandle); glAttachShader(shaderPgm, newFragHandle); glLinkProgram(shaderPgm); } #include <qgl.h> #include <QGLWidget> #include <qopengl.h> #include <qopenglfunctions.h> void CGLRenderer::renderA(int dWidth, int dHeight) { QRect rect = QRect(0, 0, dWidth, dHeight); if(dWidth == 0 || dHeight == 0) return; int BmpWidth = WIDTHBYTES(m_pImage->width() * 8); int BmpHeight = m_pImage->height(); if((rect.width() - BmpWidth) <= (rect.height() - BmpHeight)) { rect.setTop(rect.top() + (rect.height() - (rect.width() * BmpHeight ) / BmpWidth) / 2); rect.setBottom(rect.top() + (rect.width() * BmpHeight ) / BmpWidth); }else{ rect.setLeft(rect.left() + (rect.width() - (rect.height() * BmpWidth ) / BmpHeight) / 2); rect.setRight(rect.left() + (rect.height() * BmpWidth ) / BmpHeight); } glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //initVBO(); glEnable(GL_DEPTH_TEST); glViewport(rect.left(), rect.top(), rect.width(), rect.height()); linkShader(m_dProgramHandle, m_VertHandle, m_FragHandle); glUseProgram(m_dProgramHandle); GLint TexLoc = glGetUniformLocation(m_dProgramHandle, "texture"); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, m_dTexObj); glUniform1i(TexLoc, 1); projection.setToIdentity(); projection.ortho(-0.0f, (GLfloat)m_pImage->width(), -0.0f, (GLfloat)m_pImage->height(), -32768.0f, 32767.0f); GLint MatrixLoc = glGetUniformLocation(m_dProgramHandle, "mvp_matrix"); glUniformMatrix4fv(MatrixLoc, 1, GL_FALSE, projection.data()); ////////////////////////////////////////////////////////////////////////// // Tell OpenGL which VBOs to use glBindBuffer(GL_ARRAY_BUFFER, gbo[0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gbo[1]); // Offset for position quintptr offset = 0; // Tell OpenGL programmable pipeline how to locate vertex position data int vertexLocation = glGetAttribLocation(m_dProgramHandle, "a_position"); glEnableVertexAttribArray(vertexLocation); glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void *)offset); // Offset for texture coordinate offset += sizeof(QVector2D); // Tell OpenGL programmable pipeline how to locate vertex texture coordinate data int texcoordLocation = glGetAttribLocation(m_dProgramHandle, "a_texcoord"); glEnableVertexAttribArray(texcoordLocation); glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (const void *)offset); // Draw cube geometry using indices from VBO 1 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0); glUseProgram(0); glFlush(); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisable(GL_DEPTH_TEST); } // END OF CPP /////////////////////////////////////////// // HEADER /////////////////////////////////////////// #pragma once #include <QGLFunctions> #include <QOpenGLFunctions> #include <QImage> #include <QMatrix4x4> #include <QVector2D> #define WIDTHBYTES(bits) ((bits+31)/32*4) struct VertexData { QVector2D position; QVector2D texCoord; }; #include <QOpenGLWidget> class CGLRenderer : public QWidget, protected QOpenGLFunctions { Q_OBJECT public: CGLRenderer(void); ~CGLRenderer(void); void init(); bool IsGLReady() {return m_bIsInitialized;} void renderA(int dWidth, int dHeight); protected: GLuint init2DTex(QImage *image); GLuint initShaderObj(const GLchar* srcfile, GLenum shaderType); void linkShader(GLuint shaderPgm, GLuint newVertHandle, GLuint newFragHandle); protected: bool m_bIsInitialized; QImage *m_pImage; GLfloat m_fZoomRatio; GLuint m_dTexObj; GLuint m_dProgramHandle; GLuint m_VertHandle; GLuint m_FragHandle; QMatrix4x4 projection; GLuint gbo[2]; }; // END OF HEADER /////////////////////////////////////////// glUseProgram(0); glFlush(); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisable(GL_DEPTH_TEST); } // END OF CPP /////////////////////////////////////////// // HEADER /////////////////////////////////////////// #pragma once #include <QGLFunctions> #include <QOpenGLFunctions> #include <QImage> #include <QMatrix4x4> #include <QVector2D> #define WIDTHBYTES(bits) ((bits+31)/32*4) struct VertexData { QVector2D position; QVector2D texCoord; }; #include <QOpenGLWidget> class CGLRenderer : public QWidget, protected QOpenGLFunctions { Q_OBJECT public: CGLRenderer(void); ~CGLRenderer(void); void init(); bool IsGLReady() {return m_bIsInitialized;} void renderA(int dWidth, int dHeight); protected: GLuint init2DTex(QImage *image); GLuint initShaderObj(const GLchar* srcfile, GLenum shaderType); void linkShader(GLuint shaderPgm, GLuint newVertHandle, GLuint newFragHandle); protected: bool m_bIsInitialized; QImage *m_pImage; GLfloat m_fZoomRatio; GLuint m_dTexObj; GLuint m_dProgramHandle; GLuint m_VertHandle; GLuint m_FragHandle; QMatrix4x4 projection; GLuint gbo[2]; }; // END OF HEADER ///////////////////////////////////////////