AGL
A graphics library
|
The Renderer class draws meshes to the screen using shaders. More...
#include <renderer.h>
Public Member Functions | |
void | init () |
Initialize this class for drawing. More... | |
void | cleanup () |
Cleanup all resources used for drawing. More... | |
bool | initialized () const |
Return whether the Renderer is ready for drawing. More... | |
void | blendMode (BlendMode mode) |
Mode for combining colors when drawing. More... | |
Projections and view | |
void | perspective (float fovRadians, float aspect, float near, float far) |
Set the current projection to a perspective view. More... | |
void | ortho (float minx, float maxx, float miny, float maxy, float minz, float maxz) |
Set the current projection to an orthographic view. More... | |
void | lookAt (const glm::vec3 &lookfrom, const glm::vec3 &lookat, const glm::vec3 &up=glm::vec3(0.0f, 1.0f, 0.0f)) |
Set the camera position and orientation. More... | |
glm::vec3 | cameraPosition () const |
Get the current camera position. More... | |
glm::mat4 | projectionMatrix () const |
Get the current projection matrix. More... | |
glm::mat4 | viewMatrix () const |
Get the current view matrix. More... | |
Shaders | |
void | loadShader (const std::string &name, const std::string &vs, const std::string &fs) |
Load a GLSL shader from files. More... | |
void | beginShader (const std::string &shaderName) |
Set active shader to use for rendering. More... | |
void | endShader () |
Clear active shader to use for rendering. More... | |
void | beginRenderTexture (const std::string &targetName) |
Render to a texture instead of to the screen @targetName The name of the texture target. More... | |
void | endRenderTexture () |
Revert to rendering to the screen. More... | |
The name of the render target and corresponding render texture. Use | |
Load and configure a render texture target this name to activate the target and to use the rendered texture later. @slot The texture slot associated with the rendered texture @width The width in pixels of the rendered texture @height The height in pixels of the rendered texture
| |
void | loadRenderTexture (const std::string &name, int slot, int width, int height) |
void | cleanupShaders () |
Clear all active shaders. More... | |
void | setUniform (const std::string &name, float x, float y, float z) |
Set a uniform parameter in the currently active shader. More... | |
void | setUniform (const std::string &name, float x, float y, float z, float w) |
Set a uniform parameter in the currently active shader. More... | |
void | setUniform (const std::string &name, const glm::vec2 &v) |
Set a uniform parameter in the currently active shader. More... | |
void | setUniform (const std::string &name, const glm::vec3 &v) |
Set a uniform parameter in the currently active shader. More... | |
void | setUniform (const std::string &name, const glm::vec4 &v) |
Set a uniform parameter in the currently active shader. More... | |
void | setUniform (const std::string &name, const glm::mat4 &m) |
Set a uniform parameter in the currently active shader. More... | |
void | setUniform (const std::string &name, const glm::mat3 &m) |
Set a uniform parameter in the currently active shader. More... | |
void | setUniform (const std::string &name, float val) |
Set a uniform parameter in the currently active shader. More... | |
void | setUniform (const std::string &name, int val) |
Set a uniform parameter in the currently active shader. More... | |
void | setUniform (const std::string &name, bool val) |
Set a uniform parameter in the currently active shader. More... | |
void | setUniform (const std::string &name, GLuint val) |
Set a uniform parameter in the currently active shader. More... | |
void | texture (const std::string &uniformName, const std::string &textureName) |
Set a uniform sampler parameter in the currently active shader. More... | |
void | cubemap (const std::string &uniformName, const std::string &texName) |
Set a uniform sampler parameter in the currently active shader. More... | |
Loading textures | |
Textures should typically be loaded from setup() | |
void | loadTexture (const std::string &name, const std::string &filename, int slot) |
Load a texture from a file. More... | |
void | loadTexture (const std::string &name, const Image &img, int slot) |
Load a texture from an Image. | |
void | loadCubemap (const std::string &name, const std::string &dir, int slot) |
Load a cube map. | |
void | loadCubemap (const std::string &name, const std::vector< std::string > &names, int slot) |
Load a cube map. | |
void | loadCubemap (const std::string &name, const std::vector< Image > &images, int slot) |
Load a cube map. | |
Positioning | |
void | push () |
Push the current matrix onto the matrix stack. More... | |
void | pop () |
Pop the current matrix off the matrix stack. More... | |
void | identity () |
Clear the current transform. More... | |
void | scale (const glm::vec3 &xyz) |
Scale an object. More... | |
void | translate (const glm::vec3 &xyz) |
Translate an object. More... | |
void | rotate (float angleRad, const glm::vec3 &axis) |
Rotates an object. More... | |
void | transform (const glm::mat4 &trs) |
Transforms an object by the given matrix. More... | |
Drawing | |
void | sprite (const glm::vec3 &pos, const glm::vec4 &color, float size) |
Draws a sprite using a point billboard. More... | |
void | line (const glm::vec3 &p1, const glm::vec3 &p2, const glm::vec3 &c1, const glm::vec3 &c2) |
Draws a sprite using a point billboard. More... | |
void | text (const std::string &text, float x, float y) |
Draws text using the current font size and color. More... | |
void | fontColor (const glm::vec4 &color) |
Set font color for drawing text. More... | |
void | fontSize (int s) |
Set font size for drawing text. More... | |
float | textWidth (const std::string &text) |
Get the width of a string (font metrics) More... | |
float | textHeight () |
Get the height of a string (font metrics) More... | |
void | sphere () |
Draws a sphere centered at the origin with radius 0.5. More... | |
void | cube () |
Draws a cube centered at the origin with width, height, and depth equal to 1.0. More... | |
void | cone () |
Draws a cone centered at the origin, with the tip towards +Z. More... | |
void | teapot () |
Draws a teapot with largest side with width 1. More... | |
void | plane () |
Draws a plane. More... | |
void | cylinder () |
Draws a teapot with largest side with width 1. More... | |
void | capsule () |
Draws a capsule with endpoints at (0,0,0) and (0,0,1). The cap radius is 0.25 and the width is 0.5. More... | |
void | torus () |
Draws a torus. More... | |
void | skybox (float size=10.0) |
Draws a skybox (typically with a cubemap) More... | |
void | mesh (const Mesh &m) |
Draws a custom mesh. More... | |
The Renderer class draws meshes to the screen using shaders.
void agl::Renderer::beginRenderTexture | ( | const std::string & | targetName | ) |
Render to a texture instead of to the screen @targetName The name of the texture target.
After calling this function, all subsequent draw calls will be rendered to the associated texture target instead of the screen. The render target should be initialized in setup() using loadRenderTexture. Only one render target can be active at a time. Calling beginRenderTexture more than one without calling endRenderTexture will result in an error.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" using glm::vec3; class MyWindow : public agl::Window { void setup() { renderer.loadRenderTexture("teapotTex", 0, 512, 512); } void draw() { renderer.beginRenderTexture("teapotTex"); background(vec3(0.5, 1.0, 0.0)); renderer.setUniform("MainTexture.enabled", false); renderer.scale(vec3(sin(elapsedTime()))); renderer.teapot(); renderer.endRenderTexture(); background(vec3(0.3)); renderer.setUniform("MainTexture.enabled", true); renderer.texture("MainTexture.texture", "teapotTex"); renderer.identity(); renderer.rotate(elapsedTime(), vec3(1, 1, 0)); renderer.cube(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::beginShader | ( | const std::string & | shaderName | ) |
Set active shader to use for rendering.
One shadr must always be enabled for drawing to work. By default, "phong" is enabled. The shader needs to be already loaded (in setup) using loadShader
The renderer automatically loads shaders for "phong", "sprites", and "cubemap".
Usage
void agl::Renderer::blendMode | ( | BlendMode | mode | ) |
Mode for combining colors when drawing.
The alpha component controls how colors will be combined based on the current mode. Transparent objects should be drawn back to front in relation to the camera.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" using glm::vec3; class MyWindow : public agl::Window { void setup() { renderer.loadTexture("cloud", "../textures/cloud.png", 0); renderer.loadTexture("particle", "../textures/particle.png", 0); renderer.blendMode(agl::ADD); } void draw() { renderer.beginShader("sprite"); renderer.texture("image", "cloud"); renderer.sprite(vec3(-0.5f, 0.0f, 0.0f), red, 0.25f); renderer.sprite(vec3(0.5f, 0.0f, 0.0f), green, 0.25f); renderer.texture("image", "particle"); renderer.sprite(vec3(0.0f, 0.25f, 0.0f), blue, 0.25f); renderer.endShader(); } const glm::vec4 red = glm::vec4(1, 0, 0, 1); const glm::vec4 green = glm::vec4(0, 1, 0, 1); const glm::vec4 blue = glm::vec4(0, 0, 1, 1); }; int main() { MyWindow window; window.run(); }
vec3 agl::Renderer::cameraPosition | ( | ) | const |
Get the current camera position.
void agl::Renderer::capsule | ( | ) |
Draws a capsule with endpoints at (0,0,0) and (0,0,1). The cap radius is 0.25 and the width is 0.5.
void agl::Renderer::cleanup | ( | ) |
Cleanup all resources used for drawing.
This method must be called before any draw or shader calls. Window calls this method automatically. Users should not call this method.
void agl::Renderer::cleanupShaders | ( | ) |
Clear all active shaders.
Resets all active shaders (e.g. those for which beginShader has been called but endShader() hasn't). This function is called by Window at the end up each frame (users shouldn't need to call this function)
void agl::Renderer::cone | ( | ) |
Draws a cone centered at the origin, with the tip towards +Z.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" using glm::vec3; using glm::vec4; using glm::mat3; using glm::mat4; class MyWindow : public agl::Window { void draw() { // point forward direction of cone towards n // and shift base of cone to (0, 0, 0) vec3 n(1, 1, 0); vec3 z = normalize(n); vec3 x = glm::cross(vec3(0, 1, 0), z); vec3 y = glm::cross(z, x); mat4 T(vec4(x, 0), vec4(y, 0), vec4(z, 0), vec4(0.25, 0.25, 0, 1)); renderer.transform(T); renderer.cone(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::cube | ( | ) |
Draws a cube centered at the origin with width, height, and depth equal to 1.0.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { float angleRad = elapsedTime(); // angle is in radians renderer.rotate(angleRad, glm::vec3(0.707f, 0.707f, 0.0f)); renderer.cube(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::cubemap | ( | const std::string & | uniformName, |
const std::string & | texName | ||
) |
Set a uniform sampler parameter in the currently active shader.
The name should match the name of the uniform parameter. The cubemap should already be loaded. The textureName should match the key given when the texture is loaded.
// Copyright (c) 2020, Savvy Sine, Aline Normoyle // Visualize a cubemap texture using the skybox primitive #include "agl/window.h" class MyWindow : public agl::Window { void setup() { renderer.loadCubemap("cubemap", "../textures/sea", 0); perspective(glm::radians<float>(60.0f), 1.0f, 0.1f, 100.0f); } void draw() { renderer.beginShader("cubemap"); renderer.skybox(10); renderer.endShader(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::cylinder | ( | ) |
Draws a teapot with largest side with width 1.
void agl::Renderer::endRenderTexture | ( | ) |
Revert to rendering to the screen.
Calling this method without a matching beginRenderTexture method results in an error.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" using glm::vec3; class MyWindow : public agl::Window { void setup() { renderer.loadRenderTexture("teapotTex", 0, 512, 512); } void draw() { renderer.beginRenderTexture("teapotTex"); background(vec3(0.5, 1.0, 0.0)); renderer.setUniform("MainTexture.enabled", false); renderer.scale(vec3(sin(elapsedTime()))); renderer.teapot(); renderer.endRenderTexture(); background(vec3(0.3)); renderer.setUniform("MainTexture.enabled", true); renderer.texture("MainTexture.texture", "teapotTex"); renderer.identity(); renderer.rotate(elapsedTime(), vec3(1, 1, 0)); renderer.cube(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::endShader | ( | ) |
Clear active shader to use for rendering.
void agl::Renderer::fontColor | ( | const glm::vec4 & | color | ) |
Set font color for drawing text.
color | A RGBA color with values in range [0,1] |
void agl::Renderer::fontSize | ( | int | s | ) |
Set font size for drawing text.
size | The point size of the font |
void agl::Renderer::identity | ( | ) |
Clear the current transform.
Sets the current matrix to the identity matrix (e.g. no transform)
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" using glm::vec2; using glm::vec3; using glm::vec4; class MyWindow : public agl::Window { void setup() { renderer.setUniform("Fog.enabled", true); renderer.setUniform("Fog.color", vec3(0.9f)); renderer.setUniform("Fog.minDist", 5.0f); renderer.setUniform("Fog.maxDist", 9.0f); renderer.setUniform("Material.specular", vec3(0.0)); renderer.setUniform("MainTexture.enabled", true); renderer.setUniform("MainTexture.tile", vec2(20.0)); int halfw = 32; int halfh = 32; agl::Image checker(halfw*2, halfh*2); for (int i = 0; i < checker.height(); i++) { for (int j = 0; j < checker.width(); j++) { if ((i < halfh && j < halfw) || (i > halfh && j > halfw)) { checker.setVec4(i, j, vec4(0.7, 0.7, 0.7, 1)); } else { checker.setVec4(i, j, vec4(1, 1, 1, 1)); } } } renderer.loadTexture("checker", checker, 0); setupPerspectiveScene(vec3(0.0), vec3(5.0)); background(vec3(0.9f)); } void draw() { renderer.setUniform("MainTexture.enabled", true); renderer.setUniform("Material.specular", vec3(0.0)); renderer.setUniform("Material.diffuse", vec3(1)); renderer.texture("MainTexture.texture", "checker"); renderer.identity(); renderer.translate(vec3(0)); renderer.scale(vec3(20.0f)); renderer.plane(); renderer.setUniform("MainTexture.enabled", false); renderer.setUniform("Material.specular", vec3(1)); renderer.setUniform("Material.diffuse", vec3(1, 0, 0)); renderer.identity(); renderer.translate(vec3(0, 0.5, 0)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(0.5, 1, 0)); renderer.capsule(); renderer.setUniform("Material.diffuse", vec3(0.5, 1, 0)); renderer.identity(); renderer.translate(vec3(-1, 0.5, 1)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(0.5, 0.5, 0)); renderer.cone(); renderer.setUniform("Material.diffuse", vec3(1, 0, 1)); renderer.identity(); renderer.translate(vec3(0, 0.5, 1)); renderer.scale(vec3(0.5)); renderer.sphere(); renderer.setUniform("Material.diffuse", vec3(1, 1, 0.3)); renderer.identity(); renderer.translate(vec3(1, 0.5, 1)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(-0.5, 0.5, 0)); renderer.cube(); renderer.setUniform("Material.diffuse", vec3(1, 0.8, 0.1)); renderer.identity(); renderer.translate(vec3(-1, 0.5, 0)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(1, 0.5, 0)); renderer.cylinder(); renderer.setUniform("Material.diffuse", vec3(1, 0, 0.5)); renderer.identity(); renderer.translate(vec3(1, 0.5, 0)); renderer.scale(vec3(0.75)); renderer.rotate(elapsedTime(), vec3(0.5, 0.5, 0)); renderer.teapot(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::init | ( | ) |
Initialize this class for drawing.
This method must be called before any draw or shader calls. Window calls this method automatically. Users should not call this method.
bool agl::Renderer::initialized | ( | ) | const |
Return whether the Renderer is ready for drawing.
void agl::Renderer::line | ( | const glm::vec3 & | p1, |
const glm::vec3 & | p2, | ||
const glm::vec3 & | c1, | ||
const glm::vec3 & | c2 | ||
) |
Draws a sprite using a point billboard.
p1 | The location of the first point |
p2 | The location of the second point |
c1 | The color of the first point |
c2 | The color of the second point |
void agl::Renderer::loadShader | ( | const std::string & | name, |
const std::string & | vs, | ||
const std::string & | fs | ||
) |
Load a GLSL shader from files.
name | A nickname for the shader to be used in beginShader() |
vs | The vertex shader file name |
vs | The fragment shader file name |
Shaders should be loaded in setup() The default shader is "phong". The renderer automatically loads shaders for "phong", "sprites", and "cubemap". Paths are relative to the directory from which you run your application.
void agl::Renderer::loadTexture | ( | const std::string & | name, |
const std::string & | filename, | ||
int | slot | ||
) |
Load a texture from a file.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" using glm::vec3; class MyWindow : public agl::Window { void setup() { renderer.loadTexture("cloud", "../textures/cloud.png", 0); renderer.loadTexture("particle", "../textures/particle.png", 0); renderer.blendMode(agl::ADD); } void draw() { renderer.beginShader("sprite"); renderer.texture("image", "cloud"); renderer.sprite(vec3(-0.5f, 0.0f, 0.0f), red, 0.25f); renderer.sprite(vec3(0.5f, 0.0f, 0.0f), green, 0.25f); renderer.texture("image", "particle"); renderer.sprite(vec3(0.0f, 0.25f, 0.0f), blue, 0.25f); renderer.endShader(); } const glm::vec4 red = glm::vec4(1, 0, 0, 1); const glm::vec4 green = glm::vec4(0, 1, 0, 1); const glm::vec4 blue = glm::vec4(0, 0, 1, 1); }; int main() { MyWindow window; window.run(); }
void agl::Renderer::lookAt | ( | const glm::vec3 & | lookfrom, |
const glm::vec3 & | lookat, | ||
const glm::vec3 & | up = glm::vec3(0.0f, 1.0f, 0.0f) |
||
) |
Set the camera position and orientation.
lookfrom | The position of the camera (default is vec3(0,0,2)) |
lookat | The target the camera is facing (default is vec3(0,0,0)) |
up | The "up" direction of the camera (typically vec3(0,1,0)) |
If you are using Renderer from the Window class, you should call Window::lookAt instead of this method. NOTE: lookfrom and lookat should never be equal!
The current shader should define the following uniform variables
void agl::Renderer::mesh | ( | const Mesh & | m | ) |
Draws a custom mesh.
Meshes can be loaded from a file or created procedurally. Subclasses of leMesh should minimally define positions, normals, and indices. Texture (UV) coordinates and tangents may also be defined.
void agl::Renderer::ortho | ( | float | minx, |
float | maxx, | ||
float | miny, | ||
float | maxy, | ||
float | minz, | ||
float | maxz | ||
) |
Set the current projection to an orthographic view.
minx | The left side of the projection |
maxx | The right side of the projection |
miny | The bottom side of the projection |
maxy | The top side of the projection |
minz | The back side of the projection |
maxz | The front side of the projection |
If you are using Renderer from the Window class, you should call Window::ortho instead of this method.
An orthographic projection maintains parallel lines. All objects maintain their size regardless of distance to the camera. Only objects within the extents of the orthographic cuboid volume will be drawn.
The current shader should define the following uniform variables
uniform mat4 MVP A 4x4 matrix containing the product of projection * view * modelTransform
void agl::Renderer::perspective | ( | float | fovRadians, |
float | aspect, | ||
float | near, | ||
float | far | ||
) |
Set the current projection to a perspective view.
fovRadians | The field of view |
aspect | The aspect ratio (width divided by height) of the screen |
near | The distance to the near plane from the camera |
far | The distance to the far plane from the camera |
If you are using Renderer from the Window class, you should call Window::perspective instead of this method.
Perspective projections foreshorten objects should that closer objects are larger than further objects. Only objects within the view volume will be drawn. For example, objects a distance further from the far plane will not be visible.
The current shader should define the following uniform variables
uniform mat4 MVP A 4x4 matrix containing the product of projection * view * modelTransform
void agl::Renderer::plane | ( | ) |
Draws a plane.
void agl::Renderer::pop | ( | ) |
Pop the current matrix off the matrix stack.
Push the current matrix onto the matrix stack. Use push() and pop() matrix to position objects relative to other objects. For example, a character might have an arm which rotates relative to the rest of its body as it moves forward.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" using glm::vec2; using glm::vec3; using glm::vec4; class MyWindow : public agl::Window { void setup() { renderer.setUniform("Fog.enabled", true); renderer.setUniform("Fog.color", vec3(0.9f)); renderer.setUniform("Fog.minDist", 5.0f); renderer.setUniform("Fog.maxDist", 9.0f); renderer.setUniform("Material.specular", vec3(0.0)); renderer.setUniform("MainTexture.enabled", true); renderer.setUniform("MainTexture.tile", vec2(20.0)); int halfw = 32; int halfh = 32; agl::Image checker(halfw*2, halfh*2); for (int i = 0; i < checker.height(); i++) { for (int j = 0; j < checker.width(); j++) { if ((i < halfh && j < halfw) || (i > halfh && j > halfw)) { checker.setVec4(i, j, vec4(0.7, 0.7, 0.7, 1)); } else { checker.setVec4(i, j, vec4(1, 1, 1, 1)); } } } renderer.loadTexture("checker", checker, 0); setupPerspectiveScene(vec3(0.0), vec3(5.0)); background(vec3(0.9f)); } void draw() { renderer.setUniform("MainTexture.enabled", true); renderer.setUniform("Material.specular", vec3(0.0)); renderer.setUniform("Material.diffuse", vec3(1)); renderer.texture("MainTexture.texture", "checker"); renderer.identity(); renderer.translate(vec3(0)); renderer.scale(vec3(20.0f)); renderer.plane(); renderer.setUniform("MainTexture.enabled", false); renderer.setUniform("Material.specular", vec3(1)); renderer.setUniform("Material.diffuse", vec3(1, 0, 0)); renderer.identity(); renderer.translate(vec3(0, 0.5, 0)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(0.5, 1, 0)); renderer.capsule(); renderer.setUniform("Material.diffuse", vec3(0.5, 1, 0)); renderer.identity(); renderer.translate(vec3(-1, 0.5, 1)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(0.5, 0.5, 0)); renderer.cone(); renderer.setUniform("Material.diffuse", vec3(1, 0, 1)); renderer.identity(); renderer.translate(vec3(0, 0.5, 1)); renderer.scale(vec3(0.5)); renderer.sphere(); renderer.setUniform("Material.diffuse", vec3(1, 1, 0.3)); renderer.identity(); renderer.translate(vec3(1, 0.5, 1)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(-0.5, 0.5, 0)); renderer.cube(); renderer.setUniform("Material.diffuse", vec3(1, 0.8, 0.1)); renderer.identity(); renderer.translate(vec3(-1, 0.5, 0)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(1, 0.5, 0)); renderer.cylinder(); renderer.setUniform("Material.diffuse", vec3(1, 0, 0.5)); renderer.identity(); renderer.translate(vec3(1, 0.5, 0)); renderer.scale(vec3(0.75)); renderer.rotate(elapsedTime(), vec3(0.5, 0.5, 0)); renderer.teapot(); } }; int main() { MyWindow window; window.run(); }
|
inline |
Get the current projection matrix.
// Copyright 2020, Savvy Sine, Aline Normoyle #include <vector> #include "agl/window.h" using glm::vec2; using glm::vec3; using glm::vec4; using glm::mat4; class MyWindow : public agl::Window { void setup() { setCameraEnabled(false); // distance orbit camera renderer.loadTexture("particle", "../textures/particle.png", 0); renderer.blendMode(agl::ADD); _particlePos = vec3(0.0f); _lastParticlePos = _particlePos; } void draw() { renderer.beginShader("sprite"); renderer.texture("image", "particle"); renderer.sprite(_particlePos, _color, 0.5f); renderer.endShader(); } void mouseMotion(int x, int y, int dx, int dy) { if (_selected) { // convert movement into an amount to change the particle (in world space) vec2 screenDir(dx, -dy); vec2 ndcDir = (2.0f * screenDir / vec2(width(), height())); mat4 projection = renderer.projectionMatrix(); mat4 view = renderer.viewMatrix(); vec3 pDir = vec3(ndcDir, 0.0); mat4 PV = projection * view; vec3 delta = vec3(inverse(PV) * vec4(pDir, 0.0)); _particlePos = _lastParticlePos + delta; } } void mouseDown(int button, int mods) { vec2 mousePos = mousePosition(); // Convert the particle position to screen coords mat4 projection = renderer.projectionMatrix(); mat4 view = renderer.viewMatrix(); vec4 projectedPos = projection * view * vec4(_particlePos, 1.0); vec3 ndcPos = vec3(projectedPos) / projectedPos.w; vec2 screenPos = (vec2(ndcPos) + vec2(1.0)) * 0.5f; screenPos = screenPos * vec2(width(), height()); // flip y coordinate because positive Y goes down instead of up screenPos.y = height() - screenPos.y; if (length(screenPos - mousePos) < _threshold) { _color = vec4(1, 1, 0, 1); _selected = true; _lastParticlePos = _particlePos; } } void mouseUp(int button, int mods) { _color = vec4(0, 0, 1, 1); _selected = false; } private: vec3 _particlePos; vec3 _lastParticlePos; vec4 _color = vec4(0, 0, 1, 1); bool _selected = false; float _threshold = 10; }; int main() { MyWindow window; window.run(); }
void agl::Renderer::push | ( | ) |
Push the current matrix onto the matrix stack.
Use push() and pop() matrix to position objects relative to other objects. For example, a character might have an arm which rotates relative to the rest of its body as it moves forward.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" using glm::vec2; using glm::vec3; using glm::vec4; class MyWindow : public agl::Window { void setup() { renderer.setUniform("Fog.enabled", true); renderer.setUniform("Fog.color", vec3(0.9f)); renderer.setUniform("Fog.minDist", 5.0f); renderer.setUniform("Fog.maxDist", 9.0f); renderer.setUniform("Material.specular", vec3(0.0)); renderer.setUniform("MainTexture.enabled", true); renderer.setUniform("MainTexture.tile", vec2(20.0)); int halfw = 32; int halfh = 32; agl::Image checker(halfw*2, halfh*2); for (int i = 0; i < checker.height(); i++) { for (int j = 0; j < checker.width(); j++) { if ((i < halfh && j < halfw) || (i > halfh && j > halfw)) { checker.setVec4(i, j, vec4(0.7, 0.7, 0.7, 1)); } else { checker.setVec4(i, j, vec4(1, 1, 1, 1)); } } } renderer.loadTexture("checker", checker, 0); setupPerspectiveScene(vec3(0.0), vec3(5.0)); background(vec3(0.9f)); } void draw() { renderer.setUniform("MainTexture.enabled", true); renderer.setUniform("Material.specular", vec3(0.0)); renderer.setUniform("Material.diffuse", vec3(1)); renderer.texture("MainTexture.texture", "checker"); renderer.identity(); renderer.translate(vec3(0)); renderer.scale(vec3(20.0f)); renderer.plane(); renderer.setUniform("MainTexture.enabled", false); renderer.setUniform("Material.specular", vec3(1)); renderer.setUniform("Material.diffuse", vec3(1, 0, 0)); renderer.identity(); renderer.translate(vec3(0, 0.5, 0)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(0.5, 1, 0)); renderer.capsule(); renderer.setUniform("Material.diffuse", vec3(0.5, 1, 0)); renderer.identity(); renderer.translate(vec3(-1, 0.5, 1)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(0.5, 0.5, 0)); renderer.cone(); renderer.setUniform("Material.diffuse", vec3(1, 0, 1)); renderer.identity(); renderer.translate(vec3(0, 0.5, 1)); renderer.scale(vec3(0.5)); renderer.sphere(); renderer.setUniform("Material.diffuse", vec3(1, 1, 0.3)); renderer.identity(); renderer.translate(vec3(1, 0.5, 1)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(-0.5, 0.5, 0)); renderer.cube(); renderer.setUniform("Material.diffuse", vec3(1, 0.8, 0.1)); renderer.identity(); renderer.translate(vec3(-1, 0.5, 0)); renderer.scale(vec3(0.5)); renderer.rotate(elapsedTime(), vec3(1, 0.5, 0)); renderer.cylinder(); renderer.setUniform("Material.diffuse", vec3(1, 0, 0.5)); renderer.identity(); renderer.translate(vec3(1, 0.5, 0)); renderer.scale(vec3(0.75)); renderer.rotate(elapsedTime(), vec3(0.5, 0.5, 0)); renderer.teapot(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::rotate | ( | float | angleRad, |
const glm::vec3 & | axis | ||
) |
Rotates an object.
angleRad | The angle to rotate in radians |
axis | The axis to rotate around |
Rotates the object by angleRad around the given axis. Transformations are relative to the current position, size, and rotation of the object.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { float angleRad = elapsedTime(); // angle is in radians renderer.rotate(angleRad, glm::vec3(0.707f, 0.707f, 0.0f)); renderer.cube(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::scale | ( | const glm::vec3 & | xyz | ) |
Scale an object.
xyz | The proportions to resize the object. |
Changes the size of an object in each of the XYZ directions. For example, an x-component of 0.5 halves the size of the object in the X direction. Transformations are relative to the current position, size, and rotation of the object.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { renderer.scale(glm::vec3(0.75f, 0.5f, 1.0f)); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::setUniform | ( | const std::string & | name, |
bool | val | ||
) |
Set a uniform parameter in the currently active shader.
The name should match the name of the uniform parameter. Overrides correspond to different uniform variable types (which should also match).
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { // Set diffuse color in shaders/phong.fs to blue renderer.setUniform("Material.diffuse", 0.4f, 0.6f, 1.0f); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::setUniform | ( | const std::string & | name, |
const glm::mat3 & | m | ||
) |
Set a uniform parameter in the currently active shader.
The name should match the name of the uniform parameter. Overrides correspond to different uniform variable types (which should also match).
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { // Set diffuse color in shaders/phong.fs to blue renderer.setUniform("Material.diffuse", 0.4f, 0.6f, 1.0f); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::setUniform | ( | const std::string & | name, |
const glm::mat4 & | m | ||
) |
Set a uniform parameter in the currently active shader.
The name should match the name of the uniform parameter. Overrides correspond to different uniform variable types (which should also match).
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { // Set diffuse color in shaders/phong.fs to blue renderer.setUniform("Material.diffuse", 0.4f, 0.6f, 1.0f); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::setUniform | ( | const std::string & | name, |
const glm::vec2 & | v | ||
) |
Set a uniform parameter in the currently active shader.
The name should match the name of the uniform parameter. Overrides correspond to different uniform variable types (which should also match).
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { // Set diffuse color in shaders/phong.fs to blue renderer.setUniform("Material.diffuse", 0.4f, 0.6f, 1.0f); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::setUniform | ( | const std::string & | name, |
const glm::vec3 & | v | ||
) |
Set a uniform parameter in the currently active shader.
The name should match the name of the uniform parameter. Overrides correspond to different uniform variable types (which should also match).
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { // Set diffuse color in shaders/phong.fs to blue renderer.setUniform("Material.diffuse", 0.4f, 0.6f, 1.0f); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::setUniform | ( | const std::string & | name, |
const glm::vec4 & | v | ||
) |
Set a uniform parameter in the currently active shader.
The name should match the name of the uniform parameter. Overrides correspond to different uniform variable types (which should also match).
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { // Set diffuse color in shaders/phong.fs to blue renderer.setUniform("Material.diffuse", 0.4f, 0.6f, 1.0f); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::setUniform | ( | const std::string & | name, |
float | val | ||
) |
Set a uniform parameter in the currently active shader.
The name should match the name of the uniform parameter. Overrides correspond to different uniform variable types (which should also match).
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { // Set diffuse color in shaders/phong.fs to blue renderer.setUniform("Material.diffuse", 0.4f, 0.6f, 1.0f); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::setUniform | ( | const std::string & | name, |
float | x, | ||
float | y, | ||
float | z | ||
) |
Set a uniform parameter in the currently active shader.
The name should match the name of the uniform parameter. Overrides correspond to different uniform variable types (which should also match).
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { // Set diffuse color in shaders/phong.fs to blue renderer.setUniform("Material.diffuse", 0.4f, 0.6f, 1.0f); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::setUniform | ( | const std::string & | name, |
float | x, | ||
float | y, | ||
float | z, | ||
float | w | ||
) |
Set a uniform parameter in the currently active shader.
The name should match the name of the uniform parameter. Overrides correspond to different uniform variable types (which should also match).
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { // Set diffuse color in shaders/phong.fs to blue renderer.setUniform("Material.diffuse", 0.4f, 0.6f, 1.0f); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::setUniform | ( | const std::string & | name, |
GLuint | val | ||
) |
Set a uniform parameter in the currently active shader.
The name should match the name of the uniform parameter. Overrides correspond to different uniform variable types (which should also match).
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { // Set diffuse color in shaders/phong.fs to blue renderer.setUniform("Material.diffuse", 0.4f, 0.6f, 1.0f); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::setUniform | ( | const std::string & | name, |
int | val | ||
) |
Set a uniform parameter in the currently active shader.
The name should match the name of the uniform parameter. Overrides correspond to different uniform variable types (which should also match).
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { // Set diffuse color in shaders/phong.fs to blue renderer.setUniform("Material.diffuse", 0.4f, 0.6f, 1.0f); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::skybox | ( | float | size = 10.0 | ) |
Draws a skybox (typically with a cubemap)
// Copyright (c) 2020, Savvy Sine, Aline Normoyle // Visualize a cubemap texture using the skybox primitive #include "agl/window.h" class MyWindow : public agl::Window { void setup() { renderer.loadCubemap("cubemap", "../textures/sea", 0); perspective(glm::radians<float>(60.0f), 1.0f, 0.1f, 100.0f); } void draw() { renderer.beginShader("cubemap"); renderer.skybox(10); renderer.endShader(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::sphere | ( | ) |
Draws a sphere centered at the origin with radius 0.5.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::sprite | ( | const glm::vec3 & | pos, |
const glm::vec4 & | color, | ||
float | size | ||
) |
Draws a sprite using a point billboard.
pos | The location of the center of the sprite |
color | The color of the sprite |
size | The size (width/height) of the billboard |
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" using glm::vec3; class MyWindow : public agl::Window { void setup() { renderer.loadTexture("cloud", "../textures/cloud.png", 0); renderer.loadTexture("particle", "../textures/particle.png", 0); renderer.blendMode(agl::ADD); } void draw() { renderer.beginShader("sprite"); renderer.texture("image", "cloud"); renderer.sprite(vec3(-0.5f, 0.0f, 0.0f), red, 0.25f); renderer.sprite(vec3(0.5f, 0.0f, 0.0f), green, 0.25f); renderer.texture("image", "particle"); renderer.sprite(vec3(0.0f, 0.25f, 0.0f), blue, 0.25f); renderer.endShader(); } const glm::vec4 red = glm::vec4(1, 0, 0, 1); const glm::vec4 green = glm::vec4(0, 1, 0, 1); const glm::vec4 blue = glm::vec4(0, 0, 1, 1); }; int main() { MyWindow window; window.run(); }
void agl::Renderer::teapot | ( | ) |
Draws a teapot with largest side with width 1.
void agl::Renderer::text | ( | const std::string & | text, |
float | x, | ||
float | y | ||
) |
Draws text using the current font size and color.
text | The phrase to display |
x | The x-location of the text (left-most point). Range [0, screenwidth] |
y | The y-location of the text (bottom-most point). Range [0, screenheight] |
float agl::Renderer::textHeight | ( | ) |
Get the height of a string (font metrics)
void agl::Renderer::texture | ( | const std::string & | uniformName, |
const std::string & | textureName | ||
) |
Set a uniform sampler parameter in the currently active shader.
The name should match the name of the uniform parameter. The texture should already be loaded. The textureName should match the key given when the texture is loaded.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" using glm::vec3; class MyWindow : public agl::Window { void setup() { renderer.loadTexture("cloud", "../textures/cloud.png", 0); renderer.loadTexture("particle", "../textures/particle.png", 0); renderer.blendMode(agl::ADD); } void draw() { renderer.beginShader("sprite"); renderer.texture("image", "cloud"); renderer.sprite(vec3(-0.5f, 0.0f, 0.0f), red, 0.25f); renderer.sprite(vec3(0.5f, 0.0f, 0.0f), green, 0.25f); renderer.texture("image", "particle"); renderer.sprite(vec3(0.0f, 0.25f, 0.0f), blue, 0.25f); renderer.endShader(); } const glm::vec4 red = glm::vec4(1, 0, 0, 1); const glm::vec4 green = glm::vec4(0, 1, 0, 1); const glm::vec4 blue = glm::vec4(0, 0, 1, 1); }; int main() { MyWindow window; window.run(); }
float agl::Renderer::textWidth | ( | const std::string & | text | ) |
Get the width of a string (font metrics)
text | The phrase to display |
void agl::Renderer::torus | ( | ) |
Draws a torus.
void agl::Renderer::transform | ( | const glm::mat4 & | trs | ) |
Transforms an object by the given matrix.
trs | The matrix transform |
Typically this matrix will be the product of translation * rotate * scale matrices. Transformations are relative to the current position, size, and rotation of the object.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" using glm::vec3; using glm::vec4; using glm::mat3; using glm::mat4; class MyWindow : public agl::Window { void draw() { // point forward direction of cone towards n // and shift base of cone to (0, 0, 0) vec3 n(1, 1, 0); vec3 z = normalize(n); vec3 x = glm::cross(vec3(0, 1, 0), z); vec3 y = glm::cross(z, x); mat4 T(vec4(x, 0), vec4(y, 0), vec4(z, 0), vec4(0.25, 0.25, 0, 1)); renderer.transform(T); renderer.cone(); } }; int main() { MyWindow window; window.run(); }
void agl::Renderer::translate | ( | const glm::vec3 & | xyz | ) |
Translate an object.
xyz | The direction to move the object. |
Moves the object in each of the XYZ directions. For example, an x-component of 10 will move the object in the positive X direction. Transformations are relative to the current position, size, and rotation of the object.
// Copyright 2020, Savvy Sine, Aline Normoyle #include "agl/window.h" class MyWindow : public agl::Window { void draw() { float x = sin(elapsedTime()); renderer.translate(glm::vec3(x, 0.0, 0.0)); renderer.sphere(); } }; int main() { MyWindow window; window.run(); }
|
inline |
Get the current view matrix.
// Copyright 2020, Savvy Sine, Aline Normoyle #include <vector> #include "agl/window.h" using glm::vec2; using glm::vec3; using glm::vec4; using glm::mat4; class MyWindow : public agl::Window { void setup() { setCameraEnabled(false); // distance orbit camera renderer.loadTexture("particle", "../textures/particle.png", 0); renderer.blendMode(agl::ADD); _particlePos = vec3(0.0f); _lastParticlePos = _particlePos; } void draw() { renderer.beginShader("sprite"); renderer.texture("image", "particle"); renderer.sprite(_particlePos, _color, 0.5f); renderer.endShader(); } void mouseMotion(int x, int y, int dx, int dy) { if (_selected) { // convert movement into an amount to change the particle (in world space) vec2 screenDir(dx, -dy); vec2 ndcDir = (2.0f * screenDir / vec2(width(), height())); mat4 projection = renderer.projectionMatrix(); mat4 view = renderer.viewMatrix(); vec3 pDir = vec3(ndcDir, 0.0); mat4 PV = projection * view; vec3 delta = vec3(inverse(PV) * vec4(pDir, 0.0)); _particlePos = _lastParticlePos + delta; } } void mouseDown(int button, int mods) { vec2 mousePos = mousePosition(); // Convert the particle position to screen coords mat4 projection = renderer.projectionMatrix(); mat4 view = renderer.viewMatrix(); vec4 projectedPos = projection * view * vec4(_particlePos, 1.0); vec3 ndcPos = vec3(projectedPos) / projectedPos.w; vec2 screenPos = (vec2(ndcPos) + vec2(1.0)) * 0.5f; screenPos = screenPos * vec2(width(), height()); // flip y coordinate because positive Y goes down instead of up screenPos.y = height() - screenPos.y; if (length(screenPos - mousePos) < _threshold) { _color = vec4(1, 1, 0, 1); _selected = true; _lastParticlePos = _particlePos; } } void mouseUp(int button, int mods) { _color = vec4(0, 0, 1, 1); _selected = false; } private: vec3 _particlePos; vec3 _lastParticlePos; vec4 _color = vec4(0, 0, 1, 1); bool _selected = false; float _threshold = 10; }; int main() { MyWindow window; window.run(); }