ich versuche mich gerade an meinem ersten Projekt in Qt. Ich möchte nun eine einfache Ebene rendern, auf die ich auch eine Textur spannen kann. Zudem möchte ich die Shader selbst schreiben, d.h. die Vertices und Texturcoords müssen dort ebenfalls verfügbar sein.
Ich habe als Grundlage zunächst mit dem Beispiel HelloGL begonnen und mir versucht aus "Cube OpenGL ES 2.0 example" ein paar Sachen zusammenzuklauen... bisher nicht mit dem richtigen Erfolg. Nun, hier mal die entscheidenden Codestellen:
Das wurde nur leicht angepasst..
Code: Alles auswählen
void GLWidget::initializeGL()
{
qglClearColor(qtPurple.dark());
//logo = new QtLogo(this, 64);
//logo->setColor(qtGreen.dark());
initShaders();
initGeometry();
glEnable(GL_DEPTH_TEST);
//glEnable(GL_CULL_FACE);
//glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_MULTISAMPLE);
static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
}Code: Alles auswählen
void GLWidget::initShaders()
{
// Overriding system locale until shaders are compiled
setlocale(LC_NUMERIC, "C");
// Compiling vertex shader
if (!program->addShaderFromSourceFile(QGLShader::Vertex, ":/vshader.glsl"))
close();
// Compiling fragment shader
if (!program->addShaderFromSourceFile(QGLShader::Fragment, ":/fshader.glsl"))
close();
// Linking shader pipeline
if (!program->link())
close();
// Binding shader pipeline for use
if (!program->bind())
close();
// Restore system locale
setlocale(LC_ALL, "");
//vertArr_loc = program->attributeLocation("a_position");
//mvpMat_loc = program->uniformLocation("mvp_matrix");
}Code: Alles auswählen
void GLWidget::initGeometry(){
VertexData vertices[] = {
// Vertex data for face 0
{QVector3D(-1.0, -1.0, 0.0), QVector2D(0.0, 0.0)}, // v0
{QVector3D( 1.0, -1.0, 0.0), QVector2D(1.0, 0.0)}, // v1
{QVector3D(-1.0, 1.0, 0.0), QVector2D(0.0, 1.0)}, // v2
{QVector3D( 1.0, 1.0, 0.0), QVector2D(1.0, 1.0)}, // v3
};
GLushort indices[] = {
0, 1, 2, 3
};
vertexBuffer = QGLBuffer();
vertexBuffer.create();
vertexBuffer.allocate(vertices, sizeof(VertexData) * 4);
indexBuffer = QGLBuffer(QGLBuffer::IndexBuffer);
indexBuffer.create();
indexBuffer.allocate(indices, sizeof(GLushort) * 4);
}Code: Alles auswählen
void GLWidget::resizeGL(int w, int h)
{
// Set OpenGL viewport to cover whole widget
glViewport(0, 0, w, h);
// Calculate aspect ratio
qreal aspect = (qreal)w / ((qreal)h?h:1);
// Set near plane to 3.0, far plane to 7.0, field of view 45 degrees
const qreal zNear = 3.0, zFar = 7.0, fov = 45.0;
// Reset projection
projection.setToIdentity();
// Set perspective projection
projection.perspective(fov, aspect, zNear, zFar);
}Code: Alles auswählen
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glLoadIdentity();
QMatrix4x4 mv_mat;
//glTranslatef(0.0, 0.0, -10.0);
mv_mat.translate(0, 0, -10.0);
//glRotatef(xRot / 16.0, 1.0, 0.0, 0.0);
mv_mat.rotate(xRot / 16.0, 1.0, 0.0, 0.0);
//glRotatef(yRot / 16.0, 0.0, 1.0, 0.0);
mv_mat.rotate(yRot / 16.0, 0.0, 1.0, 0.0);
//glRotatef(zRot / 16.0, 0.0, 0.0, 1.0);
mv_mat.rotate(zRot / 16.0, 0.0, 0.0, 1.0);
program->setUniformValue("mvp_matrix", projection * mv_mat);
program->enableAttributeArray("a_position");
vertexBuffer.bind();
program->setAttributeBuffer("a_position", GL_FLOAT, 0, 3, 2);
indexBuffer.bind();
glDrawElements(GL_TRIANGLE_STRIP, indexBuffer.size(), sizeof(GLushort), &indexBuffer);
}Im Vertex-Shader werden dann die Vertices aus a_position mit der mvp_matrix transformiert und Fragment-Shader alle betrachteten Fragmente auf weiß gesetzt. (War bisher zu Testzwecken, um zu sehen ob überhaupt etwas passiert.)
Mir fehlen also so ein bisschen die konkreten Befehle um das gewollte zu bewerkstelligen. Kann das Qt alleine oder muss ich da eventuell auch direkt mit openGL arbeiten?
Danke schon mal im Voraus.
Und falls es irgendwie zur Sache tut:
Ubuntu 10.04 64bit, Qt 4.7.4