Unsolved How to update a scene on a QQuickItem which renders OpenGL?
-
In order to use OpenGL with QML, I created
OpenGlVideoQtQuick
which is aQQuickItem
andOpenGlVideoQtQuickRenderer
which isQObject
andQOpenGLFunctions
exactly as described here. The only difference is that I added theupdateData()
function to update the buffers, while in the example a static image is drawn in the screen.Here's the crucial part of
OpenGlVideoQtQuickRenderer
, which is thepaint
functionvoid OpenGlVideoQtQuickRenderer::paint() { if (this->firstRun) { this->firstRun = false; //qDebug() << "initializeGL"; std::cout << "initializing gl" << std::endl; //初始化opengl (QOpenGLFunctions继承)函数 initializeOpenGLFunctions(); //this->m_F = QOpenGLContext::currentContext()->functions(); //program加载shader(顶点和片元)脚本 //片元(像素) std::cout << program.addShaderFromSourceCode(QOpenGLShader::Fragment, tString2) << std::endl; //顶点shader std::cout << program.addShaderFromSourceCode(QOpenGLShader::Vertex, vString2) << std::endl; //设置顶点坐标的变量 program.bindAttributeLocation("vertexIn",A_VER); //设置材质坐标 program.bindAttributeLocation("textureIn",T_VER); //编译shader std::cout << "program.link() = " << program.link() << std::endl; } program.bind(); //传递顶点和材质坐标 //顶点 static const GLfloat ver[] = { -1.0f,-1.0f, 1.0f,-1.0f, -1.0f, 1.0f, 1.0f,1.0f }; //材质 static const GLfloat tex[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f }; //顶点 glVertexAttribPointer(A_VER, 2, GL_FLOAT, 0, 0, ver); glEnableVertexAttribArray(A_VER); //材质 glVertexAttribPointer(T_VER, 2, GL_FLOAT, 0, 0, tex); glEnableVertexAttribArray(T_VER); //glUseProgram(&program); //从shader获取材质 unis[0] = program.uniformLocation("tex_y"); unis[1] = program.uniformLocation("tex_u"); unis[2] = program.uniformLocation("tex_v"); //创建材质 glGenTextures(3, texs); //Y glBindTexture(GL_TEXTURE_2D, texs[0]); //放大过滤,线性插值 GL_NEAREST(效率高,但马赛克严重) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //创建材质显卡空间 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, 0); //U glBindTexture(GL_TEXTURE_2D, texs[1]); //放大过滤,线性插值 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //创建材质显卡空间 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width/2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0); //V glBindTexture(GL_TEXTURE_2D, texs[2]); //放大过滤,线性插值 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //创建材质显卡空间 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width / 2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0); ///分配材质内存空间 datas[0] = new unsigned char[width*height]; //Y datas[1] = new unsigned char[width*height/4]; //U datas[2] = new unsigned char[width*height/4]; //V glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texs[0]); //0层绑定到Y材质 //修改材质内容(复制内存内容) glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, datas[0]); //与shader uni遍历关联 glUniform1i(unis[0], 0); glActiveTexture(GL_TEXTURE0+1); glBindTexture(GL_TEXTURE_2D, texs[1]); //1层绑定到U材质 //修改材质内容(复制内存内容) glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width/2, height / 2, GL_RED, GL_UNSIGNED_BYTE, datas[1]); //与shader uni遍历关联 glUniform1i(unis[1],1); glActiveTexture(GL_TEXTURE0+2); glBindTexture(GL_TEXTURE_2D, texs[2]); //2层绑定到V材质 //修改材质内容(复制内存内容) glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RED, GL_UNSIGNED_BYTE, datas[2]); //与shader uni遍历关联 glUniform1i(unis[2], 2); glDrawArrays(GL_TRIANGLE_STRIP,0,4); //this->update(); // Not strictly needed for this example, but generally useful for when // mixing with raw OpenGL. m_window->resetOpenGLState();//COMMENT OR NOT? }
This is the function I'm using to update the buffers that are meant to be painted:
void OpenGlVideoQtQuickRenderer::updateData(unsigned char**data) { std::cout << "updating data..." << std::endl; memcpy(datas[0], data[0], width*height); memcpy(datas[1], data[1], width*height/4); memcpy(datas[2], data[2], width*height/4); //I should update something here }
My only problem is that I see the function updateData being called with new data, so the buffers are being updated. However, the screen continues in its initial position (green). I'm sure there must be a function I must call to update everything.
Is there anything more I need to call in
updateData
?Here's the entire code if someone wants to take a look: https://github.com/lucaszanella/orwell/blob/2aff3b97abd88e6ec2980856718e1c8302d41616/OpenGlVideoQtQuick.cpp#L117
I've tried every way of updating, but it wont work