Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/blender/blender_display_driver.cpp')
-rw-r--r--intern/cycles/blender/blender_display_driver.cpp754
1 files changed, 0 insertions, 754 deletions
diff --git a/intern/cycles/blender/blender_display_driver.cpp b/intern/cycles/blender/blender_display_driver.cpp
deleted file mode 100644
index f55a8ce8c4e..00000000000
--- a/intern/cycles/blender/blender_display_driver.cpp
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * Copyright 2021 Blender Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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 "blender/blender_display_driver.h"
-
-#include "device/device.h"
-#include "util/util_logging.h"
-#include "util/util_opengl.h"
-
-extern "C" {
-struct RenderEngine;
-
-bool RE_engine_has_render_context(struct RenderEngine *engine);
-void RE_engine_render_context_enable(struct RenderEngine *engine);
-void RE_engine_render_context_disable(struct RenderEngine *engine);
-
-bool DRW_opengl_context_release();
-void DRW_opengl_context_activate(bool drw_state);
-
-void *WM_opengl_context_create();
-void WM_opengl_context_activate(void *gl_context);
-void WM_opengl_context_dispose(void *gl_context);
-void WM_opengl_context_release(void *context);
-}
-
-CCL_NAMESPACE_BEGIN
-
-/* --------------------------------------------------------------------
- * BlenderDisplayShader.
- */
-
-unique_ptr<BlenderDisplayShader> BlenderDisplayShader::create(BL::RenderEngine &b_engine,
- BL::Scene &b_scene)
-{
- if (b_engine.support_display_space_shader(b_scene)) {
- return make_unique<BlenderDisplaySpaceShader>(b_engine, b_scene);
- }
-
- return make_unique<BlenderFallbackDisplayShader>();
-}
-
-int BlenderDisplayShader::get_position_attrib_location()
-{
- if (position_attribute_location_ == -1) {
- const uint shader_program = get_shader_program();
- position_attribute_location_ = glGetAttribLocation(shader_program, position_attribute_name);
- }
- return position_attribute_location_;
-}
-
-int BlenderDisplayShader::get_tex_coord_attrib_location()
-{
- if (tex_coord_attribute_location_ == -1) {
- const uint shader_program = get_shader_program();
- tex_coord_attribute_location_ = glGetAttribLocation(shader_program, tex_coord_attribute_name);
- }
- return tex_coord_attribute_location_;
-}
-
-/* --------------------------------------------------------------------
- * BlenderFallbackDisplayShader.
- */
-
-/* TODO move shaders to standalone .glsl file. */
-static const char *FALLBACK_VERTEX_SHADER =
- "#version 330\n"
- "uniform vec2 fullscreen;\n"
- "in vec2 texCoord;\n"
- "in vec2 pos;\n"
- "out vec2 texCoord_interp;\n"
- "\n"
- "vec2 normalize_coordinates()\n"
- "{\n"
- " return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n"
- "}\n"
- "\n"
- "void main()\n"
- "{\n"
- " gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n"
- " texCoord_interp = texCoord;\n"
- "}\n\0";
-
-static const char *FALLBACK_FRAGMENT_SHADER =
- "#version 330\n"
- "uniform sampler2D image_texture;\n"
- "in vec2 texCoord_interp;\n"
- "out vec4 fragColor;\n"
- "\n"
- "void main()\n"
- "{\n"
- " fragColor = texture(image_texture, texCoord_interp);\n"
- "}\n\0";
-
-static void shader_print_errors(const char *task, const char *log, const char *code)
-{
- LOG(ERROR) << "Shader: " << task << " error:";
- LOG(ERROR) << "===== shader string ====";
-
- stringstream stream(code);
- string partial;
-
- int line = 1;
- while (getline(stream, partial, '\n')) {
- if (line < 10) {
- LOG(ERROR) << " " << line << " " << partial;
- }
- else {
- LOG(ERROR) << line << " " << partial;
- }
- line++;
- }
- LOG(ERROR) << log;
-}
-
-static int compile_fallback_shader(void)
-{
- const struct Shader {
- const char *source;
- const GLenum type;
- } shaders[2] = {{FALLBACK_VERTEX_SHADER, GL_VERTEX_SHADER},
- {FALLBACK_FRAGMENT_SHADER, GL_FRAGMENT_SHADER}};
-
- const GLuint program = glCreateProgram();
-
- for (int i = 0; i < 2; i++) {
- const GLuint shader = glCreateShader(shaders[i].type);
-
- string source_str = shaders[i].source;
- const char *c_str = source_str.c_str();
-
- glShaderSource(shader, 1, &c_str, NULL);
- glCompileShader(shader);
-
- GLint compile_status;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
-
- if (!compile_status) {
- GLchar log[5000];
- GLsizei length = 0;
- glGetShaderInfoLog(shader, sizeof(log), &length, log);
- shader_print_errors("compile", log, c_str);
- return 0;
- }
-
- glAttachShader(program, shader);
- }
-
- /* Link output. */
- glBindFragDataLocation(program, 0, "fragColor");
-
- /* Link and error check. */
- glLinkProgram(program);
-
- /* TODO(sergey): Find a way to nicely de-duplicate the error checking. */
- GLint link_status;
- glGetProgramiv(program, GL_LINK_STATUS, &link_status);
- if (!link_status) {
- GLchar log[5000];
- GLsizei length = 0;
- /* TODO(sergey): Is it really program passed to glGetShaderInfoLog? */
- glGetShaderInfoLog(program, sizeof(log), &length, log);
- shader_print_errors("linking", log, FALLBACK_VERTEX_SHADER);
- shader_print_errors("linking", log, FALLBACK_FRAGMENT_SHADER);
- return 0;
- }
-
- return program;
-}
-
-void BlenderFallbackDisplayShader::bind(int width, int height)
-{
- create_shader_if_needed();
-
- if (!shader_program_) {
- return;
- }
-
- glUseProgram(shader_program_);
- glUniform1i(image_texture_location_, 0);
- glUniform2f(fullscreen_location_, width, height);
-}
-
-void BlenderFallbackDisplayShader::unbind()
-{
-}
-
-uint BlenderFallbackDisplayShader::get_shader_program()
-{
- return shader_program_;
-}
-
-void BlenderFallbackDisplayShader::create_shader_if_needed()
-{
- if (shader_program_ || shader_compile_attempted_) {
- return;
- }
-
- shader_compile_attempted_ = true;
-
- shader_program_ = compile_fallback_shader();
- if (!shader_program_) {
- return;
- }
-
- glUseProgram(shader_program_);
-
- image_texture_location_ = glGetUniformLocation(shader_program_, "image_texture");
- if (image_texture_location_ < 0) {
- LOG(ERROR) << "Shader doesn't contain the 'image_texture' uniform.";
- destroy_shader();
- return;
- }
-
- fullscreen_location_ = glGetUniformLocation(shader_program_, "fullscreen");
- if (fullscreen_location_ < 0) {
- LOG(ERROR) << "Shader doesn't contain the 'fullscreen' uniform.";
- destroy_shader();
- return;
- }
-}
-
-void BlenderFallbackDisplayShader::destroy_shader()
-{
- glDeleteProgram(shader_program_);
- shader_program_ = 0;
-}
-
-/* --------------------------------------------------------------------
- * BlenderDisplaySpaceShader.
- */
-
-BlenderDisplaySpaceShader::BlenderDisplaySpaceShader(BL::RenderEngine &b_engine,
- BL::Scene &b_scene)
- : b_engine_(b_engine), b_scene_(b_scene)
-{
- DCHECK(b_engine_.support_display_space_shader(b_scene_));
-}
-
-void BlenderDisplaySpaceShader::bind(int /*width*/, int /*height*/)
-{
- b_engine_.bind_display_space_shader(b_scene_);
-}
-
-void BlenderDisplaySpaceShader::unbind()
-{
- b_engine_.unbind_display_space_shader();
-}
-
-uint BlenderDisplaySpaceShader::get_shader_program()
-{
- if (!shader_program_) {
- glGetIntegerv(GL_CURRENT_PROGRAM, reinterpret_cast<int *>(&shader_program_));
- }
-
- if (!shader_program_) {
- LOG(ERROR) << "Error retrieving shader program for display space shader.";
- }
-
- return shader_program_;
-}
-
-/* --------------------------------------------------------------------
- * BlenderDisplayDriver.
- */
-
-BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene)
- : b_engine_(b_engine), display_shader_(BlenderDisplayShader::create(b_engine, b_scene))
-{
- /* Create context while on the main thread. */
- gl_context_create();
-}
-
-BlenderDisplayDriver::~BlenderDisplayDriver()
-{
- gl_resources_destroy();
-}
-
-/* --------------------------------------------------------------------
- * Update procedure.
- */
-
-bool BlenderDisplayDriver::update_begin(const Params &params,
- int texture_width,
- int texture_height)
-{
- /* Note that it's the responsibility of BlenderDisplayDriver to ensure updating and drawing
- * the texture does not happen at the same time. This is achieved indirectly.
- *
- * When enabling the OpenGL context, it uses an internal mutex lock DST.gl_context_lock.
- * This same lock is also held when do_draw() is called, which together ensure mutual
- * exclusion.
- *
- * This locking is not performed on the Cycles side, because that would cause lock inversion. */
- if (!gl_context_enable()) {
- return false;
- }
-
- if (gl_render_sync_) {
- glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
- }
-
- if (!gl_texture_resources_ensure()) {
- gl_context_disable();
- return false;
- }
-
- /* Update texture dimensions if needed. */
- if (texture_.width != texture_width || texture_.height != texture_height) {
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
- glTexImage2D(
- GL_TEXTURE_2D, 0, GL_RGBA16F, texture_width, texture_height, 0, GL_RGBA, GL_HALF_FLOAT, 0);
- texture_.width = texture_width;
- texture_.height = texture_height;
- glBindTexture(GL_TEXTURE_2D, 0);
-
- /* Texture did change, and no pixel storage was provided. Tag for an explicit zeroing out to
- * avoid undefined content. */
- texture_.need_clear = true;
- }
-
- /* Update PBO dimensions if needed.
- *
- * NOTE: Allocate the PBO for the the size which will fit the final render resolution (as in,
- * at a resolution divider 1. This was we don't need to recreate graphics interoperability
- * objects which are costly and which are tied to the specific underlying buffer size.
- * The downside of this approach is that when graphics interoperability is not used we are
- * sending too much data to GPU when resolution divider is not 1. */
- /* TODO(sergey): Investigate whether keeping the PBO exact size of the texture makes non-interop
- * mode faster. */
- const int buffer_width = params.full_size.x;
- const int buffer_height = params.full_size.y;
- if (texture_.buffer_width != buffer_width || texture_.buffer_height != buffer_height) {
- const size_t size_in_bytes = sizeof(half4) * buffer_width * buffer_height;
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
- glBufferData(GL_PIXEL_UNPACK_BUFFER, size_in_bytes, 0, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-
- texture_.buffer_width = buffer_width;
- texture_.buffer_height = buffer_height;
- }
-
- /* New content will be provided to the texture in one way or another, so mark this in a
- * centralized place. */
- texture_.need_update = true;
-
- return true;
-}
-
-void BlenderDisplayDriver::update_end()
-{
- gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
- glFlush();
-
- gl_context_disable();
-}
-
-/* --------------------------------------------------------------------
- * Texture buffer mapping.
- */
-
-half4 *BlenderDisplayDriver::map_texture_buffer()
-{
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
-
- half4 *mapped_rgba_pixels = reinterpret_cast<half4 *>(
- glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
- if (!mapped_rgba_pixels) {
- LOG(ERROR) << "Error mapping BlenderDisplayDriver pixel buffer object.";
- }
-
- if (texture_.need_clear) {
- const int64_t texture_width = texture_.width;
- const int64_t texture_height = texture_.height;
- memset(reinterpret_cast<void *>(mapped_rgba_pixels),
- 0,
- texture_width * texture_height * sizeof(half4));
- texture_.need_clear = false;
- }
-
- return mapped_rgba_pixels;
-}
-
-void BlenderDisplayDriver::unmap_texture_buffer()
-{
- glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
-
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-}
-
-/* --------------------------------------------------------------------
- * Graphics interoperability.
- */
-
-BlenderDisplayDriver::GraphicsInterop BlenderDisplayDriver::graphics_interop_get()
-{
- GraphicsInterop interop_dst;
-
- interop_dst.buffer_width = texture_.buffer_width;
- interop_dst.buffer_height = texture_.buffer_height;
- interop_dst.opengl_pbo_id = texture_.gl_pbo_id;
-
- interop_dst.need_clear = texture_.need_clear;
- texture_.need_clear = false;
-
- return interop_dst;
-}
-
-void BlenderDisplayDriver::graphics_interop_activate()
-{
- gl_context_enable();
-}
-
-void BlenderDisplayDriver::graphics_interop_deactivate()
-{
- gl_context_disable();
-}
-
-/* --------------------------------------------------------------------
- * Drawing.
- */
-
-void BlenderDisplayDriver::clear()
-{
- texture_.need_clear = true;
-}
-
-void BlenderDisplayDriver::set_zoom(float zoom_x, float zoom_y)
-{
- zoom_ = make_float2(zoom_x, zoom_y);
-}
-
-void BlenderDisplayDriver::draw(const Params &params)
-{
- /* See do_update_begin() for why no locking is required here. */
- const bool transparent = true; // TODO(sergey): Derive this from Film.
-
- if (!gl_draw_resources_ensure()) {
- return;
- }
-
- if (use_gl_context_) {
- gl_context_mutex_.lock();
- }
-
- if (texture_.need_clear) {
- /* Texture is requested to be cleared and was not yet cleared.
- *
- * Do early return which should be equivalent of drawing all-zero texture.
- * Watch out for the lock though so that the clear happening during update is properly
- * synchronized here. */
- gl_context_mutex_.unlock();
- return;
- }
-
- if (gl_upload_sync_) {
- glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
- }
-
- if (transparent) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- display_shader_->bind(params.full_size.x, params.full_size.y);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
-
- /* Trick to keep sharp rendering without jagged edges on all GPUs.
- *
- * The idea here is to enforce driver to use linear interpolation when the image is not zoomed
- * in.
- * For the render result with a resolution divider in effect we always use nearest interpolation.
- *
- * Use explicit MIN assignment to make sure the driver does not have an undefined behavior at
- * the zoom level 1. The MAG filter is always NEAREST. */
- const float zoomed_width = params.size.x * zoom_.x;
- const float zoomed_height = params.size.y * zoom_.y;
- if (texture_.width != params.size.x || texture_.height != params.size.y) {
- /* Resolution divider is different from 1, force nearest interpolation. */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
- else if (zoomed_width - params.size.x > 0.5f || zoomed_height - params.size.y > 0.5f) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- }
- else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
-
- texture_update_if_needed();
- vertex_buffer_update(params);
-
- /* TODO(sergey): Does it make sense/possible to cache/reuse the VAO? */
- GLuint vertex_array_object;
- glGenVertexArrays(1, &vertex_array_object);
- glBindVertexArray(vertex_array_object);
-
- const int texcoord_attribute = display_shader_->get_tex_coord_attrib_location();
- const int position_attribute = display_shader_->get_position_attrib_location();
-
- glEnableVertexAttribArray(texcoord_attribute);
- glEnableVertexAttribArray(position_attribute);
-
- glVertexAttribPointer(
- texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
- glVertexAttribPointer(position_attribute,
- 2,
- GL_FLOAT,
- GL_FALSE,
- 4 * sizeof(float),
- (const GLvoid *)(sizeof(float) * 2));
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- glDeleteVertexArrays(1, &vertex_array_object);
-
- display_shader_->unbind();
-
- if (transparent) {
- glDisable(GL_BLEND);
- }
-
- gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
- glFlush();
-
- if (use_gl_context_) {
- gl_context_mutex_.unlock();
- }
-}
-
-void BlenderDisplayDriver::gl_context_create()
-{
- /* When rendering in viewport there is no render context available via engine.
- * Check whether own context is to be created here.
- *
- * NOTE: If the `b_engine_`'s context is not available, we are expected to be on a main thread
- * here. */
- use_gl_context_ = !RE_engine_has_render_context(
- reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
-
- if (use_gl_context_) {
- const bool drw_state = DRW_opengl_context_release();
- gl_context_ = WM_opengl_context_create();
- if (gl_context_) {
- /* On Windows an old context is restored after creation, and subsequent release of context
- * generates a Win32 error. Harmless for users, but annoying to have possible misleading
- * error prints in the console. */
-#ifndef _WIN32
- WM_opengl_context_release(gl_context_);
-#endif
- }
- else {
- LOG(ERROR) << "Error creating OpenGL context.";
- }
-
- DRW_opengl_context_activate(drw_state);
- }
-}
-
-bool BlenderDisplayDriver::gl_context_enable()
-{
- if (use_gl_context_) {
- if (!gl_context_) {
- return false;
- }
- gl_context_mutex_.lock();
- WM_opengl_context_activate(gl_context_);
- return true;
- }
-
- RE_engine_render_context_enable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
- return true;
-}
-
-void BlenderDisplayDriver::gl_context_disable()
-{
- if (use_gl_context_) {
- if (gl_context_) {
- WM_opengl_context_release(gl_context_);
- gl_context_mutex_.unlock();
- }
- return;
- }
-
- RE_engine_render_context_disable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
-}
-
-void BlenderDisplayDriver::gl_context_dispose()
-{
- if (gl_context_) {
- const bool drw_state = DRW_opengl_context_release();
-
- WM_opengl_context_activate(gl_context_);
- WM_opengl_context_dispose(gl_context_);
-
- DRW_opengl_context_activate(drw_state);
- }
-}
-
-bool BlenderDisplayDriver::gl_draw_resources_ensure()
-{
- if (!texture_.gl_id) {
- /* If there is no texture allocated, there is nothing to draw. Inform the draw call that it can
- * can not continue. Note that this is not an unrecoverable error, so once the texture is known
- * we will come back here and create all the GPU resources needed for draw. */
- return false;
- }
-
- if (gl_draw_resource_creation_attempted_) {
- return gl_draw_resources_created_;
- }
- gl_draw_resource_creation_attempted_ = true;
-
- if (!vertex_buffer_) {
- glGenBuffers(1, &vertex_buffer_);
- if (!vertex_buffer_) {
- LOG(ERROR) << "Error creating vertex buffer.";
- return false;
- }
- }
-
- gl_draw_resources_created_ = true;
-
- return true;
-}
-
-void BlenderDisplayDriver::gl_resources_destroy()
-{
- gl_context_enable();
-
- if (vertex_buffer_ != 0) {
- glDeleteBuffers(1, &vertex_buffer_);
- }
-
- if (texture_.gl_pbo_id) {
- glDeleteBuffers(1, &texture_.gl_pbo_id);
- texture_.gl_pbo_id = 0;
- }
-
- if (texture_.gl_id) {
- glDeleteTextures(1, &texture_.gl_id);
- texture_.gl_id = 0;
- }
-
- gl_context_disable();
-
- gl_context_dispose();
-}
-
-bool BlenderDisplayDriver::gl_texture_resources_ensure()
-{
- if (texture_.creation_attempted) {
- return texture_.is_created;
- }
- texture_.creation_attempted = true;
-
- DCHECK(!texture_.gl_id);
- DCHECK(!texture_.gl_pbo_id);
-
- /* Create texture. */
- glGenTextures(1, &texture_.gl_id);
- if (!texture_.gl_id) {
- LOG(ERROR) << "Error creating texture.";
- return false;
- }
-
- /* Configure the texture. */
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- /* Create PBO for the texture. */
- glGenBuffers(1, &texture_.gl_pbo_id);
- if (!texture_.gl_pbo_id) {
- LOG(ERROR) << "Error creating texture pixel buffer object.";
- return false;
- }
-
- /* Creation finished with a success. */
- texture_.is_created = true;
-
- return true;
-}
-
-void BlenderDisplayDriver::texture_update_if_needed()
-{
- if (!texture_.need_update) {
- return;
- }
-
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
- glTexSubImage2D(
- GL_TEXTURE_2D, 0, 0, 0, texture_.width, texture_.height, GL_RGBA, GL_HALF_FLOAT, 0);
- glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-
- texture_.need_update = false;
-}
-
-void BlenderDisplayDriver::vertex_buffer_update(const Params &params)
-{
- /* Invalidate old contents - avoids stalling if the buffer is still waiting in queue to be
- * rendered. */
- glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
-
- float *vpointer = reinterpret_cast<float *>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
- if (!vpointer) {
- return;
- }
-
- vpointer[0] = 0.0f;
- vpointer[1] = 0.0f;
- vpointer[2] = params.full_offset.x;
- vpointer[3] = params.full_offset.y;
-
- vpointer[4] = 1.0f;
- vpointer[5] = 0.0f;
- vpointer[6] = (float)params.size.x + params.full_offset.x;
- vpointer[7] = params.full_offset.y;
-
- vpointer[8] = 1.0f;
- vpointer[9] = 1.0f;
- vpointer[10] = (float)params.size.x + params.full_offset.x;
- vpointer[11] = (float)params.size.y + params.full_offset.y;
-
- vpointer[12] = 0.0f;
- vpointer[13] = 1.0f;
- vpointer[14] = params.full_offset.x;
- vpointer[15] = (float)params.size.y + params.full_offset.y;
-
- glUnmapBuffer(GL_ARRAY_BUFFER);
-}
-
-CCL_NAMESPACE_END