Since I couldn't find a decent hello world program in the internet I
decided to write one. It's 256 lines long and written with QT and
OpenGL. If you have suggestions for improvement/simplification please
email me.
Could this be included in Mesa or mesa-demos?

# README
OpenGL3 Hello world.

To build and run: "qmake && make test"

# ogl.pro
TARGET = ogl
SOURCES = ogl.cc oglwidget.cc
HEADERS = oglwidget.h

QT = core gui opengl
LIBS += -lGLEW -L.

test.commands = ./ogl
test.depends = ogl
t.depends = test
edit.commands = vi oglwidget.cc
e.depends = edit

QMAKE_EXTRA_TARGETS = e edit t test

# ogl.cc
#include <QApplication>
#include "oglwidget.h"

int main( int argc, char** argv )
{
        QApplication app( argc, argv );

        OGLWidget w;
        w.show();

        return app.exec();
}

# oglwidget.h
#ifndef OPENGLWIDGET_H
#define OPENGLWIDGET_H

#include <QtOpenGL>

class OGLWidget : public QGLWidget
{
        Q_OBJECT

        public:
                OGLWidget( QGLWidget* parent = 0 );
                ~OGLWidget();

                void query();

        protected:
                void keyPressEvent( QKeyEvent* event );
                void initializeGL();
                void paintGL();

        private slots:
                void animate();
};

#endif

# oglwidget.cc
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <iterator>
#include <GL/glew.h>
#include <QtCore/qtimer.h>
#include <QtGui/qpainter.h>
#include <QTime>
#include "oglwidget.h"

inline const GLubyte *BUFFER_OFFSET( size_t bytes )
{
    return reinterpret_cast<const GLubyte *>(0) + bytes;
}

struct Quad {
        struct Vertex {
                GLfloat pos[2];
                GLfloat texcoord[2];
        };
        GLushort indices[4];
        Vertex vertices[4];

        GLuint vertex_array;
        GLuint index_buffer;
        GLuint vertex_buffer;

        GLuint shader_program;
};

Quad quad;
GLfloat projection_matrix[16];
GLfloat view_matrix[16];
GLfloat model_matrix[16];

OGLWidget::OGLWidget( QGLWidget* parent ) : QGLWidget( parent )
{
        resize( 400, 400 );
        setFocusPolicy( Qt::StrongFocus );

        QTimer* timer = new QTimer( this );
        connect( timer, SIGNAL( timeout() ), this, SLOT( animate() ) );
        timer->start( 50 );
}


OGLWidget::~OGLWidget() {}

void OGLWidget::animate() {
        updateGL();
}

void OGLWidget::keyPressEvent( QKeyEvent* event )
{
        if( event->key() == Qt::Key_Escape )
                close();        
}

void OGLWidget::initializeGL()
{
        if( glewInit() != GLEW_OK )
                std::cerr << "Can't initialize glew!\n";
        if ( ! GLEW_VERSION_3_0 ) {
                std::cerr << "OpenGL version 3 is not supported!\n";
                exit( EXIT_FAILURE );
        }

        // Shaders
        GLuint vertex_shader = glCreateShader( GL_VERTEX_SHADER );
        std::string vertex_string( std::istreambuf_iterator<char>(
std::ifstream( "ogl.vert" ).rdbuf() ),
std::istreambuf_iterator<char>() );
        const GLchar* vertex_source = reinterpret_cast<const GLchar*>(
vertex_string.c_str() );
        glShaderSource( vertex_shader, 1, & vertex_source, 0 );
        glCompileShader( vertex_shader );
        GLint compiled  = 0;
        glGetShaderiv( vertex_shader, GL_COMPILE_STATUS, & compiled );
        if( ! compiled )
                std::cerr << "Compilation of vertex shader failed!\n";

        GLuint fragment_shader = glCreateShader( GL_FRAGMENT_SHADER );
        std::string fragment_string( std::istreambuf_iterator<char>(
std::ifstream( "ogl.frag" ).rdbuf() ),
std::istreambuf_iterator<char>() );
        const GLchar* fragment_source = reinterpret_cast<const GLchar*>(
fragment_string.c_str() );
        glShaderSource( fragment_shader, 1, & fragment_source, 0 );
        glCompileShader( fragment_shader );
        glGetShaderiv( fragment_shader, GL_COMPILE_STATUS, & compiled );
        if( ! compiled )
                std::cerr << "Compilation of fragment shader failed!\n";

        quad.shader_program = glCreateProgram();
        glAttachShader( quad.shader_program, vertex_shader );
        glAttachShader( quad.shader_program, fragment_shader );
        glLinkProgram( quad.shader_program );
        GLint linked;
        glGetProgramiv( quad.shader_program, GL_LINK_STATUS, & linked );        
        glDeleteShader( vertex_shader );
        glDeleteShader( fragment_shader );
        if( ! linked )
                std::cerr << "Linking failed!\n";       

        // Geometry
        GLfloat size = 100;
        quad.vertices[0].pos[0] = -size;
        quad.vertices[0].pos[1] = +size;
        quad.vertices[1].pos[0] = -size;
        quad.vertices[1].pos[1] = -size;
        quad.vertices[2].pos[0] = +size;
        quad.vertices[2].pos[1] = +size;
        quad.vertices[3].pos[0] = +size;
        quad.vertices[3].pos[1] = -size;

        quad.indices[0] = 0;
        quad.indices[1] = 1;
        quad.indices[2] = 2;
        quad.indices[3] = 3;

        glGenVertexArrays( 1, & quad.vertex_array );    
        glBindVertexArray( quad.vertex_array );

        glGenBuffers( 1, & quad.index_buffer );
        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, quad.index_buffer );
        glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( quad.indices ),
quad.indices, GL_STATIC_DRAW );

        glGenBuffers( 1, & quad.vertex_buffer );
        glBindBuffer( GL_ARRAY_BUFFER, quad.vertex_buffer );
        glBufferData( GL_ARRAY_BUFFER, sizeof( quad.vertices ),
quad.vertices, GL_STATIC_DRAW );

        glVertexAttribPointer( glGetAttribLocation( quad.shader_program,
"Position" ), 2, GL_FLOAT, GL_FALSE, sizeof( Quad::Vertex ),
BUFFER_OFFSET( 0 ) );
        glEnableVertexAttribArray( glGetAttribLocation( quad.shader_program,
"Position" ) );

        // Matrices
        projection_matrix[ 0] = 1; projection_matrix[ 1] = 0;
projection_matrix[ 2] = 0; projection_matrix[ 3] = 0;
        projection_matrix[ 4] = 0; projection_matrix[ 5] = 1;
projection_matrix[ 6] = 0; projection_matrix[ 7] = 0;
        projection_matrix[ 8] = 0; projection_matrix[ 9] = 0;
projection_matrix[10] = 1; projection_matrix[11] = 0;
        projection_matrix[12] = 0; projection_matrix[13] = 0;
projection_matrix[14] = 0; projection_matrix[15] = 1;

        view_matrix[ 0] = 1; view_matrix[ 1] = 0; view_matrix[ 2] = 0;
view_matrix[ 3] = 0;
        view_matrix[ 4] = 0; view_matrix[ 5] = 1; view_matrix[ 6] = 0;
view_matrix[ 7] = 0;
        view_matrix[ 8] = 0; view_matrix[ 9] = 0; view_matrix[10] = 1;
view_matrix[11] = 0;
        view_matrix[12] = 0; view_matrix[13] = 0; view_matrix[14] = 0;
view_matrix[15] = 1;

        model_matrix[ 0] = 1; model_matrix[ 1] = 0; model_matrix[ 2] = 0;
model_matrix[ 3] = 0;
        model_matrix[ 4] = 0; model_matrix[ 5] = 1; model_matrix[ 6] = 0;
model_matrix[ 7] = 0;
        model_matrix[ 8] = 0; model_matrix[ 9] = 0; model_matrix[10] = 1;
model_matrix[11] = 0;
        model_matrix[12] = 0; model_matrix[13] = 0; model_matrix[14] = 0;
model_matrix[15] = 1;
}

void OGLWidget::paintGL()
{
        // ortho2d
        GLfloat left = 0;
        GLfloat right = 400;
        GLfloat bottom = 0;
        GLfloat top = 400;
        const GLfloat near_val = -1.0f;
        const GLfloat far_val = 1.0f;
        GLfloat tx = -(right + left) / (right - left);
        GLfloat ty = -(top + bottom) / (top - bottom);
        GLfloat tz = -(far_val + near_val) / (far_val - near_val);      

        projection_matrix[ 0] = 2.0 / ( right-left ); projection_matrix[ 1] =
0; projection_matrix[ 2] = 0; projection_matrix[ 3] = 0;
        projection_matrix[ 4] = 0; projection_matrix[ 5] = 2.0 / ( top-bottom
); projection_matrix[ 6] = 0; projection_matrix[ 7] = 0;
        projection_matrix[ 8] = 0; projection_matrix[ 9] = 0;
projection_matrix[10] = -2.0 / ( far_val-near_val );
projection_matrix[11] = 0;
        projection_matrix[12] = tx; projection_matrix[13] = ty;
projection_matrix[14] = tz; projection_matrix[15] = 1;

        model_matrix[ 0] = 1; model_matrix[ 1] = 0; model_matrix[ 2] = 0;
model_matrix[ 3] = 0;
        model_matrix[ 4] = 0; model_matrix[ 5] = 1; model_matrix[ 6] = 0;
model_matrix[ 7] = 0;
        model_matrix[ 8] = 0; model_matrix[ 9] = 0; model_matrix[10] = 1;
model_matrix[11] = 0;
        model_matrix[12] = 200; model_matrix[13] = 200; model_matrix[14] = 0;
model_matrix[15] = 1;

        glViewport( 0, 0, 400, 400 );
        glClearColor( 0.0, 0.0, 0.0, 1.0 );
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

        glUseProgram( quad.shader_program );

        glUniformMatrix4fv( glGetUniformLocation( quad.shader_program,
"ProjectionMatrix" ), 1, GL_FALSE, projection_matrix );
        glUniformMatrix4fv( glGetUniformLocation( quad.shader_program,
"ViewMatrix" ), 1, GL_FALSE, view_matrix );
        glUniformMatrix4fv( glGetUniformLocation( quad.shader_program,
"ModelMatrix" ), 1, GL_FALSE, model_matrix );

        glBindVertexArray( quad.vertex_array );
        glDrawElements( GL_TRIANGLE_STRIP, sizeof( quad.indices ) / sizeof(
quad.indices[0] ), GL_UNSIGNED_SHORT, BUFFER_OFFSET(0) );
        glBindVertexArray( 0 );

        glUseProgram( 0 );

        int error = glGetError();
        if( error != GL_NO_ERROR )
                std::cerr << "Error: " << glGetError() << std::endl;
}

# ogl.vert
#version 130

precision highp float;

uniform mat4 ProjectionMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ModelMatrix;

in vec2 Position;

void main()
{
    mat4 mvpMatrix = ProjectionMatrix * ViewMatrix * ModelMatrix;
    vec4 pos = vec4( Position.x, Position.y, 0.0, 1.0 );
    gl_Position = mvpMatrix * pos;
}

# ogl.frag
#version 130

precision highp float;

out vec4 fragcolor;

void main()
{
        fragcolor = vec4( 1, 1, 1, 1 );
}

------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1,  ECMAScript5, and DOM L2 & L3.
Spend less time writing and  rewriting code and more time creating great
experiences on the web. Be a part of the beta today.
http://p.sf.net/sfu/beautyoftheweb
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to