whale 1 1 сентября, 2016 Опубликовано 1 сентября, 2016 · Жалоба Народ, надо вывести двумерный массив данных 1000*800 в виде точек на image (прогаю в buildere) причем надо его сдвигать на одну координату скоростью 0,1сек ( с вводом новых ) Если делать тупо в лоб то страшные тормоза, посоветуйте куда копать, явно есть методы быстрого вывода, задача для меня вновье. Те в итоге видим экран 1000*800, по нему ползет изображение, которое обновляется справа на одну линию все время. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 1 сентября, 2016 Опубликовано 1 сентября, 2016 · Жалоба быстрые методы это аппаратно через opengl. хотя даже и тупое копирование вроде как работает. на fltk несколько мс чтобы картинку скопировать и еще ~50мс чтобы отрисовать. unsigned char pic[1000*800*3]; class MyWindow : public Fl_Double_Window{ public: MyWindow() : Fl_Double_Window(1000,800) { } void draw(){ fl_draw_image(pic,0,0,1000,800,3,0); } }; MyWindow * w; void callback(void*) { static int t = GetTickCount(); printf("%d\n",GetTickCount() - t); t = GetTickCount(); for (int y = 0; y < 800; y++){ pic[3*(0+y*1000)+0] = rand(); pic[3*(0+y*1000)+1] = rand(); pic[3*(0+y*1000)+2] = rand(); for (int x = 999; x >= 1; x--){ pic[3*(x+y*1000)+0] = pic[3*((x-1)+y*1000)+0]; pic[3*(x+y*1000)+1] = pic[3*((x-1)+y*1000)+1]; pic[3*(x+y*1000)+2] = pic[3*((x-1)+y*1000)+2]; } } w->redraw(); Fl::repeat_timeout(0.1, callback); } int main(int argc, char ** argv){ w = new MyWindow(); for (int y = 0; y < 800; y++){ for (int x = 0; x < 1000; x++){ pic[3*(x+y*1000)+0] = rand(); pic[3*(x+y*1000)+1] = rand(); pic[3*(x+y*1000)+2] = rand(); } } Fl::add_timeout(0.1, callback); w->show(); return Fl::run(); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whale 1 1 сентября, 2016 Опубликовано 1 сентября, 2016 (изменено) · Жалоба Не совсем понял а как это все вывести на форму ? Я пока просто точки ставил :rolleyes: Изменено 1 сентября, 2016 пользователем whale_nik Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whale 1 1 сентября, 2016 Опубликовано 1 сентября, 2016 (изменено) · Жалоба Типа такого надо ) Вся картинка должна ехать влево с обновлением справа Изменено 1 сентября, 2016 пользователем whale_nik Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 2 сентября, 2016 Опубликовано 2 сентября, 2016 · Жалоба Типа такого надо ) Вся картинка должна ехать влево с обновлением справа Открываете MSDN на разделе Windows GDI\Bitmap Functions. Изучаете всё, что касается семейства BitBlt-функций. Создаёте memory device context, рисуете в нём (только с умом - не перерисовывая каждый раз туеву хучу точек, а дорисовывая только новый участок точек), затем из memory device context перекидываете картинку (с необходимым сдвигом) за пару операций BitBlt (или родственных) на screen device context. И если всё так сделаете, загрузка CPU будет близкая к нулю, даже на слабом CPU. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 2 сентября, 2016 Опубликовано 2 сентября, 2016 · Жалоба Если делать тупо в лоб то страшные тормоза, посоветуйте куда копать, явно есть методы быстрого вывода, задача для меня вновье. Пример на дельфи, на билдер сами адаптируете. 1. Создаёте вспомогательный TBitmap (где-нибудь в конструкторе): bt := TBitMap.Create; 2. Рисуете в него свои точки: for y := 1 to bt.Height-1 do begin pt := bt.ScanLine[y]; for x := 1 to bt.Width-1 do pt^[x] := Round(Random*x); end; end; 3. Можете добавить что угодно, например, текст: bt.Canvas.TextOut(10,10, 'И не надо никакого MSDN'); 4. Выводите битмап на форму: Canvas.Draw(0,0, bt); Всё! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whale 1 2 сентября, 2016 Опубликовано 2 сентября, 2016 · Жалоба Сделал как советуете, все равно жесть как медленно и жрет кучу процессорного времени ( Может не так что сделал ? Builder 6.0 Project1.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 2 сентября, 2016 Опубликовано 2 сентября, 2016 · Жалоба Открываете MSDN на разделе Windows GDI\Bitmap Functions. Изучаете всё, что касается семейства BitBlt-функций. Создаёте memory device context, рисуете в нём (только с умом - не перерисовывая каждый раз туеву хучу точек, а дорисовывая только новый участок точек), затем из memory device context перекидываете картинку (с необходимым сдвигом) за пару операций BitBlt (или родственных) на screen device context. Плюсую. Кстати у TCanvas есть Handle, который явялется device context, который, как я понимаю, можно пихать в WinAPI функции. Кроме того у TCanvas имеются методы с аналогичным WinAPI функционалом, но надо бы протестировать их на тормознутость. http://docs.embarcadero.com/products/rad_s...vas_Handle.html Возможно у TImage тоже будет возможность взять device context....надо погуглить Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 2 сентября, 2016 Опубликовано 2 сентября, 2016 · Жалоба у openGL есть glDrawPixels. инициализация через GLFW а вот winAPI функции лучше запихать в... <Гусары, МОЛЧАТЬ!> можно заодно с builder 6.0 #include "GLFW/glfw3.h" #include <stdio.h> #include <windows.h> unsigned char pic[1000*800*3]; int main(void){ int t0 = GetTickCount(); GLFWwindow* window; /* Initialize the library */ if (!glfwInit()) return -1; /* Create a windowed mode window and its OpenGL context */ window = glfwCreateWindow(1000, 800, "Hello World", NULL, NULL); if (!window) { glfwTerminate(); return -1; } /* Make the window's context current */ glfwMakeContextCurrent(window); /* Loop until the user closes the window */ while (!glfwWindowShouldClose(window)){ /* Render here */ glClear(GL_COLOR_BUFFER_BIT); for (int i = 0; i < 1000*800*3; i++) pic[i] = rand(); glDrawPixels(1000,800, GL_RGB, GL_UNSIGNED_BYTE, pic); /* Swap front and back buffers */ glfwSwapBuffers(window); /* Poll for and process events */ glfwPollEvents(); printf("%d\n", GetTickCount()-t0); t0 = GetTickCount(); } glfwTerminate(); return 0; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whale 1 3 сентября, 2016 Опубликовано 3 сентября, 2016 · Жалоба Мне кажется основные тормоза и загрузка это инициализация битовой матрици все время по новой это 2 640 000 байт Если бы как то не заносить значения по новой а двигать область памяти этой матрицы, прибавляя справа по одному столбцу, там же все на указателях, нельзя так сделать ? Память как то закольцевать ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 3 сентября, 2016 Опубликовано 3 сентября, 2016 · Жалоба у openGL есть glDrawPixels. а вот winAPI функции лучше запихать в... <Гусары, МОЛЧАТЬ!> И Ваш код будет таким-же тормознутым как и предыдущих дельфи-"специалистов". Главная ошибка: перерисовывать попиксельно каждый раз весь экран. Рисовать по пикселам нужно минимум - только обновлённую часть. Старую часть изображения просто копировать ...Blt-функциями. Сомневаюсь, что у OpenGL будет выигрыш по сравнению с WinAPI-шными BitBlt/PatBlt/.... В своё время много времени потратил на оптимизацию подобной задачи: переделывал изначальный свой WinAPI-вариант (через BitBlt/PatBlt/...) на DirectDraw. Получил абсолютно то же самое время работы. Сделал вывод, что при возможности, WinAPI-шные BitBlt/PatBlt/... вызывают изнутри DirectX, поэтому и не видно разницы во времени работы. Думаю что с OpenGL будет то же самое. Конечно в том, что ставить точки лучше не по одной, а пачкой - Вы правы. В WinAPI по-моему тоже есть подобная функция. Если бы как то не заносить значения по новой а двигать область памяти этой матрицы, прибавляя справа по одному столбцу, там же все на указателях, нельзя так сделать ? Память как то закольцевать ) Я Вам это советовал ещё несколько сообщений назад. Но видно "чукча - не читатель..." Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 14 3 сентября, 2016 Опубликовано 3 сентября, 2016 · Жалоба Сделал как советуете, все равно жесть как медленно и жрет кучу процессорного времени ( Может не так что сделал ? Так у вас таймер молотит раз в миллисекунду! Это 1000FPS, конечно жрёт. Сделайте, 100ms, и будет всё нормально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 3 сентября, 2016 Опубликовано 3 сентября, 2016 · Жалоба Курить в сторону направления, заданного jcxz :) Перемещая окна винды, очевидно, что скроллинг реализовать можно. Так как сама ОС это делает. ТС можно также попробовать посмотреть в сторону оптимизации алгоритма вывода на отображение нарисованного тем или иным способом. Я имею ввиду конвейерную подготовку данных и их отображение. ( Пока виртуально отрисовывается массив, уже готовый образ отображается другим потоком). Кроме того, если ОНО сдвигается, то нет смысла перерисовывать 99.999 информации. Достаточно вывести правый "столбик", который "новый". Эти 99.999 изображения уже на экране, их выводить не нужно, достаточно только указать драйверу сместить указатель отображения левого верхнего угла массива в видео-памяти. Как до него добраться - это уже спортивный вопрос :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 52 3 сентября, 2016 Опубликовано 3 сентября, 2016 · Жалоба И Ваш код будет таким-же тормознутым как и предыдущих дельфи-"специалистов". не будет, нынче скопировать пару МБайт из памяти в память это долго??? на моём довольно древнем компе, которому лет 10 уже, это занимает 1.5мс. LARGE_INTEGER t0,t1,f; QueryPerformanceFrequency(&f); QueryPerformanceCounter(&t0); for (int j = 0; j < 800; j++) memcpy(&pic[j*3000],&pic[j*3000+3],3000-3); QueryPerformanceCounter(&t1); printf("%G\n", (double)(t1.QuadPart - t0.QuadPart)/ f.QuadPart); да это криво и правильно было бы сделать два буфера размером с экран и заполнять их по очереди и отрисовывать со сдвигом. для этого есть glRasterPos3f. а совсем правильно сложить это сразу в память видеокарты, тогда и сдвиги и отрисовка процессор никак не нагрузят Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
whale 1 3 сентября, 2016 Опубликовано 3 сентября, 2016 (изменено) · Жалоба Я правильно понял, что если создать две одинаковые матрицы, и потом по очереди копировать одну в другую со сдвигом , прибавляя новые данные ? Так можно скопировать ? Можно примерчик плиз ? Я так понимаю это glCopyPixels ? Так у вас таймер молотит раз в миллисекунду! Это 1000FPS, конечно жрёт. Сделайте, 100ms, и будет всё нормально. Эта штука вообще должна летать со скоростью пули по хорошему, как на локаторе С-400 ) со 100 мс пока зкран весь сдвинется родить можно будет ) Изменено 3 сентября, 2016 пользователем whale_nik Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться