void ShaderRegistry::LoadShadersFromDisk(const std::string& rShadersDirectory) { std::vector<std::string> shaderFiles = Directory::ListFiles(rShadersDirectory); for (unsigned int i = 0; i < shaderFiles.size(); i++) { std::string shaderName; ShaderType shaderType; if (!ExtractShaderInfo(shaderFiles[i], shaderName, shaderType)) { continue; } Shader* pShader; std::map<std::string, Shader*>::iterator it = mShadersByName.find(shaderName); if (it == mShadersByName.end()) { pShader = new Shader(shaderName); mShadersByName.insert(std::make_pair(shaderName, pShader)); } else { pShader = it->second; } pShader->Compile(rShadersDirectory + "/" + shaderFiles[i], shaderType); } std::map<std::string, Shader*>::iterator it = mShadersByName.begin(); while (it != mShadersByName.end()) { it->second->Link(); it++; } }
ShaderPtr ShaderLoader::Load(const Path & vertex_file_name, const Path & fragment_file_name, bool replaceCached) { Path resourceName = vertex_file_name.filename().generic_string() + fragment_file_name.filename().generic_string(); Resource<Shader> existingResource = this->GetResource(resourceName); if (existingResource.resource && !replaceCached) { GetContext().GetLogger()->log(LOG_LOG, "Shader returned from cache."); return existingResource.resource; } FilePtr vertexFile = GetContext().GetFileSystem()->OpenRead(vertex_file_name); FilePtr fragmentFile = GetContext().GetFileSystem()->OpenRead(fragment_file_name); if (!vertexFile->IsOpen() || !fragmentFile->IsOpen()) { return ShaderPtr(); } GetContext().GetLogger()->log(LOG_LOG, "Shader resource name: %s", resourceName.generic_string().c_str()); ByteBufferPtr vertexBuffer = vertexFile->ReadText(); ByteBufferPtr fragmentBuffer = fragmentFile->ReadText(); Shader * shader = new Shader(resourceName.generic_string(), (char*)vertexBuffer->data(), (char*)fragmentBuffer->data(), ""); shader->Compile(); if (shader->IsCompiledAndLinked()) { if (existingResource.resource) { RemoveResource(existingResource.path); GetContext().GetLogger()->log(LOG_LOG, "Removed cached shader: '%s'.", resourceName.c_str()); } GetContext().GetLogger()->log(LOG_LOG, "Shader loaded: '%s'.", resourceName.c_str()); Resource<Shader> res(ShaderPtr(shader), resourceName); this->AddResource(res); return res.resource; } else { delete shader; if (existingResource.resource) GetContext().GetLogger()->log(LOG_ERROR, "Shader failed to load: '%s', using cached version.", resourceName.generic_string().c_str()); else GetContext().GetLogger()->log(LOG_ERROR, "Shader failed to load: '%s'.", resourceName.generic_string().c_str()); return existingResource.resource; } }
Shader ResourceManager::loadShaderFromFile(const GLchar* vShaderFile, const GLchar* fShaderFile, const GLchar* gShaderFile) { // Define variables std::string vertexCode; std::string fragmentCode; std::string geometryCode; try { // Vertex std::ifstream vertexShaderFile(vShaderFile); std::stringstream vShaderStream; vShaderStream << vertexShaderFile.rdbuf(); vertexShaderFile.close(); vertexCode = vShaderStream.str(); // Fragment std::ifstream fragmentShaderFile(fShaderFile); std::stringstream fShaderStream; fShaderStream << fragmentShaderFile.rdbuf(); fragmentShaderFile.close(); fragmentCode = fShaderStream.str(); // Geometry if (gShaderFile != nullptr) { std::ifstream geometryShaderFile(gShaderFile); std::stringstream gShaderStream; gShaderStream << geometryShaderFile.rdbuf(); geometryShaderFile.close(); geometryCode = gShaderStream.str(); } } catch (std::ifstream::failure e) { std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl; } Shader shader; shader.Compile(vertexCode.c_str(), fragmentCode.c_str(), gShaderFile != nullptr ? geometryCode.c_str() : nullptr); return shader; }
Shader resourceManagerClass::loadShaderFromFile(const GLchar *vShaderFile, const GLchar *fShaderFile, const GLchar *gShaderFile) { // 1. Retrieve the vertex/fragment source code from filePath std::string vertexCode; std::string fragmentCode; std::string geometryCode; try { // Open files std::ifstream vertexShaderFile(vShaderFile); std::ifstream fragmentShaderFile(fShaderFile); std::stringstream vShaderStream, fShaderStream; // Read file's buffer contents into streams vShaderStream << vertexShaderFile.rdbuf(); fShaderStream << fragmentShaderFile.rdbuf(); // close file handlers vertexShaderFile.close(); fragmentShaderFile.close(); // Convert stream into string vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); // If geometry shader path is present, also load a geometry shader if (gShaderFile != nullptr) { std::ifstream geometryShaderFile(gShaderFile); std::stringstream gShaderStream; gShaderStream << geometryShaderFile.rdbuf(); geometryShaderFile.close(); geometryCode = gShaderStream.str(); } } catch (std::exception e) { std::cout << "ERROR::SHADER: Failed to read shader files" << std::endl; } const GLchar *vShaderCode = vertexCode.c_str(); const GLchar *fShaderCode = fragmentCode.c_str(); const GLchar *gShaderCode = geometryCode.c_str(); // 2. Now create shader object from source code Shader shader; shader.Compile(vShaderCode, fShaderCode, gShaderFile != nullptr ? gShaderCode : nullptr); return shader; }
RectangleExample(void) : vs(ShaderType::Vertex) , fs(ShaderType::Fragment) { // this could be any istream std::stringstream vs_source( "#version 120\n" "attribute vec2 Position;" "attribute vec3 Color;" "varying vec3 vertColor;" "void main(void)" "{" " vertColor = Color;" " gl_Position = vec4(Position, 0.0, 1.0);" "}" ); // set the vertex shader source vs.Source(GLSLSource::FromStream(vs_source)); // compile it vs.Compile(); std::stringstream fs_source( "#version 120\n" "varying vec3 vertColor;" "void main(void)" "{" " gl_FragColor = vec4(vertColor, 1.0);" "}" ); // set the fragment shader source fs.Source(GLSLSource::FromStream(fs_source)); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link it prog.Link(); // and use it gl.Program.Bind(prog); // bind the VAO for the rectangle gl.VertexArray.Bind(rectangle); // bind the VBO for the rectangle vertices if(auto x = gl.Buffer.Array.Push(verts)) { GLfloat rectangle_verts[8] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; // upload the data gl.Buffer.Array.Data(8, rectangle_verts); // setup the vertex attribs array for the vertices VertexArrayAttrib vert_attr(prog, "Position"); vert_attr.Setup<Vec2f>().Enable(); } // bind the VBO for the rectangle colors if(auto x = gl.Buffer.Array.Push(colors)) { GLfloat rectangle_colors[12] = { 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; // upload the data gl.Buffer.Array.Data(12, rectangle_colors); // setup the vertex attribs array for the vertices VertexArrayAttrib color_attr(prog, "Color"); color_attr.Setup<Vec3f>().Enable(); } gl.Caps.DepthTest.Disable(); }
TorusExample(void) : make_torus(1.0, 0.5, 36, 24) , torus_instr(make_torus.Instructions()) , torus_indices(make_torus.Indices()) , make_plane(make_plane_builders()) , plane_instr(make_plane[0].Instructions()) , plane_indices(make_plane[0].Indices()) , torus_vs(ShaderType::Vertex, ObjectDesc("Torus vertex")) , plane_vs(ShaderType::Vertex, ObjectDesc("Plane vertex")) , torus_fs(ShaderType::Fragment, ObjectDesc("Torus fragment")) , plane_fs(ShaderType::Fragment, ObjectDesc("Plane fragment")) , torus_prog(ObjectDesc("Torus")) , plane_prog(ObjectDesc("Plane")) , plane_normal(plane_prog, "Normal") , plane_camera_matrix(plane_prog, "CameraMatrix") , torus_camera_matrix(torus_prog, "CameraMatrix") , torus_model_matrix(torus_prog, "ModelMatrix") , plane(make_plane.size()) , plane_positions(make_plane.size()) { std::stringstream plane_count_def; plane_count_def <<"#define PlaneCount "<<plane.size()<<'\n'; const GLchar* torus_vs_source[3] = { "#version 330\n", plane_count_def.str().c_str(), "uniform mat4 ProjectionMatrix, ModelMatrix, CameraMatrix;" "uniform float ClipSign[PlaneCount];" "uniform vec4 ClipPlane[PlaneCount];" "in vec4 Position;" "in vec2 TexCoord;" "out vec2 vertTexCoord;" "void main(void)" "{" " vertTexCoord = TexCoord;" " gl_Position = " " ModelMatrix *" " Position;" " for(int p=0; p!=PlaneCount; ++p)" " {" " gl_ClipDistance[p] = " " ClipSign[p]* " " dot(ClipPlane[p], gl_Position);" " }" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " gl_Position;" "}" }; torus_vs.Source(torus_vs_source, 3); torus_vs.Compile(); torus_fs.Source( "#version 330\n" "in vec2 vertTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " float i = (" " int(vertTexCoord.x*36) % 2+" " int(vertTexCoord.y*24) % 2" " ) % 2;" " fragColor = vec4(1-i/2, 1-i/2, 1-i/2, 1.0);" "}" ); torus_fs.Compile(); torus_prog.AttachShader(torus_vs); torus_prog.AttachShader(torus_fs); torus_prog.Link(); torus_prog.Use(); // bind the VAO for the torus torus.Bind(); // bind the VBO for the torus vertices torus_positions.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray attr(torus_prog, "Position"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } // bind the VBO for the torus UV-coordinates torus_texcoords.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_torus.TexCoordinates(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray attr(torus_prog, "TexCoord"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } const GLchar* plane_vs_source[3] = { "#version 330\n", plane_count_def.str().c_str(), "uniform mat4 ProjectionMatrix, CameraMatrix;" "uniform float ClipSign[PlaneCount];" "uniform vec4 ClipPlane[PlaneCount];" "uniform vec3 Normal;" "in vec4 Position;" "out vec3 vertColor;" "void main(void)" "{" " gl_Position = Position;" " for(int p=0; p!=PlaneCount; ++p)" " {" " gl_ClipDistance[p] = " " ClipSign[p]* " " dot(ClipPlane[p], gl_Position);" " }" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " gl_Position;" " vertColor = normalize(" " abs(Normal) + " " 0.4*Position.xyz" " );" "}" }; plane_vs.Source(plane_vs_source, 3); plane_vs.Compile(); plane_fs.Source( "#version 330\n" "in vec3 vertColor;" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(vertColor, 0.7);" "}" ); plane_fs.Compile(); plane_prog.AttachShader(plane_vs); plane_prog.AttachShader(plane_fs); plane_prog.Link(); plane_prog.Use(); ProgramUniform<Vec4f> torus_clip_plane(torus_prog, "ClipPlane"); ProgramUniform<Vec4f> plane_clip_plane(plane_prog, "ClipPlane"); ProgramUniform<GLfloat> torus_clip_sign(torus_prog, "ClipSign"); ProgramUniform<GLfloat> plane_clip_sign(plane_prog, "ClipSign"); for(std::size_t p=0; p!=plane.size(); ++p) { plane[p].Bind(); plane_positions[p].Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n = make_plane[p].Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); VertexAttribArray attr(plane_prog, "Position"); attr.Setup(n, DataType::Float); attr.Enable(); } { auto eq = make_plane[p].Equation(); torus_clip_plane[p].Set(eq); plane_clip_plane[p].Set(eq); } { torus_clip_signs.push_back(torus_clip_sign[p]); plane_clip_signs.push_back(plane_clip_sign[p]); } } // gl.ClearColor(0.8f, 0.8f, 0.7f, 0.0f); gl.ClearDepth(1.0f); gl.FrontFace(make_torus.FaceWinding()); gl.Enable(Capability::DepthTest); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
PickingExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , vs(ShaderType::Vertex, ObjectDesc("Vertex")) , gs(ShaderType::Geometry, ObjectDesc("Geometry")) , fs(ShaderType::Fragment, ObjectDesc("Fragment")) { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix;" "in vec4 Position;" "out vec3 vertColor;" "flat out int vertInstanceID;" "void main(void)" "{" " float x = gl_InstanceID % 6 - 2.5;" " float y = gl_InstanceID / 6 - 2.5;" " mat4 ModelMatrix = 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," " 2*x, 2*y, 0.0, 1.0 " " );" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " ModelMatrix *" " Position;" " vertColor = vec3(" " abs(normalize((ModelMatrix*Position).xy))," " 0.1" " );" " vertInstanceID = gl_InstanceID;" "}" ); vs.Compile(); // Set the geometry shader source gs.Source( "#version 330\n" "layout(triangles) in;" "layout(points, max_vertices = 1) out;" "flat in int vertInstanceID[];" "uniform vec2 MousePos;" "out int geomInstanceID;" "out float geomDepth;" "vec2 barycentric_coords(vec4 a, vec4 b, vec4 c)" "{" // we'll need normalized device coordinates // of the triangle vertices " vec2 ad = vec2(a.x/a.w, a.y/a.w);" " vec2 bd = vec2(b.x/b.w, b.y/b.w);" " vec2 cd = vec2(c.x/c.w, c.y/c.w);" " vec2 u = cd - ad;" " vec2 v = bd - ad;" " vec2 r = MousePos - ad;" " float d00 = dot(u, u);" " float d01 = dot(u, v);" " float d02 = dot(u, r);" " float d11 = dot(v, v);" " float d12 = dot(v, r);" " float id = 1.0 / (d00 * d11 - d01 * d01);" " float ut = (d11 * d02 - d01 * d12) * id;" " float vt = (d00 * d12 - d01 * d02) * id;" " return vec2(ut, vt);" "}" "vec3 intersection(vec3 a, vec3 b, vec3 c, vec2 bc)" "{" " return (c - a)*bc.x + (b - a)*bc.y;" "}" "bool inside_triangle(vec2 b)" "{" " return (" " (b.x >= 0.0) &&" " (b.y >= 0.0) &&" " (b.x + b.y <= 1.0)" " );" "}" "void main(void)" "{" " vec2 bc = barycentric_coords(" " gl_in[0].gl_Position," " gl_in[1].gl_Position," " gl_in[2].gl_Position " " );" " if(inside_triangle(bc))" " {" " gl_Position = vec4(intersection(" " gl_in[0].gl_Position.xyz," " gl_in[1].gl_Position.xyz," " gl_in[2].gl_Position.xyz," " bc" " ), 1.0);" " geomDepth = gl_Position.z;" " geomInstanceID = vertInstanceID[0];" " EmitVertex();" " EndPrimitive();" " }" "}" ); gs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "flat in int vertInstanceID;" "in vec3 vertColor;" "uniform int Picked;" "out vec4 fragColor;" "void main(void)" "{" " if(vertInstanceID == Picked)" " fragColor = vec4(1.0, 1.0, 1.0, 1.0);" " else fragColor = vec4(vertColor, 1.0);" "}" ); fs.Compile(); // attach the shaders to the picking program pick_prog.AttachShader(vs); pick_prog.AttachShader(gs); const GLchar* var_names[2] = {"geomDepth", "geomInstanceID"}; pick_prog.TransformFeedbackVaryings( 2, var_names, TransformFeedbackMode::InterleavedAttribs ); pick_prog.Link(); // attach the shaders to the drawing program draw_prog.AttachShader(vs); draw_prog.AttachShader(fs); draw_prog.Link(); // bind the VAO for the cube cube.Bind(); // buffer for the picked instance depths and IDs picked_instances.Bind(Buffer::Target::TransformFeedback); picked_instances.BindBase( Buffer::IndexedTarget::TransformFeedback, 0 ); { std::vector<DepthAndID> data(36, DepthAndID(0.0, 0)); Buffer::Data(Buffer::Target::TransformFeedback, data); } // bind the VBO for the cube vertices verts.Bind(Buffer::Target::Array); { // make and upload the vertex data std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices VertexAttribArray draw_attr(draw_prog, "Position"); draw_attr.Setup<GLfloat>(n_per_vertex); draw_attr.Enable(); } gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.FrontFace(make_cube.FaceWinding()); gl.CullFace(Face::Back); gl.Enable(Capability::CullFace); }
SmokeExample(void) : emitters( { { { {-20.0f, -10.0f, 10.0f}, { 20.0f, 0.0f, -20.0f}, { 20.0f, 10.0f, 20.0f}, {-20.0f, 0.0f, -10.0f} }, 15.0, 200.0 }, { { { 30.0f, 0.0f, 5.0f}, {-30.0f, 0.0f, -5.0f}, {-20.0f, 20.0f, 5.0f}, { 20.0f, -10.0f, -5.0f} }, 17.0, 200.0 }, } ), vs(ShaderType::Vertex, "Vertex") , gs(ShaderType::Geometry, "Geometry") , fs(ShaderType::Fragment, "Fragment") , projection_matrix(prog, "ProjectionMatrix") , camera_matrix(prog, "CameraMatrix") , light_cam_pos(prog, "LightCamPos") { // Set the vertex shader source vs.Source( "#version 330\n" "uniform mat4 CameraMatrix;" "in vec4 Position;" "in float Age;" "in int Id;" "out float vertAge;" "out int vertId;" "void main(void)" "{" " gl_Position = CameraMatrix * Position;" " vertAge = Age;" " vertId = Id;" "}" ); // compile it vs.Compile(); // Set the geometry shader source gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "uniform vec3 LightCamPos;" "uniform mat4 ProjectionMatrix;" "in float vertAge[];" "in int vertId[];" "out vec2 geomTexCoord;" "out float geomAge;" "out float geomLightVal;" "out float geomLightBias;" "void main(void)" "{" " if(vertAge[0] > 1.0) return;" " vec3 pos = gl_in[0].gl_Position.xyz;" " vec3 lightDir = normalize(LightCamPos - pos);" " float s = 0.8, g = 3.0;" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " float angle = vertId[0];" " float cx = cos(angle), sx = sin(angle);" " mat2 rot = mat2(cx, sx, -sx, cx);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " float xoffs = xo[i]*(1.0+vertAge[0]*g)*s;" " float yoffs = yo[j]*(1.0+vertAge[0]*g)*s;" " vec2 offs = rot*vec2(xoffs, yoffs);" " gl_Position = ProjectionMatrix * vec4(" " pos.x-offs.x," " pos.y-offs.y," " pos.z," " 1.0" " );" " geomTexCoord = vec2(float(i), float(j));" " geomAge = vertAge[0];" " geomLightVal = lightDir.z;" " geomLightBias = -dot(" " normalize(vec3(offs, 0.0))," " lightDir" " );" " EmitVertex();" " }" " EndPrimitive();" "}" ); // compile it gs.Compile(); // set the fragment shader source fs.Source( "#version 330\n" "uniform sampler2D SmokeTex;" "in vec2 geomTexCoord;" "in float geomAge;" "in float geomLightVal;" "in float geomLightBias;" "out vec4 fragColor;" "void main(void)" "{" " vec3 c = texture(SmokeTex, geomTexCoord).rgb;" " float depth = c.g - c.r;" " if(depth == 0.0) discard;" " float density = min(depth * c.b * 2.0, 1.0);" " float intensity = min(" " max(" " geomLightVal*0.5+" " geomLightBias," " 0.0" " )+max(" " -geomLightVal*" " (1.0 - density)*" " geomLightBias * 5.0," " 0.0" " )," " 1.0" " ) + 0.1;" " fragColor = vec4(" " intensity," " intensity," " intensity," " (1.0 - geomAge)*density" " );" "}" ); // compile it fs.Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(gs); prog.AttachShader(fs); // link and use it prog.Link(); prog.Use(); // bind the VAO for the particles particles.Bind(); // bind the VBO for the particle positions pos_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, positions); VertexAttribArray attr(prog, "Position"); attr.Setup<Vec3f>(); attr.Enable(); } // bind the VBO for the particle ages age_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, ages); VertexAttribArray attr(prog, "Age"); attr.Setup<GLfloat>(); attr.Enable(); } // bind the VBO for the particle identifiers id_buf.Bind(Buffer::Target::Array); { Buffer::Data(Buffer::Target::Array, ids); VertexAttribArray attr(prog, "Id"); attr.Setup<GLint>(); attr.Enable(); } Texture::Active(0); UniformSampler(prog, "SmokeTex").Set(0); { auto bound_tex = Bind(smoke_tex, Texture::Target::_2D); bound_tex.Image2D( images::Cloud2D( images::Cloud( 128, 128, 128, Vec3f(0.1f, -0.5f, 0.3f), 0.5f ) ) ); bound_tex.GenerateMipmap(); bound_tex.MinFilter(TextureMinFilter::LinearMipmapLinear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.BorderColor(Vec4f(0.0f, 0.0f, 0.0f, 0.0f)); bound_tex.WrapS(TextureWrap::ClampToBorder); bound_tex.WrapT(TextureWrap::ClampToBorder); } // gl.ClearColor(0.0f, 0.1f, 0.2f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::Blend); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::OneMinusSrcAlpha); }
ShadowVolExample(const ExampleParams& params) : shape_instr(make_shape.Instructions()) , shape_indices(make_shape.Indices()) , shape_vs(ShaderType::Vertex, ObjectDesc("Shape vertex")) , depth_vs(ShaderType::Vertex, ObjectDesc("Depth vertex")) , light_vs(ShaderType::Vertex, ObjectDesc("Light vertex")) , depth_gs(ShaderType::Geometry, ObjectDesc("Depth geometry")) , light_gs(ShaderType::Geometry, ObjectDesc("Light geometry")) , shape_fs(ShaderType::Fragment, ObjectDesc("Shape fragment")) , depth_fs(ShaderType::Fragment, ObjectDesc("Depthfragment")) , light_fs(ShaderType::Fragment, ObjectDesc("Light fragment")) , shape_prog(ObjectDesc("Shape")) , depth_prog(ObjectDesc("Depth")) , light_prog(ObjectDesc("Light")) , tex_side(128) , sample_count(params.HighQuality()?1024:128) { shape_vs.Source( "#version 330\n" "uniform mat4 ProjectionMatrix, CameraMatrix, ModelMatrix;" "in vec4 Position;" "in vec3 Normal;" "in vec2 TexCoord;" "out vec3 vertNormal;" "out vec3 vertLightDir;" "out vec3 vertLightRefl;" "out vec3 vertViewDir;" "out vec3 vertViewRefl;" "uniform vec3 LightPos;" "void main(void)" "{" " gl_Position = ModelMatrix * Position;" " vertNormal = mat3(ModelMatrix)*Normal;" " vertLightDir = LightPos - gl_Position.xyz;" " vertLightRefl = reflect(" " -normalize(vertLightDir)," " normalize(vertNormal)" " );" " vertViewDir = (vec4(0.0, 0.0, 1.0, 1.0)* CameraMatrix).xyz;" " vertViewRefl = reflect(" " normalize(vertViewDir)," " normalize(vertNormal)" " );" " gl_Position = ProjectionMatrix * CameraMatrix * gl_Position;" "}" ); shape_vs.Compile(); shape_fs.Source( "#version 330\n" "in vec3 vertNormal;" "in vec3 vertLightDir;" "in vec3 vertLightRefl;" "in vec3 vertViewDir;" "in vec3 vertViewRefl;" "out vec4 fragColor;" "void main(void)" "{" " float l = length(vertLightDir);" " float d = dot(" " normalize(vertNormal), " " normalize(vertLightDir)" " ) / l;" " float s = dot(" " normalize(vertLightRefl)," " normalize(vertViewDir)" " );" " vec3 ambi = vec3(0.6, 0.3, 0.5);" " vec3 diff = vec3(0.9, 0.7, 0.8);" " vec3 spec = vec3(1.0, 0.9, 0.95);" " fragColor = vec4(" " ambi * 0.3 + " " diff * 0.7 * max(d, 0.0) + " " spec * pow(max(s, 0.0), 64), " " 1.0" " );" "}" ); shape_fs.Compile(); shape_prog.AttachShader(shape_vs); shape_prog.AttachShader(shape_fs); shape_prog.Link(); depth_vs.Source( "#version 330\n" "uniform mat4 ModelMatrix;" "uniform vec3 LightPos;" "in vec4 Position;" "void main(void)" "{" " gl_Position = " " mat4(" " 1.0, 0.0, 0.0, -LightPos.x," " 0.0, 1.0, 0.0, -LightPos.y," " 0.0, 0.0, 1.0, -LightPos.z," " 0.0, 0.0, 0.0, 1.0" " )*" " ModelMatrix *" " mat4(" " 10.0, 0.0, 0.0, 0.0," " 0.0, 10.0, 0.0, 0.0," " 0.0, 0.0, 10.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " )*" " Position;" "}" ); depth_vs.Compile(); depth_gs.Source( "#version 330\n" "layout(triangles) in;" "layout(triangle_strip, max_vertices = 18) out;" "uniform mat4 ProjectionMatrix;" "const mat4 CubeFaceMatrix[6] = mat4[6](" " mat4(" " 0.0, 0.0, -1.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " -1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " 0.0, 0.0, 1.0, 0.0," " 0.0, -1.0, 0.0, 0.0," " 1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " 1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, -1.0, 0.0," " 0.0, 1.0, 0.0, 0.0," " 0.0, 0.0, 0.0, 1.0 " " ), mat4(" " 1.0, 0.0, 0.0, 0.0," " 0.0, 0.0, 1.0, 0.0," " 0.0, -1.0, 0.0, 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," " 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," " 0.0, 0.0, 0.0, 1.0 " " )" ");" "void main(void)" "{" " for(gl_Layer=0; gl_Layer!=6; ++gl_Layer)" " {" " for(int i=0; i!=3; ++i)" " {" " gl_Position = " " ProjectionMatrix *" " CubeFaceMatrix[gl_Layer]*" " gl_in[i].gl_Position;" " EmitVertex();" " }" " EndPrimitive();" " }" "}" ); depth_gs.Compile(); depth_fs.Source( "#version 330\n" "void main(void)" "{" " gl_FragDepth = gl_FragCoord.z;" "}" ); depth_fs.Compile(); depth_prog.AttachShader(depth_vs); depth_prog.AttachShader(depth_gs); depth_prog.AttachShader(depth_fs); depth_prog.Link(); depth_prog.Use(); Uniform<Mat4f>(depth_prog, "ProjectionMatrix").Set( CamMatrixf::PerspectiveX( RightAngles(1.0), 1.0, 0.1, 10.0 ) ); // bind the VAO for the shape shape.Bind(); shape_positions.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Positions(data); Buffer::Data(Buffer::Target::Array, data); VertexAttribSlot location; if(VertexAttribArray::QueryCommonLocation( "Position", location, shape_prog, depth_prog )) { VertexAttribArray shape_attr(location); shape_attr.Setup(n_per_vertex, DataType::Float); shape_attr.Enable(); } else assert(!"Inconsistent 'Position' location"); } shape_normals.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_shape.Normals(data); Buffer::Data(Buffer::Target::Array, data); shape_prog.Use(); VertexAttribArray attr(shape_prog, "Normal"); attr.Setup(n_per_vertex, DataType::Float); attr.Enable(); } light_vs.Source( "#version 330\n" "in vec3 Position;" "out float vertZOffs;" "uniform vec3 LightPos;" "uniform int SampleCount;" "void main(void)" "{" " float hp = (SampleCount-1) * 0.5;" " vertZOffs = (gl_InstanceID - hp)/hp;" " gl_Position = vec4(Position + LightPos, 1.0);" "}" ); light_vs.Compile(); light_gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "in float vertZOffs[];" "out vec4 geomPosition;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform vec3 ViewX, ViewY, ViewZ;" "uniform float LightVolSize;" "void main(void)" "{" " float zo = vertZOffs[0];" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " geomPosition = vec4(" " gl_in[0].gl_Position.xyz+" " ViewX * xo[i] * LightVolSize+" " ViewY * yo[j] * LightVolSize+" " ViewZ * zo * LightVolSize," " 1.0" " );" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " geomPosition;" " EmitVertex();" " }" " EndPrimitive();" "}" ); light_gs.Compile(); light_fs.Source( "#version 330\n" "in vec4 geomPosition;" "out vec4 fragColor;" "uniform samplerCubeShadow ShadowMap;" "uniform int SampleCount;" "uniform vec3 LightPos;" "void main(void)" "{" " vec3 LightDir = geomPosition.xyz - LightPos;" " vec4 ShadowCoord = vec4(" " normalize(LightDir)," " length(LightDir)" " );" " float s = texture(ShadowMap, ShadowCoord);" " float alpha = s / (SampleCount * pow(length(LightDir), 2));" " fragColor = vec4(1.0, 1.0, 1.0, alpha);" "}" ); light_fs.Compile(); light_prog.AttachShader(light_vs); light_prog.AttachShader(light_gs); light_prog.AttachShader(light_fs); light_prog.Link(); light_prog.Use(); // bind the VAO for the light volume light.Bind(); // bind the VBO for the light volume plane positions light_positions.Bind(Buffer::Target::Array); { GLfloat position[3] = {0.0, 0.0, 0.0}; Buffer::Data(Buffer::Target::Array, 3, position); VertexAttribArray attr(light_prog, "Position"); attr.Setup(3, DataType::Float); attr.Enable(); } Uniform<GLint>(light_prog, "SampleCount").Set(sample_count); Uniform<GLfloat>(light_prog, "LightVolSize").Set(4); UniformSampler(light_prog, "ShadowMap").Set(0); // Setup the texture and the offscreen FBO Texture::Active(0); { auto bound_tex = Bind(depth_tex, Texture::Target::CubeMap); bound_tex.MinFilter(TextureMinFilter::Linear); bound_tex.MagFilter(TextureMagFilter::Linear); bound_tex.WrapS(TextureWrap::ClampToEdge); bound_tex.WrapT(TextureWrap::ClampToEdge); bound_tex.WrapR(TextureWrap::ClampToEdge); bound_tex.CompareFunc(CompareFunction::LEqual); bound_tex.CompareMode( TextureCompareMode::CompareRefToTexture ); for(int i=0; i!=6; ++i) { Texture::Image2D( Texture::CubeMapFace(i), 0, PixelDataInternalFormat::DepthComponent, tex_side, tex_side, 0, PixelDataFormat::DepthComponent, PixelDataType::Float, nullptr ); } auto bound_fbo = Bind( depth_fbo, Framebuffer::Target::Draw ); bound_fbo.AttachTexture( FramebufferAttachment::Depth, depth_tex, 0 ); } // gl.ClearColor(0.2f, 0.05f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); gl.Enable(Capability::CullFace); gl.FrontFace(make_shape.FaceWinding()); gl.CullFace(Face::Back); gl.BlendFunc(BlendFunction::SrcAlpha, BlendFunction::One); }
VolLightExample(void) : volume_vs(ShaderType::Vertex, ObjectDesc("Volume vertex")) , plane_vs(ShaderType::Vertex, ObjectDesc("Plane vertex")) , volume_gs(ShaderType::Geometry, ObjectDesc("Volume geometry")) , volume_fs(ShaderType::Fragment, ObjectDesc("Volume fragment")) , plane_fs(ShaderType::Fragment, ObjectDesc("Plane fragment")) , volume_prog(ObjectDesc("Volume")) , plane_prog(ObjectDesc("Plane")) , samples(150) { volume_vs.Source( "#version 330\n" "in vec4 Position;" "out float vertZOffs;" "uniform int SampleCount;" "uniform mat4 CameraMatrix;" "uniform vec3 ViewZ;" "uniform float Size;" "void main(void)" "{" " float hp = (SampleCount-1) * 0.5;" " vertZOffs = (gl_InstanceID - hp)/hp;" " gl_Position = vec4(" " Position.xyz +" " ViewZ*vertZOffs*Size*0.5," " 1.0" " );" "}" ); volume_vs.Compile(); volume_gs.Source( "#version 330\n" "layout(points) in;" "layout(triangle_strip, max_vertices = 4) out;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform mat4 TexProjectionMatrix;" "uniform vec3 ViewX, ViewY;" "uniform float Size;" "in float vertZOffs[];" "out vec4 geomTexCoord;" "void main(void)" "{" " float zo = vertZOffs[0];" " float yo[2] = float[2](-1.0, 1.0);" " float xo[2] = float[2](-1.0, 1.0);" " for(int j=0;j!=2;++j)" " for(int i=0;i!=2;++i)" " {" " vec4 v = vec4(" " gl_in[0].gl_Position.xyz+" " ViewX * xo[i] * Size+" " ViewY * yo[j] * Size," " 1.0" " );" " geomTexCoord = " " TexProjectionMatrix *" " v;" " gl_Position = " " ProjectionMatrix *" " CameraMatrix * v;" " EmitVertex();" " }" " EndPrimitive();" "}" ); volume_gs.Compile(); volume_fs.Source( "#version 330\n" "uniform sampler2D LightTex;" "uniform int SampleCount;" "in vec4 geomTexCoord;" "out vec4 fragColor;" "void main(void)" "{" " vec2 coord = geomTexCoord.st/geomTexCoord.q;" " float depth = geomTexCoord.z;" " if(depth < 0.0) discard;" " vec4 t = texture(LightTex, coord*0.5 + 0.5);" " if(t.a == 0.0) discard;" " float alpha = 10.0*(1.0-t.a)/SampleCount;" " alpha *= (t.r+t.g+t.b)*0.3333;" " alpha /= sqrt(depth);" " fragColor = vec4(t.rgb, alpha);" "}" ); volume_fs.Compile(); volume_prog.AttachShader(volume_vs); volume_prog.AttachShader(volume_gs); volume_prog.AttachShader(volume_fs); volume_prog.Link(); volume_prog.Use(); // bind the VAO for the volumes volume.Bind(); // bind the VBO for the volume positions volume_pos.Bind(Buffer::Target::Array); { GLfloat position[3] = {0.0, 0.0, 0.0}; Buffer::Data(Buffer::Target::Array, 3, position); VertexArrayAttrib attr(volume_prog, "Position"); attr.Setup<Vec3f>(); attr.Enable(); } Vec3f lightPos(2.0f, 4.0f, -3.0f); auto texProjMat = CamMatrixf::PerspectiveX(Degrees(30), 1.0, 0.3, 20.0) * CamMatrixf::LookingAt(lightPos, Vec3f(0, 0, 0)); Uniform<GLint>(volume_prog, "SampleCount").Set(samples); Uniform<GLfloat>(volume_prog, "Size").Set(Length(lightPos)); Uniform<Mat4f>(volume_prog, "TexProjectionMatrix").Set(texProjMat); plane_vs.Source( "#version 330\n" "in vec4 Position;" "uniform mat4 CameraMatrix, ProjectionMatrix;" "uniform mat4 TexProjectionMatrix;" "out vec2 vertChecker;" "out vec4 vertTexCoord;" "void main(void)" "{" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " Position;" " vertTexCoord = " " TexProjectionMatrix *" " Position;" " vertChecker = Position.xz;" "}" ); plane_vs.Compile(); plane_fs.Source( "#version 330\n" "uniform sampler2D LightTex;" "in vec4 vertTexCoord;" "in vec2 vertChecker;" "out vec4 fragColor;" "void main(void)" "{" " vec2 coord = vertTexCoord.st/vertTexCoord.q;" " vec4 t = texture(LightTex, coord*0.5 + 0.5);" " float i = (" " 1 +" " int(vertChecker.x+10) % 2+" " int(vertChecker.y+10) % 2" " ) % 2;" " vec3 color = vec3(0.1, 0.1, 0.1);" " color += t.rgb * (1.0 - t.a);" " color *= mix(" " vec3(0.9, 0.9, 1.0), " " vec3(0.4, 0.4, 0.9), " " i" " );" " fragColor = vec4(color, 1.0);" "}" ); plane_fs.Compile(); plane_prog.AttachShader(plane_vs); plane_prog.AttachShader(plane_fs); plane_prog.Link(); plane_prog.Use(); Uniform<Mat4f>(plane_prog, "TexProjectionMatrix").Set(texProjMat); plane.Bind(); // bind the VBO for the plane vertices plane_pos.Bind(Buffer::Target::Array); { GLfloat data[4*3] = { -9.0f, -4.0f, 9.0f, -9.0f, -4.0f, -9.0f, 9.0f, -4.0f, 9.0f, 9.0f, -4.0f, -9.0f }; Buffer::Data(Buffer::Target::Array, 4*3, data); plane_prog.Use(); VertexArrayAttrib attr(plane_prog, "Position"); attr.Setup<Vec3f>(); attr.Enable(); } Texture::Active(0); ProgramUniformSampler(volume_prog, "LightTex").Set(0); light_tex << Texture::Target::_2D << TextureMinFilter::LinearMipmapLinear << TextureMagFilter::Linear << TextureWrap::ClampToBorder << Vec4f(0.0f, 0.0f, 0.0f, 0.0f) << images::LoadTexture("flower_glass") << TextureMipmap(); gl.ClearColor(0.0f, 0.05f, 0.1f, 0.0f); gl.ClearDepth(1.0f); gl.BlendFunc(BlendFn::SrcAlpha, BlendFn::One); }
IShader* ShaderManager::GetShader( std::string shaderName, u32 shaderStages, std::vector<std::string> shaderFlags ) { u32 shaderHash = HashStringCRC32( shaderName + TextFileToString( shaderFlags ) ); shaderHash ^= shaderStages; std::unordered_map<u32, IShader*>::const_iterator it = m_CachedShaders.find( shaderHash ); if( it != m_CachedShaders.end() ) { return it->second; } Shader* shader = new Shader(); #if defined( FLAG_DEBUG ) shader_watch_t watch = { shaderName, shaderStages, shaderFlags, shader }; m_WatchedShaders[shaderName].push_back( watch ); #endif if( shaderStages & SHADER_STAGE_COMPUTE ) { shader->AddStage( uberShaderFolder + shaderName + stageComputeExtension, GL_COMPUTE_SHADER, &shaderFlags ); } else { if( shaderStages & SHADER_STAGE_VERTEX ) { shader->AddStage( uberShaderFolder + shaderName + stageVertexExtension, GL_VERTEX_SHADER, &shaderFlags ); } if( shaderStages & SHADER_STAGE_TESS_CONTROL ) { shader->AddStage( uberShaderFolder + shaderName + stageTessControlExtension, GL_TESS_CONTROL_SHADER, &shaderFlags ); } if( shaderStages & SHADER_STAGE_TESS_EVAL ) { shader->AddStage( uberShaderFolder + shaderName + stageTessEvalExtension, GL_TESS_EVALUATION_SHADER, &shaderFlags ); } if( shaderStages & SHADER_STAGE_GEOMETRY ) { shader->AddStage( uberShaderFolder + shaderName + stageGeometryExtension, GL_GEOMETRY_SHADER, &shaderFlags ); } if( shaderStages & SHADER_STAGE_FRAGMENT ) { shader->AddStage( uberShaderFolder + shaderName + stageFragmentExtension, GL_FRAGMENT_SHADER, &shaderFlags ); } } if( !shader->Compile() ) { CONSOLE_PRINT_ERROR( "%s => Failed to compile shader %s\n", __FUNCTION__, shaderName.c_str() ); SAFE_DELETE( shader ) return m_DefaultShader; }
ShaderPtr ShaderLoader::Load(const Path & fileName, bool replaceCached) { Resource<Shader> existingResource = this->GetResource(fileName); if (existingResource.resource && replaceCached == false) { GetContext().GetLogger()->log(LOG_LOG, "Found shader in cache, skipping loading."); return existingResource.resource; } ByteBufferPtr vertexBuffer = nullptr, fragmentBuffer = nullptr, geometryBuffer = nullptr; FilePtr vertexFile = GetContext().GetFileSystem()->OpenRead(Path(fileName).replace_extension(".vert")); vertexBuffer = vertexFile->ReadText(); FilePtr fragmentFile = GetContext().GetFileSystem()->OpenRead(Path(fileName).replace_extension(".frag")); fragmentBuffer = fragmentFile->ReadText(); if (GetContext().GetFileSystem()->FileExists(Path(fileName).replace_extension(".geom"))) { FilePtr geometryFile = GetContext().GetFileSystem()->OpenRead(Path(fileName).replace_extension(".geom")); if (geometryFile) { geometryBuffer = geometryFile->ReadText(); } } Path resourceName = fileName.filename(); Shader * sh = nullptr; if (!vertexBuffer && !fragmentBuffer) return existingResource.resource; if (geometryBuffer) { sh = new Shader(resourceName.generic_string(), (char*)vertexBuffer->data(), (char*)fragmentBuffer->data(), (char*)geometryBuffer->data()); } else { sh = new Shader(resourceName.generic_string(), (char*)vertexBuffer->data(), (char*)fragmentBuffer->data()); } sh->Compile(); if (sh->IsCompiledAndLinked()) { if (existingResource.resource) { RemoveResource(existingResource.path); GetContext().GetLogger()->log(LOG_LOG, "Removed cached shader: '%s'.", fileName.generic_string().c_str()); } GetContext().GetLogger()->log(LOG_LOG, "Shader loaded: '%s'.", fileName.generic_string().c_str()); Resource<Shader> res(ShaderPtr(sh), fileName); this->AddResource(res); return res.resource; } else { delete sh; if (existingResource.resource) GetContext().GetLogger()->log(LOG_ERROR, "Shader failed to load: '%s', using cached version.", resourceName.generic_string().c_str()); else GetContext().GetLogger()->log(LOG_ERROR, "Shader failed to load: '%s'.", resourceName.generic_string().c_str()); return existingResource.resource; } }
int main(){ try{ ILogger::Init(); Settings::Call().Parse(); ResourceManager::Call().AddPath("Data/shaders", "Shader"); ResourceManager::Call().AddPath("Data/textures", "Image"); { Window myWindow; Image Crate; Texture CrateTexture; Text FPSText, MousePosText; Clock FrameClock, FpsClock; Input myInput; myInput.Init(myWindow); Renderer& myRenderer = Renderer::Call(); myRenderer.Init(myWindow); Crate.LoadFromFile("crate.jpg"); CrateTexture.LoadFromImage(Crate); Light l; l.SetPosition(Vector3F(1,3,1.5)); l.SetDiffuse(Color(1.f,1.f,1.f)); l.SetRange(8); Shader ColorShader; ColorShader.Compile("shaderColor.vs", "shaderColor.fs"); ColorShader.Bind(); ColorShader.SendColor("ambientColor", myRenderer.GetSpecifications().mAmbientColor); ColorShader.SendFloat("constantAtt", l.GetAttenuationConstant()); ColorShader.SendFloat("linearAtt", l.GetAttenuationLinear()); ColorShader.SendFloat("quadraticAtt", l.GetAttenuationQuadratic()); ColorShader.SendFloat("range", l.GetRange()); ColorShader.SendVector3("lightPosition", l.GetPosition()); ColorShader.SendColor("lightColor", l.GetDiffuse()); ColorShader.UnBind(); Object obj1; obj1.MakeCube("cube", ColorShader); obj1.GetMaterial().mAmbient = Color(0.f, 0.08f, 0.08f); obj1.GetMaterial().mDiffuse = Color(0.f, 0.8f, 0.8f); obj1.GetMaterial().mSpecular = Color(0.0f, 0.5f, 0.5f); obj1.GetMaterial().mShininess = 50.f; Camera cam; cam.LookAt(Vector3F(0.5f,0,1), Vector3F(-2.5f,2,4)); FPSText.SetSize(12); FPSText.SetPosition(10,10); MousePosText.SetSize(12); MousePosText.SetPosition(10,22); while(myWindow.IsOpened()){ ElapsedTime = FrameClock.GetElapsedTime(); FrameClock.Reset(); if(FpsClock.GetElapsedTime() > 1.f){ FPSText.SetText(String(1.f/ElapsedTime)); FpsClock.Reset(); } while(myInput.GetEvent()){ if(myInput.GetEventType() == sf::Event::Closed) myWindow.Close(); if(myInput.IsKeyHit(Space)) if(!paused){ paused = true; FrameClock.Pause(); }else{ paused = false; FrameClock.Resume(); } } MousePosText.SetText(String("X : ")+myInput.GetMouseX()+" Y : "+myInput.GetMouseY()); MousePosText.Draw(); FPSText.Draw(); obj1.Draw(); myRenderer.BeginScene(myRenderer.GetSpecifications().mAmbientColor); myRenderer.Render(); myRenderer.EndScene(); } } }catch(Exception e){ std::cout << e.what() << std::endl; system("PAUSE"); } Renderer::Kill(); ResourceManager::Kill(); Settings::Kill(); ILogger::Kill(); #ifdef _DEBUG MemoryManager::Kill(); #endif return 0; }
RectangleExample(void) : vs(ShaderType::Vertex) , fs(ShaderType::Fragment) { // this could be any istream std::stringstream vs_source( "#version 330\n" "in vec2 Position;" "in vec3 Color;" "out vec3 vertColor;" "void main(void)" "{" " vertColor = Color;" " gl_Position = vec4(Position, 0.0, 1.0);" "}" ); // set the vertex shader source vs.Source(GLSLSource::FromStream(vs_source)); // compile it vs.Compile(); std::stringstream fs_source( "#version 330\n" "in vec3 vertColor;" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(vertColor, 1.0);" "}" ); // set the fragment shader source fs.Source(GLSLSource::FromStream(fs_source)); // 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 rectangle rectangle.Bind(); GLfloat rectangle_verts[8] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; // bind the VBO for the rectangle vertices verts.Bind(Buffer::Target::Array); // upload the data Buffer::Data(Buffer::Target::Array, 8, rectangle_verts); // setup the vertex attribs array for the vertices VertexAttribArray vert_attr(prog, "Position"); vert_attr.Setup<Vec2f>().Enable(); GLfloat rectangle_colors[12] = { 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; // bind the VBO for the rectangle colors colors.Bind(Buffer::Target::Array); // upload the data Buffer::Data(Buffer::Target::Array, 12, rectangle_colors); // setup the vertex attribs array for the vertices VertexAttribArray color_attr(prog, "Color"); color_attr.Setup<Vec3f>().Enable(); // gl.Disable(Capability::DepthTest); }