绘制一帧后,打开gl绘制变为白色

时间:2016-08-03 21:38:15

标签: c++ qt opengl

我是Opengl的新手。我使用Qt中的以下示例作为Opengl的开头,因为我知道Qt http://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-squircle-cpp.html

我用下面的代码替换了程序的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();
}

绘制国际象棋棋盘。但它的瞬间和然后屏幕变成白色。我想连续画每一帧画画的棋盘图案。 有人可以指出可能出现的问题吗?

2 个答案:

答案 0 :(得分:1)

在最顶层你有:

if (!m_program) {

然后你在最底层初始化m_program

m_program->release();

正如评论中指出的Harish相当于调用glUseProgram(0);。因此,在paint的下一次迭代中,您的着色器不受限制且无法使用。

根据文档,release();的反面是bind();所以(我不是这个类的专家)解决方案可能是在{{1}的下一次迭代中调用QOpenGLShaderProgram::bind() 1}}。

答案 1 :(得分:0)

为了将来参考,通过图形调试器(如gDEbugger)运行opengl程序是一个好主意,可以让您深入了解API中实际发生的事情。