OGLplus (0.52.0) a C++ wrapper for OpenGL

oglplus/025_multi_viewport.cpp

Shows how to draw into multiple viewport at the same time

025_multi_viewport.png

Copyright 2008-2014 Matus Chochlik. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <oglplus/gl.hpp>
#include <oglplus/all.hpp>
#include <cmath>
#include "example.hpp"
namespace oglplus {
class MultiViewportExample : public Example
{
private:
typedef shapes::SpiralSphere Shape;
// helper object building shape vertex attributes
Shape make_shape;
// helper object encapsulating shape drawing instructions
shapes::DrawingInstructions shape_instr;
// indices pointing to shape primitive elements
Shape::IndexArray shape_indices;
// wrapper around the current OpenGL context
Context gl;
// Program
Program prog;
static Program make(void)
{
vs.Source(
"#version 330\n"
"uniform mat4 ModelMatrix;"
"uniform vec3 LightPos;"
"in vec4 Position;"
"in vec3 Normal;"
"out vec3 vertNormal;"
"out vec3 vertTexCoord;"
"out vec3 vertLightDir;"
"out vec3 vertLightRefl;"
"void main(void)"
"{"
" vertNormal = mat3(ModelMatrix)*Normal;"
" vertTexCoord = Normal;"
" gl_Position = ModelMatrix * Position;"
" vertLightDir = LightPos-gl_Position.xyz;"
" vertLightRefl = reflect(-vertLightDir, vertNormal);"
"}"
);
gs.Source(
"#version 330\n"
"#extension GL_ARB_viewport_array : enable\n"
"layout(triangles) in;"
"layout(triangle_strip, max_vertices = 12) out;"
"uniform mat4 CameraMatrix[4];"
"uniform vec3 CameraPosition[4];"
"in vec3 vertNormal[];"
"in vec3 vertTexCoord[];"
"in vec3 vertLightDir[];"
"in vec3 vertLightRefl[];"
"out vec3 geomNormal;"
"out vec3 geomTexCoord;"
"out vec3 geomLightDir;"
"out vec3 geomLightRefl;"
"out vec3 geomViewDir;"
"out vec3 geomViewRefl;"
"void main(void)"
"{"
" for(int vp=0; vp!=4; ++vp)"
" {"
" gl_ViewportIndex = vp;"
" for(int v=0; v!=3; ++v)"
" {"
" geomNormal = vertNormal[v];"
" geomTexCoord = vertTexCoord[v];"
" geomLightDir = vertLightDir[v];"
" geomLightRefl = vertLightRefl[v];"
" geomViewDir = "
" CameraPosition[vp] - "
" gl_in[v].gl_Position.xyz;"
" geomViewRefl = reflect("
" -geomViewDir,"
" geomNormal"
" );"
" gl_Position = "
" CameraMatrix[vp] *"
" gl_in[v].gl_Position;"
" EmitVertex();"
" }"
" EndPrimitive();"
" }"
"}"
);
fs.Source(
"#version 330\n"
"uniform samplerCube TexUnit;"
"in vec3 geomNormal;"
"in vec3 geomTexCoord;"
"in vec3 geomLightDir;"
"in vec3 geomLightRefl;"
"in vec3 geomViewDir;"
"in vec3 geomViewRefl;"
"out vec4 fragColor;"
"void main(void)"
"{"
" float l = length(geomLightDir);"
" float d = dot("
" normalize(geomNormal), "
" normalize(geomLightDir)"
" ) / l;"
" float s = dot("
" normalize(geomLightRefl),"
" normalize(geomViewDir)"
" );"
" vec3 lt = vec3(1.0, 1.0, 1.0);"
" vec3 tex = texture(TexUnit, geomTexCoord).rgb;"
" fragColor = vec4("
" tex * 0.4 + "
" (lt + tex) * 1.5 * max(d, 0.0) + "
" lt * pow(max(s, 0.0), 64), "
" 1.0"
" );"
"}"
);
Program prog;
prog.AttachShader(vs);
prog.AttachShader(gs);
prog.AttachShader(fs);
prog.Build();
prog.Use();
return prog;
}
// Handles for setting uniforms in program
Uniform<Vec3f> camera_position_3;
Uniform<Mat4f>
camera_matrix_0,
camera_matrix_1,
camera_matrix_2,
camera_matrix_3,
model_matrix;
// A vertex array object for the rendered shape
VertexArray shape;
// VBOs for the shape's vertex attributes
Buffer verts, normals;
// The environment cube map
Texture tex;
Mat4f projection;
public:
MultiViewportExample(void)
: make_shape(1.0, 0.1, 8, 4, 48)
, shape_instr(make_shape.Instructions())
, shape_indices(make_shape.Indices())
, prog(make())
, camera_position_3(prog, "CameraPosition[3]")
, camera_matrix_0(prog, "CameraMatrix[0]")
, camera_matrix_1(prog, "CameraMatrix[1]")
, camera_matrix_2(prog, "CameraMatrix[2]")
, camera_matrix_3(prog, "CameraMatrix[3]")
, model_matrix(prog, "ModelMatrix")
{
shape.Bind();
verts.Bind(Buffer::Target::Array);
{
std::vector<GLfloat> data;
GLuint n_per_vertex = make_shape.Positions(data);
Buffer::Data(Buffer::Target::Array, data);
VertexArrayAttrib attr(prog, "Position");
attr.Setup<GLfloat>(n_per_vertex);
attr.Enable();
}
normals.Bind(Buffer::Target::Array);
{
std::vector<GLfloat> data;
GLuint n_per_vertex = make_shape.Normals(data);
Buffer::Data(Buffer::Target::Array, data);
VertexArrayAttrib attr(prog, "Normal");
attr.Setup<GLfloat>(n_per_vertex);
attr.Enable();
}
// setup the texture
{
GLuint tex_side = 512;
auto image = images::NewtonFractal(
tex_side, tex_side,
Vec3f(0.8f, 0.8f, 1.0f),
Vec3f(0.1f, 0.0f, 0.2f),
Vec2f(-0.707f, -0.707f),
Vec2f( 0.707f, 0.707f),
images::NewtonFractal::X4Minus1(),
[](double x) -> double
{
return pow(SineWave(pow(x,0.5)), 4.0);
}
);
gl.Bound(Texture::Target::CubeMap, tex)
for(int i=0; i!=6; ++i)
Texture::ImageCM(i, image);
}
//
UniformSampler(prog, "TexUnit").Set(0);
Uniform<Vec3f>(prog, "LightPos").Set(Vec3f(3.0f, 5.0f, 4.0f));
//
gl.ClearColor(0.1f, 0.05f, 0.2f, 0.0f);
gl.ClearDepth(1.0f);
gl.FrontFace(make_shape.FaceWinding());
gl.CullFace(Face::Back);
Uniform<Vec3f> camera_position(prog, "CameraPosition");
camera_position[0].Set(Vec3f(2, 0, 0));
camera_position[1].Set(Vec3f(0, 2, 0));
camera_position[2].Set(Vec3f(0, 0, 2));
}
void Reshape(GLuint width, GLuint height)
{
GLfloat w_2f = width / 2.0f;
GLfloat h_2f = height/ 2.0f;
GLfloat viewports[4*4] = {
0.0f, 0.0f, w_2f, h_2f,
w_2f, 0.0f, w_2f, h_2f,
0.0f, h_2f, w_2f, h_2f,
w_2f, h_2f, w_2f, h_2f
};
gl.ViewportArray(0, 4, viewports);
Degrees(65),
double(width)/height,
1, 30
);
camera_matrix_0.Set(
projection *
Vec4f(0, 0,-1, 0),
Vec4f(0, 1, 0, 0),
Vec4f(1, 0, 0,-3),
Vec4f(0, 0, 0, 1)
)
);
camera_matrix_1.Set(
projection *
Vec4f(1, 0, 0, 0),
Vec4f(0, 0,-1, 0),
Vec4f(0, 1, 0,-3),
Vec4f(0, 0, 0, 1)
)
);
camera_matrix_2.Set(
projection *
Vec4f(1, 0, 0, 0),
Vec4f(0, 1, 0, 0),
Vec4f(0, 0, 1,-3),
Vec4f(0, 0, 0, 1)
)
);
}
void Render(double time)
{
gl.Clear().ColorBuffer().DepthBuffer();
//
Vec3f(),
4.5 - SineWave(time / 16.0) * 1.5,
FullCircles(time / 12.0),
Degrees(SineWave(time / 30.0) * 90)
);
// set the matrix for camera orbiting the origin
camera_matrix_3.Set(projection * camera);
camera_position_3.Set(camera.Position());
// set the model matrix
model_matrix.Set(
);
shape_instr.Draw(shape_indices);
}
bool Continue(double time)
{
return time < 60.0;
}
double ScreenshotTime(void) const
{
return 3.0;
}
};
void setupExample(ExampleParams& /*params*/){ }
std::unique_ptr<ExampleThread> makeExampleThread(
Example& /*example*/,
unsigned /*thread_id*/,
const ExampleParams& /*params*/
){ return std::unique_ptr<ExampleThread>(); }
std::unique_ptr<Example> makeExample(const ExampleParams& /*params*/)
{
return std::unique_ptr<Example>(new MultiViewportExample);
}
} // namespace oglplus

Copyright © 2010-2014 Matúš Chochlík, University of Žilina, Žilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Mon Sep 22 2014 by Doxygen (version 1.8.6).