Select Git revision
opengl_image_buffer_data.cpp
opengl_image_buffer_data.cpp 4.01 KiB
//------------------------------------------------------------------------------
// Project Phoenix
//
// Copyright (c) 2017-2018 RWTH Aachen University, Germany,
// Virtual Reality & Immersive Visualization Group.
//------------------------------------------------------------------------------
// License
//
// Licensed under the 3-Clause BSD License (the "License");
// you may not use this file except in compliance with the License.
// See the file LICENSE for the full text.
// You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//------------------------------------------------------------------------------
#include "opengl_image_buffer_data.hpp"
#include <algorithm>
#include <memory>
#include <string>
namespace phx {
template <>
void phx::OpenGLImageBufferData<phx::OpenGLImageBufferDataType_RGB>::
ReadColorPixels(bool read_front_buffer) {
if (read_front_buffer) glReadBuffer(GL_FRONT_LEFT);
glReadPixels(0, 0, static_cast<GLsizei>(width_),
static_cast<GLsizei>(height_), GL_RGB, GL_UNSIGNED_BYTE,
buffer_data_.data());
}
template <>
void phx::OpenGLImageBufferData<phx::OpenGLImageBufferDataType_RGBA>::
ReadColorPixels(bool read_front_buffer) {
if (read_front_buffer) glReadBuffer(GL_FRONT_LEFT);
glReadPixels(0, 0, static_cast<GLsizei>(width_),
static_cast<GLsizei>(height_), GL_RGBA, GL_UNSIGNED_BYTE,
buffer_data_.data());
}
template <>
void phx::OpenGLImageBufferData<phx::OpenGLImageBufferDataType_Byte>::
ReadDepthPixels(bool read_front_buffer) {
if (read_front_buffer) glReadBuffer(GL_FRONT_LEFT);
glReadPixels(0, 0, static_cast<GLsizei>(width_),
static_cast<GLsizei>(height_), GL_DEPTH_COMPONENT,
GL_UNSIGNED_BYTE, buffer_data_.data());
}
template <>
void phx::OpenGLImageBufferData<phx::OpenGLImageBufferDataType_Float32>::
ReadDepthPixels(bool read_front_buffer) {
if (read_front_buffer) glReadBuffer(GL_FRONT_LEFT);
glReadPixels(0, 0, static_cast<GLsizei>(width_),
static_cast<GLsizei>(height_), GL_DEPTH_COMPONENT, GL_FLOAT,
buffer_data_.data());
}
template <>
std::unique_ptr<phx::Image> phx::OpenGLImageBufferData<
phx::OpenGLImageBufferDataType_Float32>::CreateImage() const {
// create empty image
auto image =
std::make_unique<Image>(std::array<std::size_t, 2>{{width_, height_}}, 8);
// copy data, convert float to byte
const auto image_data_pointer = image->GetPixels();
for (std::size_t i = 0; i < image_data_pointer.second; ++i) {
const auto pixel_pointer =
reinterpret_cast<const float*>(&buffer_data_[i * 4]);
image_data_pointer.first[i] = static_cast<unsigned char>(
std::max(0.f, std::min(255.f, std::round(*pixel_pointer * 255.f))));
}
return image;
}
template <>
std::unique_ptr<OpenGLImageBufferData<OpenGLImageBufferDataType_Float32>>
phx::OpenGLImageBufferData<OpenGLImageBufferDataType_Float32>::CreateFromImage(
phx::Image* image) {
// check image type
if (image->GetBitsPerPixel() != 8) image->To8Bits();
// copy width, height and data
auto dimensions = image->GetDimensions();
auto buffer = std::make_unique<
OpenGLImageBufferData<OpenGLImageBufferDataType_Float32>>(dimensions[0],
dimensions[1]);
const auto image_data_pointer = image->GetPixels();
auto& buffer_ref = *buffer.get();
for (std::size_t i = 0; i < image_data_pointer.second; ++i) {
float* float_pointer =
reinterpret_cast<float*>(&buffer_ref.buffer_data_[i * 4]);
*float_pointer = static_cast<float>(image_data_pointer.first[i]) / 255.f;
}
return buffer;
}
} // namespace phx