我是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();
}
绘制国际象棋棋盘。但它的瞬间和然后屏幕变成白色。我想连续画每一帧画画的棋盘图案。 有人可以指出可能出现的问题吗?
答案 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中实际发生的事情。