2015-04-04 98 views
1

我完全不熟悉OpenGL,并且无法将纹理和着色器绑定到VBO。使用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 

这是我使用的着色器的问题,还是我不明白的其他东西?

+0

为什么你在glVertexAttribPointer中使用20作为步幅? – VivekParamasivam 2015-04-05 08:19:51

+0

该向量包含XYZ和UV,因此步幅为20. – shadow 2015-04-05 08:34:06

回答

0

统一(gSampler)或属性(texAttr)应该是原因。要验证texAttr,如果您的输出是某种颜色,那么将其用作 gl_FragColor = vec4(texCoord.x,texCoord.y,0.0,1.0); 然后在texAttr中没有问题。我没有看到texAttr的任何编码问题。无论如何检查一次。

要验证gSampler,验证glUniform1i(m_gSampler,unit),单位应该匹配您在glDrawElement之前绑定的值(GL_TEXTURE0)。

+0

我使用'gl_FragColor = vec4(texCoord.x,texCoord.y,0.0,1.0);'它可以工作。 – shadow 2015-04-05 10:06:36

+0

我不知道如何在函数'glUniform1i(m_gSampler,unit)'中设置单位以匹配值(GL_TEXTURE0)。这里我设置0,我认为0匹配GL_TEXTURE0,1匹配GL_TEXTURE1,依此类推 – shadow 2015-04-05 10:14:34