From d5ceae44552d6beae26001e3cf754935f93f4ec5 Mon Sep 17 00:00:00 2001 From: Igor Timofeev Date: Sat, 12 Aug 2017 00:04:04 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B0=D1=80=D0=B0=20=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D1=8B=D1=85=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=B1=D1=83=D1=84=D0=B5=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Applications.cfg | 2 +- Documentation/doubleBuffering.md | 85 +++++++++++++++++++------------- lib/doubleBuffering.lua | 70 +++++++++++++++++--------- 3 files changed, 100 insertions(+), 57 deletions(-) diff --git a/Applications.cfg b/Applications.cfg index 9ac90dac..4e06f582 100644 --- a/Applications.cfg +++ b/Applications.cfg @@ -368,7 +368,7 @@ url="https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/doubleBuffering.lua", type="Library", preloadFile=true, - version=1.27, + version=1.28, }, { path="/lib/compressor.lua", diff --git a/Documentation/doubleBuffering.md b/Documentation/doubleBuffering.md index 8042d766..ba3c7b41 100644 --- a/Documentation/doubleBuffering.md +++ b/Documentation/doubleBuffering.md @@ -2,32 +2,34 @@ | ----- | | [О библиотеке](#О-библиотеке) | | [Установка](#Установка) | -| [Параметры библиотеки](#Параметры-библиотеки) | -| Методы библиотеки: | -| [buffer.setResolution](#buffersetresolution-width-height-) | -| [buffer.draw](#bufferdraw-force-) | -| [buffer.setDrawLimit](#buffersetdrawlimit-x1-y1-x2-y2-) | -| [buffer.getDrawLimit](#buffergetdrawlimit--int-x1-int-y1-int-x2-int-y2) | -| [buffer.copy](#buffercopy-x-y-width-height--table-pixeldata) | -| [buffer.paste](#bufferpaste-x-y-pixeldata-) | -| Методы отрисовки: | -| [buffer.set](#bufferpaste-x-y-pixeldata-) | -| [buffer.get](#bufferpaste-x-y-pixeldata-) | -| [buffer.square](#buffersquare-x-y-width-height-background-foreground-symbol-transparency-) | -| [buffer.clear](#bufferclear-color-transparency-) | -| [buffer.text](#buffertext-x-y-color-text-transparency-) | +| [Свойства библиотеки](#Параметры-библиотеки) | +| [Методы библиотеки](#Методы-библиотеки) | +| [    buffer.setResolution](#buffersetresolution-width-height-) | +| [    buffer.bindScreen](#bufferbindscreen-address-) | +| [    buffer.bindGPU](#bufferbindgpu-address-) | +| [Методы отрисовки](#Методы-отрисовки) | +| [    buffer.draw](#bufferdraw-force-) | +| [    buffer.setDrawLimit](#buffersetdrawlimit-x1-y1-x2-y2-) | +| [    buffer.getDrawLimit](#buffergetdrawlimit--int-x1-int-y1-int-x2-int-y2) | +| [    buffer.copy](#buffercopy-x-y-width-height--table-pixeldata) | +| [    buffer.paste](#bufferpaste-x-y-pixeldata-) | +| [    buffer.set](#bufferpaste-x-y-pixeldata-) | +| [    buffer.get](#bufferpaste-x-y-pixeldata-) | +| [    buffer.square](#buffersquare-x-y-width-height-background-foreground-symbol-transparency-) | +| [    buffer.clear](#bufferclear-color-transparency-) | +| [    buffer.text](#buffertext-x-y-color-text-transparency-) | | [Методы полупиксельной отрисовки:](#Методы-полупиксельной-отрисовки) | -| [buffer.semiPixelSet](#buffersemipixelset-x-y-color-) | -| [buffer.semiPixelSquare](#buffersemipixelsquare-x-y-width-height-color-) | -| [buffer.semiPixelLine](#buffersemipixelline-x1-y1-x2-y2-color-) | -| [buffer.semiPixelCircle](#buffersemipixelcircle-xcenter-ycenter-radius-color-) | -| [buffer.semiPixelBezierCurve](#buffersemipixelbeziercurve-points-color-precision-) | +| [    buffer.semiPixelSet](#buffersemipixelset-x-y-color-) | +| [    buffer.semiPixelSquare](#buffersemipixelsquare-x-y-width-height-color-) | +| [    buffer.semiPixelLine](#buffersemipixelline-x1-y1-x2-y2-color-) | +| [    buffer.semiPixelCircle](#buffersemipixelcircle-xcenter-ycenter-radius-color-) | +| [    buffer.semiPixelBezierCurve](#buffersemipixelbeziercurve-points-color-precision-) | | [Вспомогательные методы:](#Вспомогательные-методы) | -| [buffer.flush](#bufferflush-width-height-) | -| [buffer.getIndexByCoordinates](#buffergetindexbycoordinates-x-y--int-index) | -| [buffer.getCoordinatesByIndex](#buffergetcoordinatesbyindex-index--int-x-int-y) | -| [buffer.rawSet](#bufferrawset-index-background-foreground-symbol-) | -| [buffer.rawGet](#bufferrawget-index--int-background-int-foreground-char-symbol) | +| [    buffer.flush](#bufferflush-width-height-) | +| [    buffer.getIndexByCoordinates](#buffergetindexbycoordinates-x-y--int-index) | +| [    buffer.getCoordinatesByIndex](#buffergetcoordinatesbyindex-index--int-x-int-y) | +| [    buffer.rawSet](#bufferrawset-index-background-foreground-symbol-) | +| [    buffer.rawGet](#bufferrawget-index--int-background-int-foreground-char-symbol) | | [Практический пример #1](#Практический-пример-1) | @@ -45,7 +47,7 @@ DoubleBuffering - низкоуровневая библиотека для эф ![meow](http://i60.fastpic.ru/big/2015/1026/8a/4c72bfcbe8fbee5993bfd7a058a5f88a.png) -Цена таких космических скоростей - повышенный расход оперативной памяти. Чтобы предельно уменьшить ее расход, мы используем одномерную структуру экранных массивов вместо трехмерной: +Цена таких космических скоростей - повышенный расход оперативной памяти. Чтобы предельно уменьшить его, мы используем одномерную структуру экранных массивов вместо трехмерной: ![Imgur](http://i.imgur.com/2Pkne53.png) @@ -66,15 +68,16 @@ DoubleBuffering - низкоуровневая библиотека для эф pastebin run vTM8nbSZ -Параметры библиотеки +Свойства библиотеки ====== -| Тип параметра | Параметр |Описание | +| Тип свойства | Свойство |Описание | | ------ | ------ | ------ | | *int* | buffer.**width**| Текущее разрешение буфера по ширине | | *int* | buffer.**height**| Текущее разрешение буфера по высоте | -| *table* | buffer.**currentFrame**| Таблица с пиксельными данными, содержащая то, что в данный момент отображено на экране. Она имеет структуру ```{ 0xFFFFFF, 0x000000, "Q", 0xFFFFFF, 0x000000, "W", ... }```, где первый элемент - цвет фона, второй - цвет текста, третий - символ. И так до конца размера буфера | -| *table* | buffer.**newFrame**| Таблица с пиксельными данными, содержащая то, что пользователь отрисовывает в него в данный момент. Структура аналогична предыдущей | +| *table* | buffer.**GPUProxy**| Указатель на proxy компонента видеокарты, с которой работает буфер | +| *table* | buffer.**currentFrame**| Указатель на таблицу с пиксельными данными, содержащая то, что в данный момент отображено на экране. Она имеет структуру ```{ 0xFFFFFF, 0x000000, "Q", 0xFFFFFF, 0x000000, "W", ... }```, где первый элемент - цвет фона, второй - цвет текста, третий - символ. И так до конца размера буфера | +| *table* | buffer.**newFrame**| Указатель на таблицу с пиксельными данными, содержащая то, что пользователь отрисовывает в него в данный момент. Структура аналогична предыдущей | Основные методы ====== @@ -88,13 +91,32 @@ buffer.**setResolution**( width, height ) Установить разрешение экранного буфера и GPU равным указанному. Содержимое буфера при этом будет заполнено черными пикселями с символом пробела. +buffer.**bindScreen**( address ) +----------------------------------------------------------- +| Тип | Аргумент | Описание | +| ------ | ------ | ------ | +| *string* | address | Адрес компонента экрана | + +Связать используемую буфером видеокарту с указанным компонентом экрана. Содержимое буфера при этом будет заполнено черными пикселями с символом пробела. + +buffer.**bindGPU**( address ) +----------------------------------------------------------- +| Тип | Аргумент | Описание | +| ------ | ------ | ------ | +| *string* | address | Адрес компонента видеокарты | + +Изменить используемую буфером видеокарту на указанную. Содержимое буфера при этом будет заполнено черными пикселями с символом пробела. + +Методы отрисовки +====== + buffer.**draw**( [force] ) ----------------------------------------------------------- | Тип | Аргумент | Описание | | ------ | ------ | ------ | | [*boolean* | force] | Принудительная отрисовка | -Отрисовать содержимое буфера на экран. Если имеется опциональный аргумент *force*, то содержимое буфера будет полностью отрисовано вне зависимости от изменившихся пикселей. +Отрисовать содержимое буфера на экран. Если имеется опциональный аргумент *force*, то содержимое буфера будет отрисовано полностью и вне зависимости от изменившихся пикселей. buffer.**setDrawLimit**( x1, y1, x2, y2 ) ----------------------------------------------------------- @@ -132,9 +154,6 @@ buffer.**paste**( x, y, pixelData ) Вставить скопированное содержимое буфера по указанным координатам. -Методы отрисовки -====== - buffer.**set**( x, y, background, foreground, symbol ) ----------------------------------------------------------- | Тип | Аргумент | Описание | diff --git a/lib/doubleBuffering.lua b/lib/doubleBuffering.lua index b8bcb2d1..40ba7a03 100755 --- a/lib/doubleBuffering.lua +++ b/lib/doubleBuffering.lua @@ -6,8 +6,12 @@ local image = require("image") -------------------------------------------------------------------------------------------------------------- -local gpu = component.gpu -local buffer = {} +local buffer = { + GPUProxy = component.getPrimary("gpu"), + currentFrame = {}, + newFrame = {}, + drawLimit = {}, +} -------------------------------------------------------------------------------------------------------------- @@ -20,6 +24,8 @@ function buffer.getIndexByCoordinates(x, y) return buffer.tripleWidth * (y - 1) + x * 3 - 2 end +-------------------------------------------------------------------------------------------------------------- + function buffer.setDrawLimit(x1, y1, x2, y2) buffer.drawLimit.x1, buffer.drawLimit.y1, buffer.drawLimit.x2, buffer.drawLimit.y2 = x1, y1, x2, y2 end @@ -32,17 +38,17 @@ function buffer.getDrawLimit() return buffer.drawLimit.x1, buffer.drawLimit.y1, buffer.drawLimit.x2, buffer.drawLimit.y2 end +-------------------------------------------------------------------------------------------------------------- + function buffer.flush(width, height) if not width or not height then - width, height = gpu.getResolution() + width, height = buffer.GPUProxy.getResolution() end - buffer.currentFrame = {} - buffer.newFrame = {} + buffer.currentFrame, buffer.newFrame = {}, {} buffer.width = width buffer.height = height buffer.tripleWidth = width * 3 - buffer.drawLimit = {} buffer.resetDrawLimit() for y = 1, buffer.height do @@ -59,10 +65,20 @@ function buffer.flush(width, height) end function buffer.setResolution(width, height) - gpu.setResolution(width, height) + buffer.GPUProxy.setResolution(width, height) buffer.flush(width, height) end +function buffer.bindScreen(...) + buffer.GPUProxy.bind(...) + buffer.flush(buffer.GPUProxy.getResolution()) +end + +function buffer.bindGPU(address) + buffer.GPUProxy = component.proxy(address) + buffer.flush(buffer.GPUProxy.getResolution()) +end + -------------------------------------------------------------------------------------------------------------- function buffer.rawSet(index, background, foreground, symbol) @@ -488,14 +504,14 @@ local function info(...) table.insert(text, tostring(args[i])) end - local b = gpu.getBackground() - local f = gpu.getForeground() - gpu.setBackground(0x0) - gpu.setForeground(0xFFFFFF) - gpu.fill(1, buffer.height, buffer.width, 1, " ") - gpu.set(2, buffer.height, table.concat(text, ", ")) - gpu.setBackground(b) - gpu.setForeground(f) + local b = buffer.GPUProxy.getBackground() + local f = buffer.GPUProxy.getForeground() + buffer.GPUProxy.setBackground(0x0) + buffer.GPUProxy.setForeground(0xFFFFFF) + buffer.GPUProxy.fill(1, buffer.height, buffer.width, 1, " ") + buffer.GPUProxy.set(2, buffer.height, table.concat(text, ", ")) + buffer.GPUProxy.setBackground(b) + buffer.GPUProxy.setForeground(f) require("event").pull("touch") end @@ -561,16 +577,16 @@ function buffer.draw(force) end for background in pairs(changes) do - gpu.setBackground(background) + buffer.GPUProxy.setBackground(background) for foreground in pairs(changes[background]) do if currentForeground ~= foreground then - gpu.setForeground(foreground) + buffer.GPUProxy.setForeground(foreground) currentForeground = foreground end for i = 1, #changes[background][foreground], 3 do - gpu.set(changes[background][foreground][i], changes[background][foreground][i + 1], changes[background][foreground][i + 2]) + buffer.GPUProxy.set(changes[background][foreground][i], changes[background][foreground][i + 1], changes[background][foreground][i + 2]) end end end @@ -584,13 +600,21 @@ buffer.flush() ------------------------------------------------------------------------------------------------------ --- gpu.setBackground(0x0) --- gpu.fill(1, 1, buffer.width, buffer.height, " ") +-- buffer.GPUProxy.setBackground(0x0) +-- buffer.GPUProxy.fill(1, 1, buffer.width, buffer.height, " ") --- -- buffer.clear(0xFF8888) +-- buffer.clear(0x1D1D1D) + +-- buffer.semiPixelBezierCurve({ +-- {x = 2, y = 2}, +-- {x = 20, y = 90}, +-- {x = 40, y = 60}, +-- {x = 120, y = 10}, +-- }, 0xFFFFFF, 0.01) +-- buffer.semiPixelLine(2, 2, 100, 80, 0xFFFFFF) -- buffer.square(1, 1, buffer.width, buffer.height, 0xFF8888, 0x0, "Q") --- -- buffer.square(1, 1, buffer.width, buffer.height, 0xFFFFFF, 0xFFFFFF, "Q") --- -- buffer.square(3, 3, 10, 5, 0x00FF00, 0x0, "Q") +-- buffer.square(1, 1, buffer.width, buffer.height, 0xFFFFFF, 0xFFFFFF, "Q") +-- buffer.square(3, 3, 10, 5, 0x00FF00, 0x0, "Q") -- buffer.draw(true) -- buffer.image(1, 1, image.load("/MineOS/Pictures/Raspberry.pic"))