#include <QImage>
#include <QOpenGLBuffer>
#include <QOpenGLContext>
#include <QOpenGLFramebufferObject>
#include <QOpenGLShaderProgram>
#include <QString>
#include <QWidget>
#include <QDebug>
#include "offScreenExp.hpp"
offScreenExp::offScreenExp(QWindow *parent) :
QWindow(parent),
context_(nullptr)
{
setSurfaceType(QWindow::OpenGLSurface);
setFormat(QSurfaceFormat());
create();
}
{
//create the context
if (!context_) {
context_ = new QOpenGLContext(this);
QSurfaceFormat format;
context_->setFormat(format);
if (!context_->create())
qFatal("Cannot create the requested OpenGL context!");
}
context_->makeCurrent(this);
initializeOpenGLFunctions();
//load image
QString const prefix
("/Users/Qt/program/experiment_apps_and_libs/openGLTest/simpleGPGPU/");
QImage img
(prefix
+ "images/emili.jpg");
if(img.isNull()){
qFatal("image is null");
}
//if(glCheckFramebufferStatus(fbo.handle()) != GL_FRAMEBUFFER_COMPLETE){
// qDebug()<<"frame buffer error";
//}
qDebug()<<"has opengl fbo : "<<QOpenGLFramebufferObject::hasOpenGLFramebufferObjects();
//use two triangles two cover whole screen
std::vector<GLfloat> const vertex{
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f,
};
//initialize vbo
QOpenGLBuffer buffer(QOpenGLBuffer::VertexBuffer);
buffer.create();
buffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
buffer.bind();
buffer.allocate(&vertex[0], vertex.size() * sizeof(GLfloat) );
buffer.release();
//create texture
GLuint rendered_texture;
glGenTextures(1, &rendered_texture);
// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_2D, rendered_texture);
//naive solution, better encapsulate the format in a function
if(img.
format() == QImage::Format_Indexed8){ glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, img.width(), img.height(), 0, GL_RED, GL_UNSIGNED_BYTE, img.scanLine(0));
}else if(img.
format() == QImage::Format_RGB888){ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.width(), img.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, img.scanLine(0));
}else{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.width(), img.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, temp.scanLine(0));
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
//compile and link program
QOpenGLShaderProgram program;
if(!program.addShaderFromSourceCode(QOpenGLShader::Vertex,
"attribute highp vec4 qt_Vertex;"
"varying highp vec2 qt_TexCoord0;"
"void main(void)"
"{"
" gl_Position = qt_Vertex;"
" qt_TexCoord0 = (qt_Vertex.xy + vec2(1.0)) * 0.5;"
"}")){
qDebug()<<"QOpenGLShader::Vertex error : " + program.log();
}
// Compile fragment shader
if (!program.addShaderFromSourceCode(QOpenGLShader::Fragment,
"uniform sampler2D source;"
"varying highp vec2 qt_TexCoord0;"
"vec3 toGray(vec3 rgb)"
"{"
" return vec3(rgb.r * 0.299 + rgb.g * 0.587 + rgb.b * 0.114);"
"}"
"void main(void)"
"{"
"vec3 gray = toGray(texture2D(source, qt_TexCoord0).rgb);"
"gl_FragColor = vec4(gray, 0.0);"
"}"
)){
qDebug()<<"QOpenGLShader::Fragment error : " + program.log();
}
// Link shader pipeline
if (!program.link()){
qDebug()<<"link error : " + program.log();
}
//render the texture as usual
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, img.width(), img.height());
program.bind();
buffer.bind();
program.enableAttributeArray("qt_Vertex");
program.setAttributeBuffer( "qt_Vertex", GL_FLOAT, 0, 4);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, rendered_texture);
//bind and create fbo
QOpenGLFramebufferObject fbo(img.size());
qDebug()<<"bind success? : "<<fbo.bind();
glDrawArrays(GL_TRIANGLES, 0, buffer.size());
program.disableAttributeArray("qt_Vertex");
program.release();
glActiveTexture(0);
glBindTexture(GL_TEXTURE_2D, 0);
buffer.release();
QImage result
= fbo.
toImage();
fbo.release();
context_->doneCurrent();
return result;
}
#include <QImage>
#include <QOpenGLBuffer>
#include <QOpenGLContext>
#include <QOpenGLFramebufferObject>
#include <QOpenGLShaderProgram>
#include <QString>
#include <QWidget>
#include <QDebug>
#include "offScreenExp.hpp"
offScreenExp::offScreenExp(QWindow *parent) :
QWindow(parent),
context_(nullptr)
{
setSurfaceType(QWindow::OpenGLSurface);
setFormat(QSurfaceFormat());
create();
}
QImage offScreenExp::render()
{
//create the context
if (!context_) {
context_ = new QOpenGLContext(this);
QSurfaceFormat format;
context_->setFormat(format);
if (!context_->create())
qFatal("Cannot create the requested OpenGL context!");
}
context_->makeCurrent(this);
initializeOpenGLFunctions();
//load image
QString const prefix("/Users/Qt/program/experiment_apps_and_libs/openGLTest/simpleGPGPU/");
QImage img(prefix + "images/emili.jpg");
if(img.isNull()){
qFatal("image is null");
}
//if(glCheckFramebufferStatus(fbo.handle()) != GL_FRAMEBUFFER_COMPLETE){
// qDebug()<<"frame buffer error";
//}
qDebug()<<"has opengl fbo : "<<QOpenGLFramebufferObject::hasOpenGLFramebufferObjects();
//use two triangles two cover whole screen
std::vector<GLfloat> const vertex{
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f,
};
//initialize vbo
QOpenGLBuffer buffer(QOpenGLBuffer::VertexBuffer);
buffer.create();
buffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
buffer.bind();
buffer.allocate(&vertex[0], vertex.size() * sizeof(GLfloat) );
buffer.release();
//create texture
GLuint rendered_texture;
glGenTextures(1, &rendered_texture);
// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_2D, rendered_texture);
//naive solution, better encapsulate the format in a function
if(img.format() == QImage::Format_Indexed8){
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, img.width(), img.height(), 0, GL_RED, GL_UNSIGNED_BYTE, img.scanLine(0));
}else if(img.format() == QImage::Format_RGB888){
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.width(), img.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, img.scanLine(0));
}else{
QImage temp = img.convertToFormat(QImage::Format_RGB888);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.width(), img.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, temp.scanLine(0));
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
//compile and link program
QOpenGLShaderProgram program;
if(!program.addShaderFromSourceCode(QOpenGLShader::Vertex,
"attribute highp vec4 qt_Vertex;"
"varying highp vec2 qt_TexCoord0;"
"void main(void)"
"{"
" gl_Position = qt_Vertex;"
" qt_TexCoord0 = (qt_Vertex.xy + vec2(1.0)) * 0.5;"
"}")){
qDebug()<<"QOpenGLShader::Vertex error : " + program.log();
}
// Compile fragment shader
if (!program.addShaderFromSourceCode(QOpenGLShader::Fragment,
"uniform sampler2D source;"
"varying highp vec2 qt_TexCoord0;"
"vec3 toGray(vec3 rgb)"
"{"
" return vec3(rgb.r * 0.299 + rgb.g * 0.587 + rgb.b * 0.114);"
"}"
"void main(void)"
"{"
"vec3 gray = toGray(texture2D(source, qt_TexCoord0).rgb);"
"gl_FragColor = vec4(gray, 0.0);"
"}"
)){
qDebug()<<"QOpenGLShader::Fragment error : " + program.log();
}
// Link shader pipeline
if (!program.link()){
qDebug()<<"link error : " + program.log();
}
//render the texture as usual
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, img.width(), img.height());
program.bind();
buffer.bind();
program.enableAttributeArray("qt_Vertex");
program.setAttributeBuffer( "qt_Vertex", GL_FLOAT, 0, 4);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, rendered_texture);
//bind and create fbo
QOpenGLFramebufferObject fbo(img.size());
qDebug()<<"bind success? : "<<fbo.bind();
glDrawArrays(GL_TRIANGLES, 0, buffer.size());
program.disableAttributeArray("qt_Vertex");
program.release();
glActiveTexture(0);
glBindTexture(GL_TEXTURE_2D, 0);
buffer.release();
QImage result = fbo.toImage();
fbo.release();
context_->doneCurrent();
return result;
}
To copy to clipboard, switch view to plain text mode
Bookmarks