MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[4]) { float srgb_f[4]; linearrgb_to_srgb_v4(srgb_f, linear); F4TOCHAR4(srgb_f, srgb); }
/* byte to float pixels, input and output 4-channel RGBA */ void IMB_buffer_float_from_byte(float *rect_to, const uchar *rect_from, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from) { float tmp[4]; int x, y; /* we need valid profiles */ BLI_assert(profile_to != IB_PROFILE_NONE); BLI_assert(profile_from != IB_PROFILE_NONE); /* RGBA input */ for (y = 0; y < height; y++) { const uchar *from = rect_from + stride_from * y * 4; float *to = rect_to + ((size_t)stride_to) * y * 4; if (profile_to == profile_from) { /* no color space conversion */ for (x = 0; x < width; x++, from += 4, to += 4) { rgba_uchar_to_float(to, from); } } else if (profile_to == IB_PROFILE_LINEAR_RGB) { /* convert sRGB to linear */ if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_uchar4_predivide(to, from); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_uchar4(to, from); } } } else if (profile_to == IB_PROFILE_SRGB) { /* convert linear to sRGB */ if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { rgba_uchar_to_float(tmp, from); linearrgb_to_srgb_predivide_v4(to, tmp); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { rgba_uchar_to_float(tmp, from); linearrgb_to_srgb_v4(to, tmp); } } } } }
/* byte to byte pixels, input and output 4-channel RGBA */ void IMB_buffer_byte_from_byte(uchar *rect_to, const uchar *rect_from, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from) { float tmp[4]; int x, y; /* we need valid profiles */ BLI_assert(profile_to != IB_PROFILE_NONE); BLI_assert(profile_from != IB_PROFILE_NONE); /* always RGBA input */ for (y = 0; y < height; y++) { const uchar *from = rect_from + stride_from * y * 4; uchar *to = rect_to + stride_to * y * 4; if (profile_to == profile_from) { /* same profile, copy */ memcpy(to, from, sizeof(uchar) * 4 * width); } else if (profile_to == IB_PROFILE_LINEAR_RGB) { /* convert to sRGB to linear */ if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { rgba_uchar_to_float(tmp, from); srgb_to_linearrgb_predivide_v4(tmp, tmp); rgba_float_to_uchar(to, tmp); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { rgba_uchar_to_float(tmp, from); srgb_to_linearrgb_v4(tmp, tmp); rgba_float_to_uchar(to, tmp); } } } else if (profile_to == IB_PROFILE_SRGB) { /* convert from linear to sRGB */ if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { rgba_uchar_to_float(tmp, from); linearrgb_to_srgb_predivide_v4(tmp, tmp); rgba_float_to_uchar(to, tmp); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { rgba_uchar_to_float(tmp, from); linearrgb_to_srgb_v4(tmp, tmp); rgba_float_to_uchar(to, tmp); } } } } }
void KX_FontObject::DrawFontText() { /* Allow for some logic brick control */ if (this->GetProperty("Text")) m_text = split_string(this->GetProperty("Text")->GetText()); /* only draws the text if visible */ if (this->GetVisible() == 0) return; /* update the animated color */ this->GetObjectColor().getValue(m_color); /* Font Objects don't use the glsl shader, this color management code is copied from gpu_shader_material.glsl */ float color[4]; if (m_do_color_management) { linearrgb_to_srgb_v4(color, m_color); } else { copy_v4_v4(color, m_color); } /* HARDCODED MULTIPLICATION FACTOR - this will affect the render resolution directly */ const float RES = BGE_FONT_RES * m_resolution; const float size = m_fsize * this->NodeGetWorldScaling()[0] * RES; const float aspect = m_fsize / size; /* Get a working copy of the OpenGLMatrix to use */ double mat[16]; memcpy(mat, this->GetOpenGLMatrix(), sizeof(double)*16); /* Account for offset */ MT_Vector3 offset = this->NodeGetWorldOrientation() * m_offset * this->NodeGetWorldScaling(); mat[12] += offset[0]; mat[13] += offset[1]; mat[14] += offset[2]; /* Orient the spacing vector */ MT_Vector3 spacing = MT_Vector3(0, m_fsize*m_line_spacing, 0); spacing = this->NodeGetWorldOrientation() * spacing * this->NodeGetWorldScaling()[1]; /* Draw each line, taking spacing into consideration */ for (int i=0; i<m_text.size(); ++i) { if (i!=0) { mat[12] -= spacing[0]; mat[13] -= spacing[1]; mat[14] -= spacing[2]; } m_rasterizer->RenderText3D(m_fontid, m_text[i], int(size), m_dpi, color, mat, aspect); } }
void KX_FontObject::UpdateBuckets() { // Update datas and add mesh slot to be rendered only if the object is not culled. if (m_bVisible && m_meshUser) { if (m_pSGNode->IsDirty()) { GetOpenGLMatrix(); } // Allow for some logic brick control if (GetProperty("Text")) { m_text = split_string(GetProperty("Text")->GetText()); } // update the animated color GetObjectColor().getValue(m_color); // Font Objects don't use the glsl shader, this color management code is copied from gpu_shader_material.glsl float color[4]; if (m_do_color_management) { linearrgb_to_srgb_v4(color, m_color); } else { copy_v4_v4(color, m_color); } // HARDCODED MULTIPLICATION FACTOR - this will affect the render resolution directly const float RES = BGE_FONT_RES * m_resolution; const float size = m_fsize * NodeGetWorldScaling()[0] * RES; const float aspect = m_fsize / size; // Account for offset MT_Vector3 offset = NodeGetWorldOrientation() * m_offset * NodeGetWorldScaling(); // Orient the spacing vector MT_Vector3 spacing = NodeGetWorldOrientation() * MT_Vector3(0.0f, m_fsize * m_line_spacing, 0.0f) * NodeGetWorldScaling()[1]; RAS_TextUser *textUser = (RAS_TextUser *)m_meshUser; textUser->SetColor(MT_Vector4(color)); textUser->SetFrontFace(!m_bIsNegativeScaling); textUser->SetFontId(m_fontid); textUser->SetSize(size); textUser->SetDpi(m_dpi); textUser->SetAspect(aspect); textUser->SetOffset(offset); textUser->SetSpacing(spacing); textUser->SetTexts(m_text); textUser->ActivateMeshSlots(); } }
void PreviewOperation::executeRegion(rcti *rect, unsigned int tileNumber) { int offset; float color[4]; for (int y = rect->ymin; y < rect->ymax; y++) { offset = (y * getWidth() + rect->xmin) * 4; for (int x = rect->xmin; x < rect->xmax; x++) { float rx = floor(x / this->m_divider); float ry = floor(y / this->m_divider); color[0] = 0.0f; color[1] = 0.0f; color[2] = 0.0f; color[3] = 1.0f; this->m_input->read(color, rx, ry, COM_PS_NEAREST); linearrgb_to_srgb_v4(color, color); F4TOCHAR4(color, this->m_outputBuffer + offset); offset += 4; } } }
/* float to float pixels, output 4-channel RGBA */ void IMB_buffer_float_from_float(float *rect_to, const float *rect_from, int channels_from, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from) { int x, y; /* we need valid profiles */ BLI_assert(profile_to != IB_PROFILE_NONE); BLI_assert(profile_from != IB_PROFILE_NONE); if (channels_from == 1) { /* single channel input */ for (y = 0; y < height; y++) { const float *from = rect_from + ((size_t)stride_from) * y; float *to = rect_to + ((size_t)stride_to) * y * 4; for (x = 0; x < width; x++, from++, to += 4) { to[0] = to[1] = to[2] = to[3] = from[0]; } } } else if (channels_from == 3) { /* RGB input */ for (y = 0; y < height; y++) { const float *from = rect_from + ((size_t)stride_from) * y * 3; float *to = rect_to + ((size_t)stride_to) * y * 4; if (profile_to == profile_from) { /* no color space conversion */ for (x = 0; x < width; x++, from += 3, to += 4) { copy_v3_v3(to, from); to[3] = 1.0f; } } else if (profile_to == IB_PROFILE_LINEAR_RGB) { /* convert from sRGB to linear */ for (x = 0; x < width; x++, from += 3, to += 4) { srgb_to_linearrgb_v3_v3(to, from); to[3] = 1.0f; } } else if (profile_to == IB_PROFILE_SRGB) { /* convert from linear to sRGB */ for (x = 0; x < width; x++, from += 3, to += 4) { linearrgb_to_srgb_v3_v3(to, from); to[3] = 1.0f; } } } } else if (channels_from == 4) { /* RGBA input */ for (y = 0; y < height; y++) { const float *from = rect_from + ((size_t)stride_from) * y * 4; float *to = rect_to + ((size_t)stride_to) * y * 4; if (profile_to == profile_from) { /* same profile, copy */ memcpy(to, from, sizeof(float) * ((size_t)4) * width); } else if (profile_to == IB_PROFILE_LINEAR_RGB) { /* convert to sRGB to linear */ if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_predivide_v4(to, from); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { srgb_to_linearrgb_v4(to, from); } } } else if (profile_to == IB_PROFILE_SRGB) { /* convert from linear to sRGB */ if (predivide) { for (x = 0; x < width; x++, from += 4, to += 4) { linearrgb_to_srgb_predivide_v4(to, from); } } else { for (x = 0; x < width; x++, from += 4, to += 4) { linearrgb_to_srgb_v4(to, from); } } } } } }