Example(GLuint width, GLuint height) : log_sink( [](const oglplus::ARB_debug_output::CallbackData& data) -> void { std::cout << "[" << data.id << "] '" << data.message << "'" << std::endl; std::cout << " [source] '" << oglplus::EnumValueName(data.source) << "'" << std::endl; std::cout << " [type] '" << oglplus::EnumValueName(data.type) << "'" << std::endl; std::cout << " [severity] '" << oglplus::EnumValueName(data.severity) << "'" << std::endl; } ) { using namespace oglplus; dbg.Control( DebugOutputARBSource::DontCare, DebugOutputARBType::DontCare, DebugOutputARBSeverity::Low, true ); gl.ClearColor(1.0f, 1.0f, 1.0f, 0.0f); gl.Viewport(width, height); glc.MatrixMode(CompatibilityMatrixMode::Projection); glc.LoadIdentity(); glc.MatrixMode(CompatibilityMatrixMode::Modelview); glc.LoadIdentity(); }
DSATextureExample(int /*argc*/, const char** /*argv*/) : gl() , prog(make_prog()) , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , model_matrix(prog, "ModelMatrix") , textured_cube( oglplus::List("Position")("Normal")("TexCoord").Get(), oglplus::shapes::Cube(), prog ) { using namespace oglplus; checker.target = Texture::Target::_2D; checker.Image2D(images::CheckerRedBlack(256, 256, 8, 8)); checker.GenerateMipmap(); checker.MinFilter(TextureMinFilter::LinearMipmapLinear); checker.MagFilter(TextureMagFilter::Linear); checker.Anisotropy(2.0); checker.WrapS(TextureWrap::Repeat); checker.WrapT(TextureWrap::Repeat); checker.Bind(); (prog/"Checker") = 0; (prog/"LightPos") = Vec3f(10.0f, 20.0f, 30.0f); gl.ClearColor(0.3f, 0.3f, 0.3f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); }
void drawScene() { gl.ClearColor(0.2, 0.2, 0.2, 1.0); gl.Clear().ColorBuffer().DepthBuffer(); gl.Viewport(0, 0, 640, 480); // draw GUI System::getSingleton().renderAllGUIContexts(); }
PathExample(int, const char**) { using namespace oglplus; PathNVCommand commands[] = { PathNVCommand::MoveTo, PathNVCommand::LineTo, PathNVCommand::LineTo, PathNVCommand::LineTo, PathNVCommand::LineTo, PathNVCommand::Close }; GLfloat coords[] = { 0.00, 0.85, 0.65,-0.80, -0.85, 0.30, 0.85, 0.30, -0.65,-0.80 }; path.Commands( sizeof(commands)/sizeof(commands[0]), commands, sizeof(coords)/sizeof(coords[0]), coords ); path.StrokeWidth(0.01); path.JoinStyle(PathNVJoinStyle::Round); GLfloat dash_array[] = {0.05, 0.02}; path.DashArray( sizeof(dash_array)/sizeof(dash_array[0]), dash_array ); glc.MatrixMode(CompatibilityMatrixMode::Projection); glc.LoadIdentity(); glc.MatrixMode(CompatibilityMatrixMode::Modelview); glc.LoadIdentity(); gl.ClearColor(1.0f, 1.0f, 1.0f, 0.0f); gl.ClearStencil(0); gl.StencilMask(~0); gl.StencilFunc(CompareFunction::NotEqual, 0, 0x1F); gl.StencilOp( StencilOperation::Keep, StencilOperation::Keep, StencilOperation::Zero ); gl.Enable(Capability::StencilTest); }
STBTruetypeExample(int argc, const char** argv) : gl() , tr(oglplus::text::STBTrueTypeRendering(0, 1, 2)) , font(tr.LoadFont((argc>1)?argv[1]:"FreeSans")) , oglp_layout(tr.MakeLayout(font, "OGLplus")) , desc_layout(tr.MakeLayout(font, u8"a C++ wrapper for OpenGL©")) , time_layout(tr.MakeLayout(font, 25)) , rndr(tr.GetRenderer( oglplus::FragmentShader( oglplus::ObjectDesc("Pixel color"), oglplus::StrCRef( "#version 330\n" "vec4 PixelColor(" " vec4 TexelColor," " vec3 GlyphPosition," " float GlyphXOffset," " vec2 GlyphExtent," " vec2 GlyphCoord," " float LayoutWidth" ")" "{" " float g = GlyphXOffset / LayoutWidth;" " float b = GlyphCoord.y;" " vec3 Color = mix(" " vec3(1.0, 0.2, 0.2+0.8*b), " " vec3(0.2, 1.0, 0.2+0.8*b), " " g" " );" " return vec4(Color, TexelColor.r);" "}") ) ) ) { using namespace oglplus; rndr.Use(); gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.Enable(Capability::Blend); gl.BlendFunc( BlendFunction::SrcAlpha, BlendFunction::DstAlpha ); }
PangoCairoTextExample(int argc, const char** argv) : gl() , tr(0) , font(tr.LoadFont((argc>2)?argv[2]:"Sans 38")) , layout(tr.MakeLayout(font, 48)) , rndr(tr.GetRenderer( oglplus::FragmentShader( oglplus::ObjectDesc("Pixel color"), "#version 330\n" "uniform vec3 Color;" "uniform float Opacity;" "vec4 PixelColor(" " vec4 TexelColor," " vec3 GlyphPosition," " float GlyphXOffset," " vec2 GlyphExtent," " vec2 GlyphCoord," " float LayoutWidth" ")" "{" " return vec4(Color, TexelColor.r*Opacity);" "}" ) ) ), rndr_color(rndr.GetUniform<oglplus::Vec3f>("Color")) , rndr_opacity(rndr.GetUniform<GLfloat>("Opacity")) , prev_interval(-1) , current_line(0) { using namespace oglplus; rndr.Use(); gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.Enable(Capability::Blend); gl.BlendFunc( BlendFunction::SrcAlpha, BlendFunction::DstAlpha ); rndr.SetAlignment(text::Alignment::Center); }
TextExample(int /*argc*/, const char** /*argv*/) : text_glyphs(128) { using namespace oglplus; GLfloat font_scale = 48; text_glyphs.GlyphRange( PathNVFontTarget::Standard, "Sans", PathNVFontStyle::Bold, 0, 128, PathNVMissingGlyph::Use, ~0, font_scale ); GLfloat color_gen_coeffs[9] = { -0.6f, 0.0f, 0.8f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f }; npr.ColorGen( PathNVColor::Primary, PathNVGenMode::ObjectBoundingBox, PathNVColorFormat::RGB, color_gen_coeffs ); gl.ClearColor(1.0f, 1.0f, 1.0f, 0.0f); gl.ClearStencil(0); gl.StencilMask(~0); gl.StencilFunc(CompareFunction::NotEqual, 0, 0xFF); gl.StencilOp( StencilOperation::Keep, StencilOperation::Keep, StencilOperation::Zero ); gl.Enable(Capability::StencilTest); }
TriangleExample(void) : gl() , prog(make_prog()) { triangle.Bind(); GLfloat triangle_pos[9] = { -1.0f,-1.0f, 0.0f, 1.0f,-1.0f, 0.0f, -1.0f, 1.0f, 0.0f }; positions.Bind(oglplus::Buffer::Target::Array); oglplus::Buffer::Data( oglplus::Buffer::Target::Array, triangle_pos ); oglplus::VertexAttribArray(prog, "Position") .Setup<GLfloat>(3) .Enable(); gl.ClearColor(1.0, 0.0, 1.0, 0.0); }
GLMBoxesExample(int, const char**) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 CameraMatrix, ScaleMatrix;" "uniform vec3 LightPos;" "uniform float Time;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertColor;" "void main(void)" "{" " float angle = gl_InstanceID * 10 * 2 * 3.14159 / 360.0;" " float ct = cos(angle+Time);" " float st = sin(angle+Time);" " mat4 ModelMatrix = mat4(" " ct, 0.0, st, 0.0," " 0.0, 1.0, 0.0, 0.0," " -st, 0.0, ct, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ) * mat4(" " 1.0, 0.0, 0.0, 0.0," " 0.0, 1.0, 0.0, 0.0," " 0.0, 0.0, 1.0, 0.0," " 12.0, 0.0, 0.0, 1.0 " " ) * mat4(" " ct, -st, 0.0, 0.0," " st, ct, 0.0, 0.0," " 0.0, 0.0, 1.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " );" " gl_Position = " " ModelMatrix *" " ScaleMatrix *" " Position;" " vec3 vertLightDir = normalize(LightPos - gl_Position.xyz);" " vec3 vertNormal = normalize((" " ModelMatrix *" " vec4(Normal, 0.0)" " ).xyz);" " gl_Position = CameraMatrix * gl_Position;" " vertColor = abs(normalize(" " Normal -" " vec3(1.0, 1.0, 1.0) +" " Position.xyz*0.2" " )) * (0.6 + 0.5*max(dot(vertNormal, vertLightDir), 0.0));" "}" ); // compile it vs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "in vec3 vertColor;" "out vec3 fragColor;" "void main(void)" "{" " fragColor = vertColor;" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the cube cube.Bind(); // bind the VBO for the cube vertex positions positions.Bind(oglplus::Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); // upload the data oglplus::Buffer::Data(oglplus::Buffer::Target::Array, data); // setup the vertex attribs array for the vertices oglplus::VertexArrayAttrib attr(prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // bind the VBO for the cube normals normals.Bind(oglplus::Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Normals(data); // upload the data oglplus::Buffer::Data(oglplus::Buffer::Target::Array, data); // setup the vertex attribs array for the vertices oglplus::VertexArrayAttrib attr(prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // gl.ClearColor(0.8f, 0.8f, 0.8f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(oglplus::Capability::DepthTest); oglplus::Uniform<oglplus::Vec3f>(prog, "LightPos").Set( glm::vec3(7.0, 3.0, -1.0) ); oglplus::Uniform<oglplus::Mat4f>(prog, "ScaleMatrix").Set( glm::scale(glm::mat4(1.0), glm::vec3(1.0, 0.3, 1.7)) ); }
BitmapGlyphExample(int argc, const char** argv) : gl() , tr(0, 1, 2) , font(tr.LoadFont((argc>1)?argv[1]:"Sans")) , oglp_layout(tr.MakeLayout(font, "OGLplus")) #if !OGLPLUS_NO_UNICODE_LITERALS , desc_layout(tr.MakeLayout(font, u8"a C++ wrapper for OpenGL©")) #else , desc_layout(tr.MakeLayout(font, "a C++ wrapper for OpenGL(c)")) #endif , time_layout(tr.MakeLayout(font, 25)) , rndr(tr.GetRenderer( oglplus::GeometryShader( oglplus::ObjectDesc("Layout transform"), "#version 150\n" "uniform mat4 ProjectionMatrix,CameraMatrix,LayoutMatrix;" "mat4 Matrix = ProjectionMatrix*CameraMatrix*LayoutMatrix;" "vec4 TransformLayout(vec3 GlyphPosition)" "{" " return Matrix * vec4(GlyphPosition, 1.0);" "}" ), oglplus::GeometryShader( oglplus::ObjectDesc("Glyph transform"), "#version 150\n" "uniform float Time;" "vec3 TransformGlyph(" " vec4 LogicalMetrics," " vec4 InkMetrics," " vec2 Pos," " float XOffs," " float LayoutWidth," " int Idx" ")" "{" " float a = Idx*0.7+Time*2.4;" " return vec3(" " Pos.x+XOffs," " Pos.y+sin(a)*0.1," " cos(a)*0.05" " );" "}" ), oglplus::FragmentShader( oglplus::ObjectDesc("Pixel color"), "#version 150\n" "vec4 PixelColor(" " vec4 TexelColor," " vec3 GlyphPosition," " float GlyphXOffset," " vec2 GlyphExtent," " vec2 GlyphCoord," " float LayoutWidth" ")" "{" " float g = GlyphXOffset / LayoutWidth - GlyphCoord.x;" " vec3 Color = mix(" " vec3(1.0, 0.2+0.8*g, 0.2), " " vec3(0.2, 0.2+0.8*g, 1.0), " " (GlyphPosition.z+0.1)/0.2" " );" " return vec4(Color, TexelColor.r);" "}" ) ) ), rndr_projection_matrix(rndr.GetUniform<oglplus::Mat4f>("ProjectionMatrix")) , rndr_camera_matrix(rndr.GetUniform<oglplus::Mat4f>("CameraMatrix")) , rndr_layout_matrix(rndr.GetUniform<oglplus::Mat4f>("LayoutMatrix")) , rndr_time(rndr.GetUniform<GLfloat>("Time")) { using namespace oglplus; rndr.Use(); gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.Enable(Capability::Blend); gl.BlendFunc( BlendFunction::SrcAlpha, BlendFunction::DstAlpha ); }
BlenderMeshExample(int argc, const char* argv[]) : prog() , camera_matrix(prog, "CameraMatrix") , light_position(prog, "LightPosition") , camera_position(prog, "CameraPosition") , face_normals(prog, "FaceNormals") , element_count(0) { using namespace oglplus; VertexShader vs; vs.Source( "#version 330\n" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 LightPosition, CameraPosition;" "mat4 Matrix = ProjectionMatrix * CameraMatrix;" "in vec3 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertViewDir;" "void main(void)" "{" " vertNormal = Normal;" " vertLightDir = LightPosition - Position;" " vertViewDir = CameraPosition - Position;" " gl_Position = Matrix * vec4(Position, 1.0);" "}" ); vs.Compile(); prog.AttachShader(vs); GeometryShader gs; gs.Source( "#version 330\n" "layout (triangles) in;" "layout (triangle_strip, max_vertices=3) out;" "uniform bool FaceNormals;" "in vec3 vertNormal[3];" "in vec3 vertLightDir[3];" "in vec3 vertViewDir[3];" "out vec3 geomNormal;" "out vec3 geomLightDir;" "out vec3 geomViewDir;" "void main(void)" "{" " vec3 fn;" " if(FaceNormals)" " {" " vec3 p0 = gl_in[0].gl_Position.xyz;" " vec3 p1 = gl_in[1].gl_Position.xyz;" " vec3 p2 = gl_in[2].gl_Position.xyz;" " fn = normalize(cross(p1-p0, p2-p0));" " }" " for(int v=0; v!=3; ++v)" " {" " gl_Position = gl_in[v].gl_Position;" " if(FaceNormals) geomNormal = fn;" " else geomNormal = vertNormal[v];" " geomLightDir = vertLightDir[v];" " geomViewDir = vertViewDir[v];" " EmitVertex();" " }" " EndPrimitive();" "}" ); gs.Compile(); prog.AttachShader(gs); FragmentShader fs; fs.Source( "#version 330\n" "in vec3 geomNormal;" "in vec3 geomLightDir;" "in vec3 geomViewDir;" "out vec3 fragColor;" "void main(void)" "{" " vec3 LightColor = vec3(1.0, 1.0, 1.0);" " vec3 MatColor = vec3(0.5, 0.5, 0.5);" " vec3 LightRefl = reflect(-geomLightDir, geomNormal);" " float Ambient = 0.3;" " float Diffuse = max(dot(" " normalize(geomNormal)," " normalize(geomLightDir)" " ), 0.0);" " float Contour = pow((1.0 - max(dot(" " normalize(geomNormal)," " normalize(geomViewDir)" " )-0.1, 0.0))*1.05, 4.0);" " float Specular = pow(clamp(dot(" " normalize(geomViewDir)," " normalize(LightRefl)" " )+0.005, 0.0, 0.98), 64.0);" " fragColor = MatColor * LightColor * (Contour + Diffuse + Ambient)+" " LightColor * Specular;" "}" ); fs.Compile(); prog.AttachShader(fs); prog.Link(); prog.Use(); gl.PrimitiveRestartIndex(0); // vectors with vertex position and normals // the values at index 0 is unused // 0 is used as primitive restart index std::vector<GLfloat> pos_data(3, 0.0); std::vector<GLfloat> nml_data(3, 0.0); // index offset starting at 1 GLuint index_offset = 1; // vectors with vertex indices std::vector<GLuint> idx_data(1, 0); // open an input stream std::ifstream input(argc>1? argv[1]: "./test.blend"); // check if we succeeded if(!input.good()) throw std::runtime_error("Error opening file for reading"); // parse the input stream imports::BlendFile blend_file(input); // get the file's global block auto glob_block = blend_file.StructuredGlobalBlock(); // get the default scene auto scene_data = blend_file[glob_block.curscene]; // // get the pointer to the first object in the scene auto object_link_ptr = scene_data.Field<void*>("base.first").Get(); // and go through the whole list of objects while(object_link_ptr) { // for each list element open the linked list block auto object_link_data = blend_file[object_link_ptr]; // get the pointer to its object auto object_ptr = object_link_data.Field<void*>("object").Get(); // open the object block (if any) if(object_ptr) try { auto object_data = blend_file[object_ptr]; // get the data pointer auto object_data_ptr = object_data.Field<void*>("data").Get(); // open the data block (if any) if(object_data_ptr) { auto object_data_data = blend_file[object_data_ptr]; // if it is a mesh if(object_data_data.StructureName() == "Mesh") { // get the object matrix field auto object_obmat_field = object_data.Field<float>("obmat"); // make a transformation matrix Mat4f obmat( object_obmat_field.Get(0, 0), object_obmat_field.Get(0, 4), object_obmat_field.Get(0, 8), object_obmat_field.Get(0,12), object_obmat_field.Get(0, 1), object_obmat_field.Get(0, 5), object_obmat_field.Get(0, 9), object_obmat_field.Get(0,13), object_obmat_field.Get(0, 2), object_obmat_field.Get(0, 6), object_obmat_field.Get(0,10), object_obmat_field.Get(0,14), object_obmat_field.Get(0, 3), object_obmat_field.Get(0, 7), object_obmat_field.Get(0,11), object_obmat_field.Get(0,15) ); // the number of vertices std::size_t n_verts = 0; // get the vertex block pointer auto vertex_ptr = object_data_data.Field<void*>("mvert").Get(); // open the vertex block (if any) if(vertex_ptr) { auto vertex_data = blend_file[vertex_ptr]; // get the number of vertices in the block n_verts = vertex_data.BlockElementCount(); // get the vertex coordinate and normal fields auto vertex_co_field = vertex_data.Field<float>("co"); auto vertex_no_field = vertex_data.Field<short>("no"); // make two vectors of position and normal data std::vector<GLfloat> ps(3 * n_verts); std::vector<GLfloat> ns(3 * n_verts); for(std::size_t v=0; v!=n_verts; ++v) { // (transpose y and z axes) // get the positional coordinates Vec4f position( vertex_co_field.Get(v, 0), vertex_co_field.Get(v, 1), vertex_co_field.Get(v, 2), 1.0f ); Vec4f newpos = obmat * position; ps[3*v+0] = newpos.x(); ps[3*v+1] = newpos.z(); ps[3*v+2] =-newpos.y(); // get the normals Vec4f normal( vertex_no_field.Get(v, 0), vertex_no_field.Get(v, 1), vertex_no_field.Get(v, 2), 0.0f ); Vec4f newnorm = obmat * normal; ns[3*v+0] = newnorm.x(); ns[3*v+1] = newnorm.z(); ns[3*v+2] =-newnorm.y(); } // append the values pos_data.insert(pos_data.end(), ps.begin(), ps.end()); nml_data.insert(nml_data.end(), ns.begin(), ns.end()); } // get the face block pointer auto face_ptr = object_data_data.Field<void*>("mface").Get(); // open the face block (if any) if(face_ptr) { auto face_data = blend_file[face_ptr]; // get the number of faces in the block std::size_t n_faces = face_data.BlockElementCount(); // get the vertex index fields of the face auto face_v1_field = face_data.Field<int>("v1"); auto face_v2_field = face_data.Field<int>("v2"); auto face_v3_field = face_data.Field<int>("v3"); auto face_v4_field = face_data.Field<int>("v4"); // make a vector of index data std::vector<GLuint> is(5 * n_faces); for(std::size_t f=0; f!=n_faces; ++f) { // get face vertex indices int v1 = face_v1_field.Get(f); int v2 = face_v2_field.Get(f); int v3 = face_v3_field.Get(f); int v4 = face_v4_field.Get(f); is[5*f+0] = v1+index_offset; is[5*f+1] = v2+index_offset; is[5*f+2] = v3+index_offset; is[5*f+3] = v4?v4+index_offset:0; is[5*f+4] = 0; // primitive restart index } // append the values idx_data.insert(idx_data.end(), is.begin(), is.end()); } // get the poly block pointer auto poly_ptr = object_data_data.TryGet<void*>("mpoly", nullptr); // and the loop block pointer auto loop_ptr = object_data_data.TryGet<void*>("mloop", nullptr); // open the poly and loop blocks (if we have both) if(poly_ptr && loop_ptr) { auto poly_data = blend_file[poly_ptr]; auto loop_data = blend_file[loop_ptr]; // get the number of polys in the block std::size_t n_polys = poly_data.BlockElementCount(); // get the fields of poly and loop auto poly_loopstart_field = poly_data.Field<int>("loopstart"); auto poly_totloop_field = poly_data.Field<int>("totloop"); auto loop_v_field = loop_data.Field<int>("v"); // make a vector of index data std::vector<GLuint> is; for(std::size_t f=0; f!=n_polys; ++f) { int ls = poly_loopstart_field.Get(f); int tl = poly_totloop_field.Get(f); for(int l=0; l!=tl; ++l) { int v = loop_v_field.Get(ls+l); is.push_back(v+index_offset); } is.push_back(0); // primitive restart index } // append the values idx_data.insert(idx_data.end(), is.begin(), is.end()); } index_offset += n_verts; } } } catch(...) { } // and get the pointer to the nex block object_link_ptr = object_link_data.Field<void*>("next").Get(); } meshes.Bind(); positions.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, pos_data); VertexAttribArray attr(prog, "Position"); attr.Setup<GLfloat>(3); attr.Enable(); } normals.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, nml_data); VertexAttribArray attr(prog, "Normal"); attr.Setup<GLfloat>(3); attr.Enable(); } indices.Bind(Buffer::Target::ElementArray); Buffer::Data(Buffer::Target::ElementArray, idx_data); element_count = idx_data.size(); // find the extremes of the mesh(es) GLfloat min_x = pos_data[3], max_x = pos_data[3]; GLfloat min_y = pos_data[4], max_y = pos_data[4]; GLfloat min_z = pos_data[5], max_z = pos_data[5]; for(std::size_t v=1, vn=pos_data.size()/3; v!=vn; ++v) { GLfloat x = pos_data[v*3+0]; GLfloat y = pos_data[v*3+1]; GLfloat z = pos_data[v*3+2]; if(min_x > x) min_x = x; if(min_y > y) min_y = y; if(min_z > z) min_z = z; if(max_x < x) max_x = x; if(max_y < y) max_y = y; if(max_z < z) max_z = z; } // position the camera target camera_target = Vec3f( (min_x + max_x) * 0.5, (min_y + max_y) * 0.5, (min_z + max_z) * 0.5 ); // and calculate a good value for camera distance camera_distance = 1.1*Distance(camera_target, Vec3f(min_x, min_y, min_z))+1.0; gl.ClearColor(0.17f, 0.22f, 0.17f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::PrimitiveRestart); }
STBTruetypeExample(int argc, const char** argv) : gl() , tr(0, 1, 2) , font(tr.LoadFont((argc>1)?argv[1]:"FreeSans")) , oglp_layout(tr.MakeLayout(font, "OGLplus")) #if !OGLPLUS_NO_UNICODE_LITERALS , desc_layout(tr.MakeLayout(font, u8"a C++ wrapper for OpenGL©")) #else , desc_layout(tr.MakeLayout(font, "a C++ wrapper for OpenGL(c)")) #endif , time_layout(tr.MakeLayout(font, 25)) , rndr(tr.GetRenderer( oglplus::GeometryShader( oglplus::ObjectDesc("Layout transform"), oglplus::StrCRef( "#version 150\n" "uniform mat4 ProjectionMatrix,CameraMatrix,LayoutMatrix;" "mat4 Matrix = ProjectionMatrix*CameraMatrix*LayoutMatrix;" "vec4 TransformLayout(vec3 GlyphPosition)" "{" " return Matrix * vec4(GlyphPosition, 1.0);" "}") ), oglplus::GeometryShader( oglplus::ObjectDesc("Glyph transform"), oglplus::StrCRef("#version 150\n" "uniform float Time;" "uniform int Axis;" "vec3 TransformGlyph(" " vec4 LogicalMetrics," " vec4 InkMetrics," " vec2 Pos," " float XOffs," " float LayoutWidth," " int Idx" ")" "{" " float a = Idx*0.3+Time*2.4;" " float cx = cos(a);" " float sx = sin(a);" " mat3 m;" " vec3 v;" " vec3 o = vec3(XOffs, 0, 0);" " vec3 p = vec3(Pos, 0);" " if(Axis == 0)" " {" " m = mat3(" " 1, 0, 0," " 0, cx, sx," " 0,-sx, cx " " );" " v = vec3(0, (InkMetrics.z-InkMetrics.w)*0.5, 0);" " }" " else if(Axis == 1)" " {" " m = mat3(" " cx, 0,-sx," " 0, 1, 0," " sx, 0, cx " " );" " v = vec3((InkMetrics.y-InkMetrics.x)*0.5, 0, 0);" " }" " else if(Axis == 2)" " {" " m = mat3(" " 1, 0, 0," " 0,-cx,-sx," " 0, sx,-cx " " );" " v = vec3(0, 0, 0);" " }" " return m*(p-v)+(o+v);" "}") ), oglplus::FragmentShader( oglplus::ObjectDesc("Pixel color"), oglplus::StrCRef("#version 150\n" "vec4 PixelColor(" " vec4 TexelColor," " vec3 GlyphPosition," " float GlyphXOffset," " vec2 GlyphExtent," " vec2 GlyphCoord," " float LayoutWidth" ")" "{" " float g = GlyphXOffset / LayoutWidth;" " vec3 Color = mix(" " vec3(1.0, 0.2, 0.2), " " vec3(0.2, 0.4, 1.0), " " g" " );" " return vec4(Color, TexelColor.r);" "}") ) ) ), rndr_projection_matrix(rndr.GetUniform<oglplus::Mat4f>("ProjectionMatrix")) , rndr_camera_matrix(rndr.GetUniform<oglplus::Mat4f>("CameraMatrix")) , rndr_layout_matrix(rndr.GetUniform<oglplus::Mat4f>("LayoutMatrix")) , rndr_time(rndr.GetUniform<GLfloat>("Time")) , rndr_axis(rndr.GetUniform<GLint>("Axis")) { using namespace oglplus; rndr.Use(); gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.Enable(Capability::Blend); gl.BlendFunc( BlendFunction::SrcAlpha, BlendFunction::DstAlpha ); }
TextExample(int /*argc*/, const char** /*argv*/) : text("OpenGL") , text_path(text.size()) , glyph_indices(make_glyph_indices()) , glyph_spacings(glyph_indices.size()) { using namespace oglplus; GLfloat font_scale = 64; text_path.Glyphs( PathNVFontTarget::Standard, "Sans", PathNVFontStyle::Bold, text, PathNVMissingGlyph::Use, ~0, font_scale); text_path.GetSpacing( PathNVListMode::AccumAdjacentPairs, glyph_indices, 1.0f, 1.0f, PathNVTransformType::TranslateX, glyph_spacings); glyph_spacings.insert(glyph_spacings.begin(), 0); glyph_spacings.pop_back(); glyph_indices.pop_back(); GLfloat text_left = glyph_spacings.front(); GLfloat text_right = glyph_spacings.back(); GLfloat font_min_max[2]; text_path.GetMetricRange( PathNVMetricQuery::FontYMinBounds | PathNVMetricQuery::FontYMaxBounds, 1, 0, font_min_max); projection.Ortho( text_left - 10, text_right + 10, font_min_max[0], font_min_max[1], -1.0, +1.0); modelview.LoadIdentity(); gl.ClearColor(1.0f, 1.0f, 1.0f, 0.0f); gl.ClearStencil(0); gl.StencilMask(~0); gl.StencilFunc(CompareFunction::NotEqual, 0, 0xFF); gl.StencilOp( StencilOperation::Keep, StencilOperation::Keep, StencilOperation::Zero); gl.Enable(Capability::StencilTest); }