我是OpenGL的新手,在将纹理和着色器绑定到VBO时遇到了麻烦。
这是我的代码。
static const char *vertexShaderSource =
"attribute highp vec3 posAttr;\n"
"attribute highp vec2 texAttr;\n"
"varying highp vec2 texCoord;\n"
"uniform highp mat4 matrix;\n"
"void main() {\n"
" texCoord = texAttr;\n"
" gl_Position = matrix * vec4(posAttr, 1.0);\n"
"}\n";
static const char *fragmentShaderSource =
"varying highp vec2 texCoord;\n"
"uniform sampler2D gSampler;\n"
"void main() {\n"
//" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" //it work
" gl_FragColor = texture2D(gSampler, texCoord);\n" //it not work
"}\n";
创建缓冲区。
void TriangleWindow::createVertexBuffer()
{
GLfloat vertices[] = {
1.0f,1.0f,0.0f, 0.0f,0.0f,
0.0f,1.0f,1.0f, 0.5f,0.0f,
1.0f,0.0f,1.0f, 1.0f,0.0f,
0.5f,0.0f,0.0f, 0.5f,1.0f
};
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
qDebug()<<"sizeof(vertices) is "<<sizeof(vertices);
}
void TriangleWindow::createIndexBuffer()
{
GLuint indexs[] = {
0,1,3,
0,2,1,
0,3,2,
1,3,2
};
glGenBuffers(1, &m_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexs), indexs, GL_STATIC_DRAW);
qDebug()<<"sizeof(indexs) is "<<sizeof(indexs);
}
void TriangleWindow::createTextureBuffer()
{
QString resPath = "/Users/luxiaodong/Project/Demo/OpenGLES/res";
QString imgPath = QString("%1/test.png").arg(resPath);
qDebug()<<imgPath;
QImage image = QImage(imgPath).convertToFormat( QImage::Format_RGBA8888 );
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glGenTextures(1, &m_tex);
glBindTexture(GL_TEXTURE_2D, m_tex);
glTexParameterf(m_tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(m_tex, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(m_tex, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)image.bits() );
//glTexImage2D(GL_TEXTURE_2D, 0, 4, image.width(), image.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
}
初始化
void TriangleWindow::initialize()
{
createVertexBuffer();
createIndexBuffer();
createTextureBuffer();
m_program = new QOpenGLShaderProgram(this);
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
m_program->link();
m_posAttr = m_program->attributeLocation("posAttr");
m_texAttr = m_program->attributeLocation("texAttr");
m_matrixUniform = m_program->uniformLocation("matrix");
m_gSampler = m_program->uniformLocation("gSampler");
m_program->setUniformValue(m_gSampler, 0);
qDebug()<<m_posAttr<<m_texAttr<<m_matrixUniform<<m_gSampler;
}
渲染
void TriangleWindow::render()
{
const qreal retinaScale = devicePixelRatio();
glViewport(0, 0, width() * retinaScale, height() * retinaScale);
glClear(GL_COLOR_BUFFER_BIT);
m_program->bind();
QMatrix4x4 matrix;
matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);
matrix.translate(0, 0, -4);
matrix.rotate(100.0f * m_frame/screen()->refreshRate(), 0, 1, 0);
m_program->setUniformValue(m_matrixUniform, matrix);
m_program->setUniformValue(m_gSampler, 0);
glEnableVertexAttribArray(m_posAttr);
glEnableVertexAttribArray(m_texAttr);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 20, (const GLvoid*)0);
glVertexAttribPointer(m_texAttr, 2, GL_FLOAT, GL_FALSE, 20, (const GLvoid*)12);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_tex);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (const GLvoid*)0 );
glDisableVertexAttribArray(m_texAttr);
glDisableVertexAttribArray(m_posAttr);
m_program->release();
++m_frame;
}
我不确定自己在做什么错。我尝试使用着色器进行了其他操作,但这似乎无关紧要。在fragmentShader中。
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" //it work
" gl_FragColor = texture2D(gSampler, texCoord);\n" //it not work
这是我正在使用的着色器的问题,还是我不了解的其他问题?
最佳答案
统一(gSampler)或属性(texAttr)应该是原因。要验证texAttr,请将此用作gl_FragColor = vec4(texCoord.x,texCoord.y,0.0,1.0);
如果您的输出为某种颜色,则texAttr中没有问题。我看不到texAttr的任何编码问题。无论如何要检查一次。
要验证gSampler,请验证glUniform1i(m_gSampler,unit),该单位应与glDrawElement之前用于绑定的值(GL_TEXTURE0)相匹配。