2016-08-03 30 views
-1

我是Opengl的新手。我使用Qt中的以下示例作为Opengl的开始,因为我知道Qt。
http://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-squircle-cpp.htmlOpen gl draw画一圈后变成白色

我用下面的代码替换了程序的paint函数,意图绘制棋盘图案。以下不是我的程序的绘画或渲染功能

paint() 
{ 
if (!m_program) { 
    initializeOpenGLFunctions(); 

    m_program = new QOpenGLShaderProgram(); 
    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, 
             "attribute highp vec4 vertices;" 
             "varying highp vec2 coords;" 
             "void main() {" 
             " gl_Position = vertices;" 
             " coords = vertices.xy;" 
             "}"); 
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, 
             "uniform lowp float t;" 
             "varying highp vec2 coords;" 
             "void main() {" 
             " lowp float i = 1. - (pow(abs(coords.x), 4.) + pow(abs(coords.y), 4.));" 
             " i = smoothstep(t - 0.8, t + 0.8, i);" 
             " i = floor(i * 20.)/20.;" 
             " gl_FragColor = vec4(coords * .5 + .5, i, i);" 
             "}"); 

    m_program->bindAttributeLocation("vertices", 0); 
    m_program->link(); 
} 

auto width = static_cast<float>(m_viewportSize.width()); 
auto height = static_cast<float>(m_viewportSize.height()); 
auto a = 2.f/width; 
auto b = 2.f/height; 
std::vector<float> matrix = 
{ 
    a , 0, 0, 0, 
    0, -b, 0, 0, 
    0, 0, 1, 0, 
    -1, 1, 0, 1 
}; 

// Set the projection matrix 
glMatrixMode(GL_PROJECTION); 
glLoadMatrixf(matrix.data()); 

// Initialize vertices: 
std::vector<float> vertices = 
{ 
    0,  0, 
    0,  height, 
    width, height, 
    width, 0 
}; 

// Initialize colors 
std::vector<float> colors = 
{ 
    1, 0, 0, 
    0, 1, 0, 
    0, 0, 1, 
    0, 1, 1 
}; 

// Initialize texture virtice 
std::vector<float> texCoord = 
{ 
    0, 0, 
    0, 1, 
    1, 1, 
    1, 0 
}; 

// Create texture: simple chess board 8x8 
auto numRows = 8u; 
auto numCols = 8u; 
auto character = 172u; 
auto remain = 255u - character; 
std::vector<unsigned char> texture(numCols * numRows); 
for (auto i = 0u; i < texture.size(); ++i) 
    texture[i] = ((i + (i/numCols)) % 2) * remain + character; 

// Upload to GPU texture 
unsigned textureID; 
glGenTextures(1, &textureID); 
glBindTexture(GL_TEXTURE_2D, textureID); 
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_LUMINANCE, numCols, numRows, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, texture.data()); 

// Initialize clear colors 
glClearColor(0.f, 0.f, 0.f, 1.f); 
// Activate necessary states 
glEnable(GL_TEXTURE_2D); 
glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_COLOR_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
glVertexPointer(2, GL_FLOAT, 0, vertices.data()); 
glColorPointer(3, GL_FLOAT, 0, colors.data()); 
glTexCoordPointer(2, GL_FLOAT, 0, texCoord.data()); 

// render 
glClear(GL_COLOR_BUFFER_BIT); 
glDrawArrays(GL_QUADS, 0, 4); 

m_program->disableAttributeArray(0); 
m_program->release(); 
m_window->resetOpenGLState(); 
} 

棋盘是绘制的。但是,它的绘制分秒&然后屏幕变成完全白色。我想在每一帧绘制中连续绘制棋盘图案。 有人可以指出可能会出错吗?

+0

是的,看着最后5行你正在绘制一个单帧,然后你开始释放GL程序并重置窗口。 –

+0

我注释了最后3行,但没有帮助。 –

+0

为什么我的问题被投票了?它出什么问题了 ? –

回答

1

在最顶部,你有:

if (!m_program) { 

那么你初始化m_program,在最底层,你有:

m_program->release(); 

其作为哈里什在评论中指出,等效于调用glUseProgram(0);。所以在paint的下一次迭代中,着色器不会被绑定,也不可用。

根据文档的release();反过来bind();所以(我不是专家对这个类)的解决方案可能是打电话给QOpenGLShaderProgram::bind()paint的下一次迭代。

+0

'm_program-> release()'与'glUseProgram(0)'相同。它可能会导致代码中的内存泄漏,但并不是他为什么会出现白屏。请参阅链接http://doc.qt.io/qt-5/qopenglshaderprogram.html#release – Harish

+0

@Harish现在看看我的答案是否更有用 – marcinj

+0

调用绑定现在每帧连续显示数据。我还评论了addShaderFromSourceCode的调用。正如我告诉我我是一个新手,我从http://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-squircle-cpp.html复制了样本。我的目标是从我有的图像中提供自己的字符数据,并用实际图像数据(无符号字符数组)替换棋盘图案。请评论我是否在右边。这个讨论肯定对我有帮助 –

0

为了将来的参考,通过像gDEbugger这样的图形调试器来运行opengl程序是一个好主意,让您能够深入了解API内部实际发生的事情。

+0

好点@Sombero孩子。我会尝试获取gDebbugger。目前我主要想知道在API背后发生的事情 –