1 #include "../StdAfx.h"
\r
3 #include "gpu_frame.h"
\r
4 #include "../../common/image/copy.h"
\r
5 #include "../../common/gl/utility.h"
\r
9 struct gpu_frame::implementation
\r
11 implementation(size_t width, size_t height)
\r
12 : pbo_(0), data_(nullptr), width_(width), height_(height), size_(width*height*4), reading_(false), texture_(0), alpha_(1.0f)
\r
19 glDeleteBuffers(1, &pbo_);
\r
21 glDeleteTextures(1, &texture_);
\r
27 CASPAR_GL_CHECK(glGenBuffers(1, &pbo_));
\r
35 CASPAR_GL_CHECK(glGenTextures(1, &texture_));
\r
37 CASPAR_GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_));
\r
39 CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
\r
40 CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
\r
41 CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
\r
42 CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
\r
44 CASPAR_GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width_, height_, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
\r
47 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo()));
\r
48 if(data_ != nullptr)
\r
50 CASPAR_GL_CHECK(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
\r
53 CASPAR_GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_));
\r
54 CASPAR_GL_CHECK(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
\r
55 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
\r
60 if(data_ != nullptr)
\r
62 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo()));
\r
63 CASPAR_GL_CHECK(glBufferData(GL_PIXEL_UNPACK_BUFFER, size_, NULL, GL_STREAM_DRAW));
\r
64 void* ptr = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
\r
65 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
\r
66 data_ = reinterpret_cast<unsigned char*>(ptr);
\r
68 BOOST_THROW_EXCEPTION(std::bad_alloc());
\r
72 void read_lock(GLenum mode)
\r
74 CASPAR_GL_CHECK(glReadBuffer(mode));
\r
75 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo()));
\r
76 if(data_ != nullptr)
\r
78 CASPAR_GL_CHECK(glUnmapBuffer(GL_PIXEL_PACK_BUFFER));
\r
81 CASPAR_GL_CHECK(glBufferData(GL_PIXEL_PACK_BUFFER, size_, NULL, GL_STREAM_READ));
\r
82 CASPAR_GL_CHECK(glReadPixels(0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
\r
83 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
\r
89 if(data_ != nullptr || !reading_)
\r
91 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo()));
\r
92 void* ptr = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
\r
93 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
\r
94 data_ = reinterpret_cast<unsigned char*>(ptr);
\r
96 BOOST_THROW_EXCEPTION(std::bad_alloc());
\r
104 glTranslatef(x_*2.0f, y_*2.0f, 0.0f);
\r
105 glColor4f(1.0f, 1.0f, 1.0f, alpha_);
\r
106 CASPAR_GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_));
\r
108 glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
\r
109 glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
\r
110 glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f);
\r
111 glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
\r
116 unsigned char* data()
\r
118 if(data_ == nullptr)
\r
119 BOOST_THROW_EXCEPTION(invalid_operation());
\r
125 audio_data_.clear();
\r
134 unsigned char* data_;
\r
139 std::vector<short> audio_data_;
\r
146 gpu_frame::gpu_frame(size_t width, size_t height) : impl_(new implementation(width, height)){}
\r
147 void gpu_frame::write_lock(){impl_->write_lock();}
\r
148 bool gpu_frame::write_unlock(){return impl_->write_unlock();}
\r
149 void gpu_frame::read_lock(GLenum mode){impl_->read_lock(mode);}
\r
150 bool gpu_frame::read_unlock(){return impl_->read_unlock();}
\r
151 void gpu_frame::draw(){impl_->draw();}
\r
152 unsigned char* gpu_frame::data(){return impl_->data();}
\r
153 size_t gpu_frame::size() const { return impl_->size_; }
\r
154 size_t gpu_frame::width() const { return impl_->width_;}
\r
155 size_t gpu_frame::height() const { return impl_->height_;}
\r
156 const std::vector<short>& gpu_frame::audio_data() const { return impl_->audio_data_; }
\r
157 std::vector<short>& gpu_frame::audio_data() { return impl_->audio_data_; }
\r
158 void gpu_frame::reset(){impl_->reset();}
\r
159 float gpu_frame::alpha() const{ return impl_->alpha_;}
\r
160 void gpu_frame::alpha(float value){ impl_->alpha_ = value;}
\r
161 float gpu_frame::x() const { return impl_->x_;}
\r
162 float gpu_frame::y() const { return impl_->y_;}
\r
163 void gpu_frame::translate(float x, float y) { impl_->x_ += x; impl_->y_ += y; }
\r