RenderStack

0.1.4

RenderStack is a support library for OpenGL 3+, with interface and implementation done in C++. Currently only Windows is supported, and all the features are very limited. Documentation is non-existent - use the source.

Current RenderStack features:

RenderStack comes with a small C++ library called mesh3d for manipulating meshes.

Done so far

Things to try

Download

http://neure.ath.cx/renderstack/renderstack-0.1.4.zip source archive, version 0.1.4, April 11, 2010

Lisence

RenderStack is licensed with the GNU Lesser General Public License version 2.1 or later (LGPL v2.1+). Copyright (c) 2010 Timo Suoranta.

Examples

Simple test for nearly minimal OpenGL 3.2 application using renderstack:

simple.png
/*
    RenderStack  Support library for OpenGL 3+
    Copyright (C) 2010  Timo Suoranta

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "renderstack/rs.h"
#include "renderstack/rs_log.h"
#include "renderstack/rs_gl.h"
#include "renderstack/window.hpp"
#include "renderstack/rectangle.hpp"
#include "renderstack/render_target.hpp"
#include "renderstack/viewport.hpp"
#include "renderstack/camera.hpp"
#include "renderstack/buffer.hpp"
#include "renderstack/mesh.hpp"
#include "renderstack/program.hpp"
#include "renderstack/frame.hpp"
#include "renderstack/vec3.hpp"
#include "renderstack/uniform_bindings.hpp"
#include "renderstack/attribute_bindings.hpp"

#include "renderstack/scoped_ptr.hpp"
#include "renderstack/shapes/polymesh.hpp"

std::string g_vertex_shader = 
"#version 150                                                            \n"
"                                                                        \n"
"in vec3 _position;                                                      \n"
"in vec3 _normal;                                                        \n"
"                                                                        \n"
"uniform mat4 _local_to_clip_matrix;                                     \n"
"uniform mat4 _local_to_world_matrix;                                    \n"
"                                                                        \n"
"out vec3 v_normal;                                                      \n"
"                                                                        \n"
"void main()                                                             \n"
"{                                                                       \n"
"    gl_Position = _local_to_clip_matrix * vec4(_position, 1.0);         \n"
"    v_normal    = vec3(_local_to_world_matrix * vec4(_normal, 0.0));    \n"
"}                                                                       \n";

std::string g_fragment_shader = 
"#version 150                                                            \n"
"                                                                        \n"
"uniform vec3  _light_direction;                                         \n"
"uniform vec3  _light_color;                                             \n"
"uniform vec3  _surface_color;                                           \n"
"                                                                        \n"
"in vec3 v_normal;                                                       \n"
"                                                                        \n"
"out vec4 out_color;                                                     \n"
"                                                                        \n"
"void main(void)                                                         \n"
"{                                                                       \n"
"    vec3  N          = normalize(v_normal);                             \n"
"    vec3  L          = _light_direction.xyz;                            \n"
"    float ln         = dot(L, N);                                       \n"
"    float ln_clamped = max(ln, 0.0);                                    \n"
"                                                                        \n"
"    out_color.rgb = _surface_color * _light_color * ln_clamped;         \n"
"    out_color.a   = 1.0;                                                \n"
"}                                                                       \n";

renderstack::window                         g_window;
renderstack::viewport                       g_viewport;
renderstack::camera                         g_camera;
renderstack::frame                          g_frame;
scoped_ptr<renderstack::program>            g_program;
scoped_ptr<renderstack::render_target>      g_render_target;
scoped_ptr<renderstack::shapes::polymesh>   g_mesh;

renderstack::uniform_mappings               g_uniform_mappings;
renderstack::uniform_bindings               g_uniform_bindings;
renderstack::uniform_parameter_source       g_parameters;

extern "C" int rs_application_begin(void)
{
    /*  Initialize window and render target */ 
    g_window.client_area().set(200, 200, 640, 480);
    g_window.set_red_size         ( 8);
    g_window.set_green_size       ( 8);
    g_window.set_blue_size        ( 8);
    g_window.set_depth_size       (24);
    g_window.set_fullscreen       (false);
    g_window.set_msaa_sample_count(0);
    g_window.set_srgb_capable     (false);

    g_window.realize();

    g_render_target.reset(
        new renderstack::default_render_target(
            g_window.client_area().width(),
            g_window.client_area().height()
        )
    );
    g_viewport.set(
        0, 
        0, 
        g_window.client_area().width(), 
        g_window.client_area().height()
    );

    /*  Create object  */ 
    {
        g_mesh.reset(
            new renderstack::shapes::sphere(2.0f, 12, 46)
        );
        g_frame.set_hpb_xyz(
            renderstack::vec3(0.0f, 0.0f, 0.0f), 
            renderstack::vec3(0.0f, 0.0f, 0.0f)
        );
    }

    /*  Setup camera  */ 
    g_camera.set_hpb_xyz(
        renderstack::vec3( 0.0f, 0.0f, 0.0f),
        renderstack::vec3( 0.0f, 0.0f, 4.0f)
    );
    g_camera.set_fov(60.0f * RS_PI / 180.0f);

    /*  Setup program  */ 
    g_program.reset(
        new renderstack::program(
            g_vertex_shader, 
            g_fragment_shader, 
            renderstack::mesh_mode_polygon_fill
        )
    );

    /*  Map attributes and uniforms  */ 
    g_program->attribute_mappings().insert("_position", renderstack::vertex_attribute_usage_position, 0, 3);
    g_program->attribute_mappings().insert("_normal",   renderstack::vertex_attribute_usage_normal,   0, 3);

    /*  Map shader uniform names to logical uniforms  */ 
    g_uniform_mappings.insert("_local_to_world_matrix",  renderstack::logical_uniform_local_to_world);
    g_uniform_mappings.insert("_world_to_local_matrix",  renderstack::logical_uniform_world_to_local);
    g_uniform_mappings.insert("_local_to_clip_matrix",   renderstack::logical_uniform_local_to_clip);
    g_uniform_mappings.insert("_clip_to_local_matrix",   renderstack::logical_uniform_clip_to_local);
    g_uniform_mappings.insert("_world_to_clip_matrix",   renderstack::logical_uniform_world_to_clip);
    g_uniform_mappings.insert("_clip_to_world_matrix",   renderstack::logical_uniform_clip_to_world);
    g_uniform_mappings.insert("_view_position_in_world", renderstack::logical_uniform_view_position_in_world);

    /*  Map shader uniform names to named and typed parameters  */ 
    g_uniform_mappings.insert("_light_direction", "light_direction", renderstack::uniform_type_vec3, 1);
    g_uniform_mappings.insert("_light_color",     "light_color",     renderstack::uniform_type_vec3, 1);
    g_uniform_mappings.insert("_surface_color",   "surface_color",   renderstack::uniform_type_vec3, 1);

    /*  Create parameters  */ 
    g_parameters.add_vec3("surface_color"  )->value[0] = renderstack::vec3(1.00f, 1.00f, 1.00f);
    g_parameters.add_vec3("light_direction")->value[0] = renderstack::vec3(0.00f, 1.00f, 0.00f);
    g_parameters.add_vec3("light_color"    )->value[0] = renderstack::vec3(1.00f, 1.00f, 1.00f);

    /*  Create bindings  */ 
    g_uniform_mappings.bind_uniforms(g_uniform_bindings, *g_program, g_camera);
    g_uniform_mappings.bind_uniforms(g_uniform_bindings, *g_program, g_frame);
    g_uniform_mappings.bind_uniforms(g_uniform_bindings, *g_program, g_parameters);

    ::rs_application_update();

    g_window.show();

    return 0;
}

extern "C" void rs_application_end(char* message)
{
    ::rs_log(message);
}


extern "C" void rs_application_update(void)
{
    ::rs_gl_enable          (GL_DEPTH_TEST);

    /*  Updates projection matrix and camera transformation  */ 
    g_camera.update         (g_viewport);

    /*  Catenate object transform with camera transform and projection  */ 
    g_camera.update_frame   (g_frame);

    /*  Clear  */ 
    ::rs_gl_viewport        (0, 0, g_render_target->width(), g_render_target->height());
    ::rs_gl_clear_color     (0.5f, 0.5f, 0.5f, 1.0f);
    ::rs_gl_clear           (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    /*  Select and prepare program for rendering  */ 
    g_program->use();
    g_uniform_bindings.apply();
    g_mesh->begin(*g_program);

    /*  Draw primitives  */ 
    ::rs_gl_draw_elements(
        g_mesh->index_buffer(g_program->mesh_mode())->gl_mode(), 
        g_mesh->index_buffer(g_program->mesh_mode())->count(), 
        g_mesh->index_buffer(g_program->mesh_mode())->gl_index_type(), 
        0
    );

    g_mesh->end();

    /*  Done with rendering  */ 
    g_window.swap_buffers();
}

extern "C" void rs_application_fail(char* message)
{
    ::rs_log(message);
    ::exit(-1);
}

extern "C" void rs_application_reshape(void)
{
    g_window.reshape();
    g_render_target->resize(
        g_window.client_area().width(),
        g_window.client_area().height()
    );
}

More advanced test, rendering with linear float 4x multisample render target:

test_cpp.png
Generated on Sun Apr 11 12:23:08 2010 for RenderStack by  doxygen 1.6.3