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 ///////////////////////////////////////////
    


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