简体   繁体   中英

use vbo , draw texture with shader, but don't show anything

I'm completely new to OpenGL and am having trouble on binding texture and shaders to VBOs works.

Here's my code.

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";

create buffers.

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());
}

initialize

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;
}

render

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;
}

I'm not sure what i am doing wrong. I tried different things with the shader but it seems it doesn't matter. in fragmentShader.

"   gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"           //it work
"   gl_FragColor = texture2D(gSampler, texCoord);\n"      //it not work

Is this a problem with the shader I'm using, or is it something else that I'm not understanding?

Either the uniform(gSampler) or attribute(texAttr) should be the reason. To verify texAttr, use this as gl_FragColor = vec4(texCoord.x,texCoord.y,0.0,1.0); if your output is in some color then there is no problem in texAttr. I don't see any coding issue for texAttr. Anyway check once.

To verify gSampler, verify the glUniform1i(m_gSampler,unit), the unit should match the value(GL_TEXTURE0) you used to bind before glDrawElement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM