| #include "opengl/opengl_render_paint.hpp" |
| #include "shapes/paint/color.hpp" |
| #include "opengl/opengl_renderer.hpp" |
| #include "opengl/opengl_render_path.hpp" |
| |
| using namespace rive; |
| |
| void fillColorBuffer(float* buffer, unsigned int value) |
| { |
| buffer[0] = colorRed(value) / 255.0f; |
| buffer[1] = colorGreen(value) / 255.0f; |
| buffer[2] = colorBlue(value) / 255.0f; |
| buffer[3] = colorAlpha(value) / 255.0f; |
| } |
| |
| void OpenGLRenderPaint::style(RenderPaintStyle style) { m_PaintStyle = style; } |
| |
| void OpenGLRenderPaint::color(unsigned int value) |
| { |
| fillColorBuffer(m_Color, value); |
| } |
| |
| void OpenGLRenderPaint::thickness(float value) {} |
| |
| void OpenGLRenderPaint::join(StrokeJoin value) {} |
| |
| void OpenGLRenderPaint::cap(StrokeCap value) {} |
| |
| void OpenGLRenderPaint::blendMode(BlendMode value) {} |
| |
| void OpenGLRenderPaint::linearGradient(float sx, float sy, float ex, float ey) |
| { |
| if (m_Gradient == nullptr) |
| { |
| m_Gradient = new OpenGLGradient(1); |
| } |
| m_Gradient->position(sx, sy, ex, ey); |
| } |
| |
| void OpenGLRenderPaint::radialGradient(float sx, float sy, float ex, float ey) |
| { |
| if (m_Gradient == nullptr) |
| { |
| m_Gradient = new OpenGLGradient(2); |
| } |
| m_Gradient->position(sx, sy, ex, ey); |
| } |
| |
| void OpenGLRenderPaint::addStop(unsigned int color, float stop) |
| { |
| m_Gradient->addStop(color, stop); |
| } |
| |
| void OpenGLRenderPaint::completeGradient() {} |
| |
| OpenGLRenderPaint::~OpenGLRenderPaint() { delete m_Gradient; } |
| |
| bool OpenGLRenderPaint::doesDraw() const |
| { |
| return true; |
| return m_Color[3] > 0.0f && |
| (m_Gradient == nullptr || m_Gradient->m_IsVisible); |
| } |
| |
| void OpenGLRenderPaint::draw(OpenGLRenderer* renderer, |
| const Mat2D& transform, |
| OpenGLRenderPath* path) |
| { |
| uint32_t type = 0; |
| if (m_Gradient != nullptr) |
| { |
| type = m_Gradient->m_Type; |
| m_Gradient->bind(renderer); |
| } |
| |
| glUniform1i(renderer->fillTypeUniformIndex(), type); |
| glUniform4fv(renderer->colorUniformIndex(), 1, m_Color); |
| |
| path->cover(renderer, transform); |
| } |
| |
| OpenGLGradient::OpenGLGradient(int type) : m_Type(type) {} |
| |
| void OpenGLGradient::position(float sx, float sy, float ex, float ey) |
| { |
| m_Colors.clear(); |
| m_Stops.clear(); |
| m_IsVisible = false; |
| m_Position[0] = sx; |
| m_Position[1] = sy; |
| m_Position[2] = ex; |
| m_Position[3] = ey; |
| } |
| |
| void OpenGLGradient::bind(OpenGLRenderer* renderer) |
| { |
| auto numberOfStops = m_Stops.size(); |
| |
| glUniform1i(renderer->stopCountUniformIndex(), numberOfStops); |
| glUniform4fv( |
| renderer->stopColorsUniformIndex(), numberOfStops, &m_Colors[0]); |
| glUniform1fv(renderer->stopsUniformIndex(), numberOfStops, &m_Stops[0]); |
| glUniform4fv(renderer->gradientPositionUniformIndex(), 1, &m_Position[0]); |
| } |
| |
| void OpenGLGradient::addStop(unsigned int color, float stop) |
| { |
| auto index = m_Colors.size(); |
| m_Colors.resize(index + 4); |
| |
| fillColorBuffer(&m_Colors[index], color); |
| if (m_Colors[index + 3] > 0.0f) |
| { |
| m_IsVisible = true; |
| } |
| m_Stops.push_back(stop); |
| } |