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.
http://neure.ath.cx/renderstack/renderstack-0.1.4.zip source archive, version 0.1.4, April 11, 2010
RenderStack is licensed with the GNU Lesser General Public License version 2.1 or later (LGPL v2.1+). Copyright (c) 2010 Timo Suoranta.
Simple test for nearly minimal OpenGL 3.2 application using renderstack:
/* 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: