void Reshape(GLuint vp_width, GLuint vp_height) { width = vp_width; height = vp_height; float aspect = float(width) / height; auto projection = CamMatrixf::PerspectiveX(Degrees(60), aspect, 1, 20); plane_projection_matrix.Set(projection); shape_projection_matrix.Set(projection); gl.Bound(Texture::Target::Rectangle, depth_tex) .Image2D( 0, PixelDataInternalFormat::DepthComponent, width / tex_size_div, height / tex_size_div, 0, PixelDataFormat::DepthComponent, PixelDataType::Float, nullptr); gl.Bound(Texture::Target::Rectangle, reflect_tex) .Image2D( 0, PixelDataInternalFormat::RGB, width / tex_size_div, height / tex_size_div, 0, PixelDataFormat::RGB, PixelDataType::UnsignedByte, nullptr); }
void Render(double time) { gl.Clear().ColorBuffer().DepthBuffer(); // auto camera = CamMatrixf::Orbiting( Vec3f(), 4.5, Degrees(time * 35), Degrees(SineWave(time / 30.0) * 60) ); auto model = ModelMatrixf::RotationY(FullCircles(time * 0.25)) * ModelMatrixf::RotationX(FullCircles(time * 0.33)); camera_matrix.Set(camera); model_matrix.Set(model); transf_time.Set(time); face_pp.Bind(); gl.PolygonMode(PolygonMode::Fill); torus_instr.Draw(torus_indices); frame_pp.Bind(); gl.PolygonMode(PolygonMode::Line); torus_instr.Draw(torus_indices); }
double Draw(double time) { assert(!shapes.empty()); assert(ishape != shapes.end()); shapes::ShapeWrapper& shape = *ishape; const double interval = 11.0; double segment = time - shape_time; double fade = segment*(interval-segment); fade -= 1.0; if(fade < 0.0) fade = 0.0; fade = std::sqrt(fade/interval); if(fade > 1.0) fade = 1.0; if(segment > interval) { if(++ishape == shapes.end()) { ishape = shapes.begin(); } shape_time = time; } gl.Clear().DepthBuffer(); float dist = (1.0+SineWave(time / 13.0))*2.5; projection_matrix.Set( CamMatrixf::PerspectiveX( Degrees(45), 1.0, 1.0+dist, shape.BoundingSphere().Radius()*2.0+1.0+dist ) ); camera_matrix.Set( CamMatrixf::Orbiting( Vec3f(), shape.BoundingSphere().Radius()+1.5+dist, FullCircles(time / 27.0), Degrees(SineWave(time / 23.0) * 89) ) ); model_matrix.Set( ModelMatrixf::RotationA( Vec3f(1,1,1), FullCircles(time /-37.0) ) ); prog.Use(); shape.Use(); shape.Draw(); return fade; }
void _use_font(const BitmapFontEssence& essence) { if(_prev_font_essence != static_cast<const void*>(&essence)) { essence.Use(); _bitmap_sampler.Set(GLint(essence.BitmapTexUnit())); _metric_sampler.Set(GLint(essence.MetricTexUnit())); _pg_map_sampler.Set(GLint(essence.PageMapTexUnit())); _prev_font_essence = &essence; } }
void Reshape(GLuint width, GLuint height) { gl.Viewport(width, height); Mat4f projection = CamMatrixf::PerspectiveX( Degrees(65), double(width)/height, 1, 40 ); norm_projection_matrix.Set(projection); refl_projection_matrix.Set(projection); }
void SRPWindows::DrawWindow() { if (m_bInitialized && m_psWindowsData->bIsVisable) // should suffice { // set the program m_pCurrentRenderer->SetProgram(m_pProgramWrapper); // set the render state to allow for transparency m_pCurrentRenderer->SetRenderState(RenderState::BlendEnable, true); /* possible change - let (re)sizing be handled by the program uniform, see http://dev.pixellight.org/forum/viewtopic.php?f=6&t=503 */ { const PLMath::Rectangle &cViewportRect = m_pCurrentRenderer->GetViewport(); float fX1 = cViewportRect.vMin.x; float fY1 = cViewportRect.vMin.y; float fX2 = cViewportRect.vMax.x; float fY2 = cViewportRect.vMax.y; Matrix4x4 m_mObjectSpaceToClipSpace; m_mObjectSpaceToClipSpace.OrthoOffCenter(fX1, fX2, fY1, fY2, -1.0f, 1.0f); // create program uniform ProgramUniform *pProgramUniform = m_pProgramWrapper->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) pProgramUniform->Set(m_mObjectSpaceToClipSpace); const int nTextureUnit = m_pProgramWrapper->Set("TextureMap", m_pTextureBuffer); if (nTextureUnit >= 0) { // set sampler states m_pCurrentRenderer->SetSamplerState(nTextureUnit, Sampler::AddressU, TextureAddressing::Clamp); m_pCurrentRenderer->SetSamplerState(nTextureUnit, Sampler::AddressV, TextureAddressing::Clamp); m_pCurrentRenderer->SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::None); m_pCurrentRenderer->SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::None); m_pCurrentRenderer->SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None); } // set vertex attributes m_pProgramWrapper->Set("VertexPosition", m_pVertexBuffer, VertexBuffer::Position); m_pProgramWrapper->Set("VertexTexCoord", m_pVertexBuffer, VertexBuffer::TexCoord); } // draw primitives m_pCurrentRenderer->DrawPrimitives(Primitive::TriangleStrip, 0, 4); } }
void Render(const BitmapGlyphLayoutTpl<BitmapFont>& layout) { // we'll need the layout font's essence assert(layout._font._essence); // use the layout's font _use_font(*layout._font._essence); // use the layout's storage _use_layout(layout._data); // load the font pages referenced by the layout layout._font._essence->LoadPages( layout._pages.data(), layout._pages.size() ); // set the Layout Width uniform value if necessary if(_layout_width_active) _layout_width.Set(layout._data._width); // draw the glyphs Context gl; gl.DrawArrays( PrimitiveType::Points, layout._data._offset, layout._data._length ); }
void Render(double time) { namespace se = oglplus::smart_enums; gl.Clear().ColorBuffer().DepthBuffer().StencilBuffer(); // make the camera matrix orbiting around the origin // at radius of 3.5 with elevation between 15 and 90 degrees Mat4f camera = CamMatrixf::Orbiting( Vec3f(), 6.5, Degrees(time * 135), Degrees(15 + (-SineWave(0.25+time/12.5)+1.0)*0.5*75) ); ModelMatrixf model = ModelMatrixf::Translation(0.0f, 1.5f, 0.0); ModelMatrixf identity; // norm_camera_matrix.Set(camera); refl_camera_matrix.Set(camera); // draw the plane into the stencil buffer prog_norm.Use(); gl.Disable(se::Blend()); gl.Disable(se::DepthTest()); gl.Enable(se::StencilTest()); gl.ColorMask(false, false, false, false); gl.StencilFunc(se::Always(), 1, 1); gl.StencilOp(se::Keep(), se::Keep(), se::Replace()); norm_model_matrix.Set(identity); plane.Bind(); gl.DrawArrays(se::TriangleStrip(), 0, 4); gl.ColorMask(true, true, true, true); gl.Enable(se::DepthTest()); gl.StencilFunc(se::Equal(), 1, 1); gl.StencilOp(se::Keep(), se::Keep(), se::Keep()); // draw the torus using the reflection program prog_refl.Use(); refl_model_matrix.Set(model); torus.Bind(); torus_instr.Draw(torus_indices); gl.Disable(se::StencilTest()); prog_norm.Use(); // draw the torus using the normal object program norm_model_matrix.Set(model); torus_instr.Draw(torus_indices); // blend-in the plane gl.Enable(se::Blend()); gl.BlendEquation(se::Max()); norm_model_matrix.Set(identity); plane.Bind(); gl.DrawArrays(se::TriangleStrip(), 0, 4); }
ReflectionExample() : make_plane( Vec3f(), Vec3f(3.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, -3.0f), 15, 15) , plane_instr(make_plane.Instructions()) , plane_indices(make_plane.Indices()) , make_shape() , shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , plane_vs(ObjectDesc("Plane vertex")) , shape_vs(ObjectDesc("Shape vertex")) , plane_fs(ObjectDesc("Plane fragment")) , shape_fs(ObjectDesc("Shape fragment")) , plane_projection_matrix(plane_prog) , plane_camera_matrix(plane_prog) , plane_model_matrix(plane_prog) , shape_projection_matrix(shape_prog) , shape_camera_matrix(shape_prog) , shape_model_matrix(shape_prog) , width(800) , height(600) , tex_size_div(2) { plane_vs.Source( "#version 140\n" "uniform vec3 LightPosition;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "out vec3 vertLightDir;" "out vec4 vertTexCoord;" "void main()" "{" " gl_Position = ModelMatrix*Position;" " vertLightDir = LightPosition - gl_Position.xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" " vertTexCoord = gl_Position;" "}"); plane_vs.Compile(); plane_fs.Source( "#version 140\n" "uniform sampler2DRect ReflectTex;" "uniform vec3 Normal;" "in vec3 vertLightDir;" "in vec4 vertTexCoord;" "out vec3 fragColor;" "const int n = 5;" "const int ns = (n*n);" "const float blur = 0.15/n;" "void main()" "{" " float d = dot(Normal, normalize(vertLightDir));" " float intensity = 0.5 + pow(1.4*d, 2.0);" " vec3 color = vec3(0.0, 0.0, 0.0);" " int n = 2;" " float pct = 0.5/vertTexCoord.w;" " for(int y=-n; y!=(n+1); ++y)" " for(int x=-n; x!=(n+1); ++x)" " {" " vec2 coord = vertTexCoord.xy;" " coord += vec2(blur*x, blur*y);" " coord *= pct;" " coord += vec2(0.5, 0.5);" " coord *= textureSize(ReflectTex);" " color += texture(ReflectTex, coord).rgb/ns;" " }" " fragColor = color*intensity;" "}"); plane_fs.Compile(); plane_prog.AttachShader(plane_vs); plane_prog.AttachShader(plane_fs); plane_prog.Link(); plane_prog.Use(); plane_projection_matrix.BindTo("ProjectionMatrix"); plane_camera_matrix.BindTo("CameraMatrix"); plane_model_matrix.BindTo("ModelMatrix"); Vec3f lightPos(3.0f, 0.5f, 2.0f); Uniform<Vec3f>(plane_prog, "LightPosition").Set(lightPos); Uniform<Vec3f>(plane_prog, "Normal").Set(make_plane.Normal()); plane.Bind(); plane_verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_plane.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexArrayAttrib attr(plane_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // Texture::Active(1); gl.Bound(Texture::Target::Rectangle, depth_tex) .MinFilter(TextureMinFilter::Linear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::ClampToEdge) .WrapT(TextureWrap::ClampToEdge); Texture::Active(0); ProgramUniformSampler(plane_prog, "ReflectTex").Set(0); gl.Bound(Texture::Target::Rectangle, reflect_tex) .MinFilter(TextureMinFilter::Linear) .MagFilter(TextureMagFilter::Linear) .WrapS(TextureWrap::ClampToEdge) .WrapT(TextureWrap::ClampToEdge); gl.Bound(Framebuffer::Target::Draw, fbo) .AttachTexture(FramebufferAttachment::Color, reflect_tex, 0) .AttachTexture(FramebufferAttachment::Depth, depth_tex, 0); shape_vs.Source( "#version 140\n" "uniform vec3 LightPosition;" "uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "out vec3 vertViewDir;" "out vec3 vertColor;" "void main()" "{" " gl_Position = ModelMatrix * Position;" " vertLightDir = LightPosition - gl_Position.xyz;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLightRefl = reflect(" " -normalize(vertLightDir)," " normalize(vertNormal)" " );" " vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)*CameraMatrix).xyz;" " vertColor = vec3(1, 1, 1) - vertNormal;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}"); shape_vs.Compile(); shape_fs.Source( "#version 140\n" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec3 vertColor;" "out vec3 fragColor;" "void main()" "{" " float l = length(vertLightDir);" " float d = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / l;" " float s = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 lt = vec3(1.0, 1.0, 1.0);" " fragColor = " " vertColor * 0.4 + " " (lt + vertColor)*pow(max(2.5*d, 0.0), 3) + " " lt * pow(max(s, 0.0), 64);" "}"); shape_fs.Compile(); shape_prog.AttachShader(shape_vs); shape_prog.AttachShader(shape_fs); shape_prog.Link(); shape_prog.Use(); shape_projection_matrix.BindTo("ProjectionMatrix"); shape_camera_matrix.BindTo("CameraMatrix"); shape_model_matrix.BindTo("ModelMatrix"); Uniform<Vec3f>(shape_prog, "LightPosition").Set(lightPos); shape.Bind(); shape_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(shape_prog, "Position"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } shape_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(shape_prog, "Normal"); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // gl.ClearColor(0.5f, 0.5f, 0.4f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); }
ReflectionExample(void) : torus_indices(make_torus.Indices()) , torus_instr(make_torus.Instructions()) , vs_norm(ObjectDesc("Vertex-Normal")) , vs_refl(ObjectDesc("Vertex-Reflection")) , gs_refl(ObjectDesc("Geometry-Reflection")) , norm_projection_matrix(prog_norm) , norm_camera_matrix(prog_norm) , norm_model_matrix(prog_norm) , refl_projection_matrix(prog_refl) , refl_camera_matrix(prog_refl) , refl_model_matrix(prog_refl) { namespace se = oglplus::smart_enums; // Set the normal object vertex shader source vs_norm.Source( "#version 330\n" "in vec4 Position;" "in vec3 Normal;" "out vec3 geomColor;" "out vec3 geomNormal;" "out vec3 geomLight;" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "uniform vec3 LightPos;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " geomColor = Normal;" " geomNormal = mat3(ModelMatrix)*Normal;" " geomLight = LightPos-gl_Position.xyz;" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); // compile it vs_norm.Compile(); // Set the reflected object vertex shader source // which just passes data to the geometry shader vs_refl.Source( "#version 330\n" "in vec4 Position;" "in vec3 Normal;" "out vec3 vertNormal;" "void main(void)" "{" " gl_Position = Position;" " vertNormal = Normal;" "}" ); // compile it vs_refl.Compile(); // Set the reflected object geometry shader source // This shader creates a reflection matrix that // relies on the fact that the reflection is going // to be done by the y-plane gs_refl.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 6) out;" "in vec3 vertNormal[];" "uniform mat4 ProjectionMatrix;" "uniform mat4 CameraMatrix;" "uniform mat4 ModelMatrix;" "out vec3 geomColor;" "out vec3 geomNormal;" "out vec3 geomLight;" "uniform vec3 LightPos;" "mat4 ReflectionMatrix = 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," " 0.0, 0.0, 0.0, 1.0 " ");" "void main(void)" "{" " for(int v=0; v!=gl_in.length(); ++v)" " {" " vec4 Position = gl_in[v].gl_Position;" " gl_Position = ModelMatrix * Position;" " geomColor = vertNormal[v];" " geomNormal = mat3(ModelMatrix)*vertNormal[v];" " geomLight = LightPos - gl_Position.xyz;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " ReflectionMatrix *" " gl_Position;" " EmitVertex();" " }" " EndPrimitive();" "}" ); // compile it gs_refl.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "in vec3 geomColor;" "in vec3 geomNormal;" "in vec3 geomLight;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(geomLight);" " float d = l > 0.0 ? dot(" " geomNormal, " " normalize(geomLight)" " ) / l : 0.0;" " float i = 0.2 + max(d, 0.0) * 2.0;" " fragColor = vec4(abs(geomNormal)*i, 1.0);" "}" ); // compile it fs.Compile(); // attach the shaders to the normal rendering program prog_norm.AttachShader(vs_norm); prog_norm.AttachShader(fs); // link it prog_norm.Link(); norm_projection_matrix.BindTo("ProjectionMatrix"); norm_camera_matrix.BindTo("CameraMatrix"); norm_model_matrix.BindTo("ModelMatrix"); // attach the shaders to the reflection rendering program prog_refl.AttachShader(vs_refl); prog_refl.AttachShader(gs_refl); prog_refl.AttachShader(fs); // link it prog_refl.Link(); refl_projection_matrix.BindTo("ProjectionMatrix"); refl_camera_matrix.BindTo("CameraMatrix"); refl_model_matrix.BindTo("ModelMatrix"); // bind the VAO for the torus torus.Bind(); // bind the VBO for the torus vertices torus_verts.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); // upload the data Buffer::Data(se::Array(), data); // setup the vertex attribs array for the vertices typedef VertexArrayAttrib VAA; VertexAttribSlot loc_norm = VAA::GetLocation(prog_norm, "Position"), loc_refl = VAA::GetLocation(prog_refl, "Position"); assert(loc_norm == loc_refl); VertexArrayAttrib attr(loc_norm); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // bind the VBO for the torus normals torus_normals.Bind(se::Array()); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Normals(data); // upload the data Buffer::Data(se::Array(), data); // setup the vertex attribs array for the normals typedef VertexArrayAttrib VAA; VertexAttribSlot loc_norm = VAA::GetLocation(prog_norm, "Normal"), loc_refl = VAA::GetLocation(prog_refl, "Normal"); assert(loc_norm == loc_refl); VertexArrayAttrib attr(loc_norm); attr.Setup<GLfloat>(n_per_vertex); attr.Enable(); } // bind the VAO for the plane plane.Bind(); // bind the VBO for the plane vertices plane_verts.Bind(se::Array()); { GLfloat data[4*3] = { -2.0f, 0.0f, 2.0f, -2.0f, 0.0f, -2.0f, 2.0f, 0.0f, 2.0f, 2.0f, 0.0f, -2.0f }; // upload the data Buffer::Data(se::Array(), 4*3, data); // setup the vertex attribs array for the vertices prog_norm.Use(); VertexArrayAttrib attr(prog_norm, "Position"); attr.Setup<Vec3f>(); attr.Enable(); } // bind the VBO for the torus normals plane_normals.Bind(se::Array()); { GLfloat data[4*3] = { -0.1f, 1.0f, 0.1f, -0.1f, 1.0f, -0.1f, 0.1f, 1.0f, 0.1f, 0.1f, 1.0f, -0.1f }; // upload the data Buffer::Data(se::Array(), 4*3, data); // setup the vertex attribs array for the normals prog_norm.Use(); VertexArrayAttrib attr(prog_norm, "Normal"); attr.Setup<Vec3f>(); attr.Enable(); } NoVertexArray().Bind(); Vec3f lightPos(2.0f, 2.0f, 3.0f); prog_norm.Use(); (prog_norm/"LightPos").Set(lightPos); prog_refl.Use(); (prog_refl/"LightPos").Set(lightPos); // gl.ClearColor(0.2f, 0.2f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.ClearStencil(0); }
/** * @brief * Sets the value of this parameter to a parameter within the given manager GPU program */ bool Parameter::SetManagerParameterValue(Program &cProgram, const PLCore::String &sName) const { // Get the GPU program uniform ProgramUniform *pProgramUniform = cProgram.GetUniform(sName); if (pProgramUniform) { // Set parameter switch (m_nType) { case Parameters::String: // GPU programs don't have string parameters break; case Parameters::Integer: pProgramUniform->Set(*static_cast<const int*>(m_pValue)); break; case Parameters::Integer2: pProgramUniform->Set2(static_cast<const int*>(m_pValue)); break; case Parameters::Integer3: pProgramUniform->Set3(static_cast<const int*>(m_pValue)); break; case Parameters::Integer4: pProgramUniform->Set4(static_cast<const int*>(m_pValue)); break; case Parameters::Float: pProgramUniform->Set(*static_cast<const float*>(m_pValue)); break; case Parameters::Float2: pProgramUniform->Set2(static_cast<const float*>(m_pValue)); break; case Parameters::Float3: pProgramUniform->Set3(static_cast<const float*>(m_pValue)); break; case Parameters::Float4: pProgramUniform->Set4(static_cast<const float*>(m_pValue)); break; case Parameters::Double: pProgramUniform->Set(*static_cast<const double*>(m_pValue)); break; case Parameters::Double2: pProgramUniform->Set2(static_cast<const double*>(m_pValue)); break; case Parameters::Double3: pProgramUniform->Set3(static_cast<const double*>(m_pValue)); break; case Parameters::Double4: pProgramUniform->Set4(static_cast<const double*>(m_pValue)); break; case Parameters::Float3x3: // [TODO] New shader interface: Add Set3x3 method? //pProgramUniform->Set(static_cast<const float*>(m_pValue)); pProgramUniform->Set(Matrix3x3(static_cast<const float*>(m_pValue))); break; case Parameters::Float3x4: // [TODO] New shader interface: Add Set3x4 method? //pProgramUniform->Set(static_cast<const float*>(m_pValue)); break; case Parameters::Float4x4: // [TODO] New shader interface: Add Set4x4 method? pProgramUniform->Set(Matrix4x4(static_cast<const float*>(m_pValue))); break; case Parameters::Double4x4: // [TODO] New shader interface: Add Set4x4 method? //pProgramUniform->Set(static_cast<const double*>(m_pValue)); break; case Parameters::TextureBuffer: return false; // Error, not supported case Parameters::UnknownDataType: default: return false; // Error, not supported } // Done return true; } // Error! return false; }
//[-------------------------------------------------------] //[ Private virtual PLRenderer::SurfacePainter functions ] //[-------------------------------------------------------] void SPRTTShaders::OnPaint(Surface &cSurface) { // Get the used renderer Renderer &cRenderer = GetRenderer(); // Clear the content of the current used render target by using gray (this way, in case on an graphics error we might still see at least something) cRenderer.Clear(Clear::Color | Clear::ZBuffer, Color4::Gray); // Backup current render target and set the new one to render in our texture buffer Surface *pRenderSurfaceBackup = cRenderer.GetRenderTarget(); if (cRenderer.SetRenderTarget(m_pRenderTarget)) { if (m_pColorTarget1) cRenderer.SetColorRenderTarget(static_cast<TextureBuffer*>(m_pColorTarget1), 1); if (m_pColorTarget2) cRenderer.SetColorRenderTarget(static_cast<TextureBuffer*>(m_pColorTarget2), 2); if (m_pColorTarget3) cRenderer.SetColorRenderTarget(static_cast<TextureBuffer*>(m_pColorTarget3), 3); // Draw the scene DrawScene(cRenderer); // Reset render target cRenderer.SetRenderTarget(pRenderSurfaceBackup); } // This code is similar to the code of the triangle sample. But instead of a // triangle we will draw three rotating quadrangles. Further the used vertex // buffer has texture coordinates and we apply the 'teapot' texture buffer on the primitives. // Clear the content of the current used render target // Make our program to the current one if (cRenderer.SetProgram(m_pProgram)) { // Set program vertex attributes, this creates a connection between "Vertex Buffer Attribute" and "Vertex Shader Attribute" m_pProgram->Set("VertexPosition", m_pPositionVertexBuffer, VertexBuffer::Position); m_pProgram->Set("VertexTextureCoordinate", m_pPositionVertexBuffer, VertexBuffer::TexCoord); m_pProgram->Set("VertexColor", m_pColorVertexBuffer, VertexBuffer::Color); // Set color factor m_pProgram->Set("ColorFactor", 0.0f); // Calculate the composed view projection matrix - we need it multiple times Matrix4x4 mViewProjection; { // Calculate the view matrix Matrix4x4 mView; { mView.SetTranslation(0.0f, 0.0f, -5.0f); } // Calculate the projection matrix Matrix4x4 mProjection; { const float fAspect = 1.0f; const float fAspectRadio = cRenderer.GetViewport().GetWidth()/(cRenderer.GetViewport().GetHeight()*fAspect); mProjection.PerspectiveFov(static_cast<float>(45.0f*Math::DegToRad), fAspectRadio, 0.001f, 1000.0f); } // Calculate the composed view projection matrix mViewProjection = mProjection*mView; } // No back face culling, please. Else we can only see one 'side' of the quadrangle cRenderer.SetRenderState(RenderState::CullMode, Cull::None); Matrix4x4 mWorld; { // Draw quadrangle 1: Primary render target // Set object space to clip space matrix uniform ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { mWorld.SetTranslationMatrix(2.0f, 1.0f, 0.0f); pProgramUniform->Set(mViewProjection*mWorld); } { // Set the texture buffer we rendered our teapot in as the current texture buffer const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pRenderTarget->GetTextureBuffer()); if (nTextureUnit >= 0) { // Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None); } } // Draw cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4); } { // Draw quadrangle 2: Color render target 1 // Set object space to clip space matrix uniform ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { mWorld.FromEulerAngleY(static_cast<float>(m_fRotation*Math::DegToRad)); mWorld.SetTranslation(-2.0f, 1.0f, 0.0f); pProgramUniform->Set(mViewProjection*mWorld); } { // Set the texture buffer we rendered our teapot in as the current texture buffer const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pColorTarget1 ? static_cast<TextureBuffer*>(m_pColorTarget1) : m_pRenderTarget->GetTextureBuffer()); if (nTextureUnit >= 0) { // Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None); } } // Draw cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4); } { // Draw quadrangle 3: Color render target 2 // Set object space to clip space matrix uniform ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { mWorld.FromEulerAngleZ(static_cast<float>(m_fRotation*Math::DegToRad)); mWorld.SetTranslation(0.0f, 1.0f, 0.0f); pProgramUniform->Set(mViewProjection*mWorld); } { // Set the texture buffer we rendered our teapot in as the current texture buffer const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pColorTarget2 ? static_cast<TextureBuffer*>(m_pColorTarget2) : m_pRenderTarget->GetTextureBuffer()); if (nTextureUnit >= 0) { // Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None); } } // Draw cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4); } { // Draw quadrangle 4: Color render target 3 // Set object space to clip space matrix uniform ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { mWorld.FromEulerAngleZ(static_cast<float>(-m_fRotation*Math::DegToRad)); mWorld.SetTranslation(-2.0f, -1.0f, 0.0f); pProgramUniform->Set(mViewProjection*mWorld); } { // Set the texture buffer we rendered our teapot in as the current texture buffer const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pColorTarget3 ? static_cast<TextureBuffer*>(m_pColorTarget3) : m_pRenderTarget->GetTextureBuffer()); if (nTextureUnit >= 0) { // Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None); } } // Draw cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4); } { // Draw quadrangle 4: Primary render target, but with per vertex color - the primitive will be quite colorful :) // Set object space to clip space matrix uniform ProgramUniform *pProgramUniform = m_pProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { mWorld.FromEulerAngleZ(static_cast<float>(-m_fRotation*Math::DegToRad)); mWorld.SetTranslation(2.0f, -1.0f, 0.0f); pProgramUniform->Set(mViewProjection*mWorld); } // Set color factor m_pProgram->Set("ColorFactor", 1.0f); { // Set the texture buffer we rendered our teapot in as the current texture buffer const int nTextureUnit = m_pProgram->Set("DiffuseMap", m_pRenderTarget->GetTextureBuffer()); if (nTextureUnit >= 0) { // Disable mip mapping - this is required because we created/filled no mipmaps for your texture buffer cRenderer.SetSamplerState(nTextureUnit, Sampler::MagFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MinFilter, TextureFiltering::Linear); cRenderer.SetSamplerState(nTextureUnit, Sampler::MipFilter, TextureFiltering::None); } } // Draw cRenderer.DrawPrimitives(Primitive::TriangleStrip, 0, 4); } // Change the backface culling back to the default setting cRenderer.SetRenderState(RenderState::CullMode, Cull::CCW); } // Increase the rotation by the current time difference (time past since the last frame) // -> Normally, such work should NOT be performed within the rendering step, but we want // to keep the implementation simple in here... m_fRotation += Timing::GetInstance()->GetTimeDifference()*50; }
/** * @brief * Draws the scene */ void SPRTTShaders::DrawScene(Renderer &cRenderer) { // Clear the content of the current used render target by using gray (this way, in case on an graphics error we might still see at least something) cRenderer.Clear(Clear::Color | Clear::ZBuffer, Color4::Gray); // Make our program to the current one if (cRenderer.SetProgram(m_pSceneProgram)) { // Calculate the world matrix Matrix4x4 mWorld; { // Build a rotation matrix by using a given Euler angle around the y-axis mWorld.FromEulerAngleY(static_cast<float>(m_fRotation*Math::DegToRad)); } // Set program uniforms ProgramUniform *pProgramUniform = m_pSceneProgram->GetUniform("ObjectSpaceToClipSpaceMatrix"); if (pProgramUniform) { // Calculate the view matrix Matrix4x4 mView; { mView.SetTranslation(0.0f, -0.1f, -0.5f); } // Calculate the projection matrix Matrix4x4 mProjection; { const float fAspect = 1.0f; const float fAspectRadio = cRenderer.GetViewport().GetWidth()/(cRenderer.GetViewport().GetHeight()*fAspect); mProjection.PerspectiveFov(static_cast<float>(45.0f*Math::DegToRad), fAspectRadio, 0.001f, 1000.0f); } // Calculate the final composed world view projection matrix const Matrix4x4 mWorldViewProjection = mProjection*mView*mWorld; // Set object space to clip space matrix uniform pProgramUniform->Set(mWorldViewProjection); } // Set object space to world space matrix uniform pProgramUniform = m_pSceneProgram->GetUniform("ObjectSpaceToWorldSpaceMatrix"); if (pProgramUniform) pProgramUniform->Set(mWorld); // Set world space light direction pProgramUniform = m_pSceneProgram->GetUniform("LightDirection"); if (pProgramUniform) pProgramUniform->Set(Vector3::UnitZ); // Get the used mesh const Mesh *pMesh = m_pMeshHandler->GetMesh(); if (pMesh) { // Get the mesh LOD level to use const MeshLODLevel *pLODLevel = pMesh->GetLODLevel(0); if (pLODLevel && pLODLevel->GetIndexBuffer()) { // Get and use the index buffer of the mesh LOD level cRenderer.SetIndexBuffer(pLODLevel->GetIndexBuffer()); // Get the vertex buffer of the mesh handler VertexBuffer *pVertexBuffer = m_pMeshHandler->GetVertexBuffer(); if (pVertexBuffer) { // Set program vertex attributes, this creates a connection between "Vertex Buffer Attribute" and "Vertex Shader Attribute" ProgramAttribute *pProgramAttribute = m_pSceneProgram->GetAttribute("VertexPosition"); if (pProgramAttribute) pProgramAttribute->Set(pVertexBuffer, VertexBuffer::Position); pProgramAttribute = m_pSceneProgram->GetAttribute("VertexNormal"); if (pProgramAttribute) pProgramAttribute->Set(pVertexBuffer, VertexBuffer::Normal); // Loop through all geometries of the mesh const Array<Geometry> &lstGeometries = *pLODLevel->GetGeometries(); for (uint32 nGeo=0; nGeo<lstGeometries.GetNumOfElements(); nGeo++) { // Is this geometry active? const Geometry &cGeometry = lstGeometries[nGeo]; if (cGeometry.IsActive()) { // Draw the geometry cRenderer.DrawIndexedPrimitives( cGeometry.GetPrimitiveType(), 0, pVertexBuffer->GetNumOfElements()-1, cGeometry.GetStartIndex(), cGeometry.GetIndexSize() ); } } } } } } }