Хорошее начало... чем его надо собирать?Я буду использовать компилятор GCC и очень легковесную среду разработки Geany (для Windows доступна).
В общем, какой компилятор будешь пользовать? Какую IDE?
Блин, забыл предупредить... у меня видюхи нет с поддержкой Open CL :( Может лучше сначала потренироваться на рендере для процессора?Я весь день потратил, чтобы добиться работоспособности своей видеокарты, но, ещё не добился. Это хорошо, что ты предложил потренироваться
Возник вопрос №1: Как собираешься данные из Блендера передавать в рейтресер? Это будет прямой доступ к .blend загруженному в оперативную память или реэкспорт в какой-то свой формат перед рендером?Как говорится, мы лёгких путей не ищем. Если правильно расставить птицы в cmake при сборке блендера, то можно вместо гуёвины собрать библиотеку. В винде это получается ни blender.exe, а bpy.dll, в линуксе это bpy.so. Вот эту либу я и собираюсь использовать в рендерере.
#include <python3.5m/Python.h>
#include <iostream>
#include <string>
int main(int, char **) {
PyObject *mName, *pModule, *pFunc;
PyObject *pArgs, *pValue, *sResult;
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")");
PyRun_SimpleString("from bimport import hello");
mName = PyUnicode_FromString("bimport");
char fName[] = "hello";
pModule = PyImport_Import(mName);
pFunc = PyObject_GetAttrString(pModule, fName);
char fileName[] = "/home/leonid/workspace/blender/files_blend/test_so.blend";
PyObject *pyFileName = PyBytes_FromString(fileName);
pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs, 0, pyFileName);
pValue = PyObject_CallObject(pFunc, pArgs);
double cTuple[3];
for (int i = 0; i < 3; i++){
sResult = PyTuple_GetItem(pValue,i);
double cResult = PyFloat_AsDouble(sResult);
cTuple[i] = cResult;
}
std::cout<<cTuple[0]<<std::endl;
std::cout<<cTuple[1]<<std::endl;
std::cout<<cTuple[2]<<std::endl;
Py_Finalize();
return 0;
}
Вот ещё один рейтресер на C++ https://github.com/iquadrat/raytracer (http://blender-3d.ru/forum/go.php?url=aHR0cHM6Ly9naXRodWIuY29tL2lxdWFkcmF0L3JheXRyYWNlcg==)Это большой проект. Для начала без opencl подойдёт вот эта статья:
>> Это большой проект.Ты будешь помогать?
... а с нуля слабо?! но не просто #include #@уяк-#@уяк, а с постановки-с задачи ...
Вот тебе ещё инфы для размышлений (формат .blend файла)Вот ещё инфы от Ильи Белкина: https://docs.google.com/document/d/1VHt0flhV41fZAUuYsYqK0Vgn49KZfkekeQ39JnijC08/edit?pref=2&pli=1 (http://blender-3d.ru/forum/go.php?url=aHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZG9jdW1lbnQvZC8xVkh0MGZsaFY0MWZaQVV1WXNZcUswVmduNDlLWmZrZWtlUTM5Sm5pakMwOC9lZGl0P3ByZWY9MiZhbXA7cGxpPTE=)
http://www.atmind.nl/blender/mystery_ot_blend.html (http://blender-3d.ru/forum/go.php?url=aHR0cDovL3d3dy5hdG1pbmQubmwvYmxlbmRlci9teXN0ZXJ5X290X2JsZW5kLmh0bWw=)
http://www.atmind.nl/blender/blender-sdna-249.html (http://blender-3d.ru/forum/go.php?url=aHR0cDovL3d3dy5hdG1pbmQubmwvYmxlbmRlci9ibGVuZGVyLXNkbmEtMjQ5Lmh0bWw=)
>> Это большой проект.С нуля слабо, увы... хотя с нуля правильней :) На счёт определения целей и постановки задачи - согласен полностью!
... а с нуля слабо?! но не просто #include #@уяк-#@уяк, а с постановки-с задачи ...
... вот то что требуется сделать оно для чего и в чём цель? ...Ну ваще, я хотел упросить Ланухумыча, попробовать сделать ГИ на разблюренных картах окружения, что должно было дать прирост в скорости, теоретически... но потом...
Ты режешь меня без ножа. Написать нормальный парсер бинарника Блендера - это отдельный труд. Я этим заниматься не буду. Проще форкнуть Блендер и вписывать в него недостающие функции. Вот, я помню, как ты с bdancer чего-то там добивался от сетки, чтобы высвечивались только узлы с определённым количеством фейсов, принадлежащих одной вершине. Тут надо определиться, как сказал Николай, поставить задачу. ЧТО НАМ НУЖНО? ЧЕГО МЫ ХОТИМ?Вот тебе ещё инфы для размышлений (формат .blend файла)Вот ещё инфы от Ильи Белкина: https://docs.google.com/document/d/1VHt0flhV41fZAUuYsYqK0Vgn49KZfkekeQ39JnijC08/edit?pref=2&pli=1 (http://blender-3d.ru/forum/go.php?url=aHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZG9jdW1lbnQvZC8xVkh0MGZsaFY0MWZaQVV1WXNZcUswVmduNDlLWmZrZWtlUTM5Sm5pakMwOC9lZGl0P3ByZWY9MiZhbXA7cGxpPTE=)
http://www.atmind.nl/blender/mystery_ot_blend.html (http://blender-3d.ru/forum/go.php?url=aHR0cDovL3d3dy5hdG1pbmQubmwvYmxlbmRlci9teXN0ZXJ5X290X2JsZW5kLmh0bWw=)
http://www.atmind.nl/blender/blender-sdna-249.html (http://blender-3d.ru/forum/go.php?url=aHR0cDovL3d3dy5hdG1pbmQubmwvYmxlbmRlci9ibGVuZGVyLXNkbmEtMjQ5Lmh0bWw=)
Оставлю здесь. Вдруг, кому пригодится...
Вот, я помню, как ты с bdancer чего-то там добивался от сетки, чтобы высвечивались только узлы с определённым количеством фейсов, принадлежащих одной вершине.Да это моя глупость была... ещё одно ненужное никому дополнение, из-за неполного знания всех функций Блендера :) А bdancer - молодец, крут и шарит.
... хорошо, давайте с постановки задачи ...Я уже здесь на форуме упоминал Art Of Illusion. Мне нравится этот рендер.
... вот то что требуется сделать оно для чего и в чём цель? ...
... есть ли какое-нибудь противоречие, которое было бы решено в результате достижения поставленной цели? ...
Ты не придирайся к моим словам, а улавливай суть, которую я хочу до тебя донести. Все внешние рендеры общаются с Блендером посредством файлов, созданных пайтоном. Уходит время на запись и чтение. Я избавился от записи.
Да хозяин - барин, я тебя вовсе не хочу неволить ... относись к моим сообщениям как к пожеланиям, а не как указаниям, пожалуста.ЦитироватьВот, я помню, как ты с bdancer чего-то там добивался от сетки, чтобы высвечивались только узлы с определённым количеством фейсов, принадлежащих одной вершине.Да это моя глупость была... ещё одно ненужное никому дополнение, из-за неполного знания всех функций Блендера :) А bdancer - молодец, крут и шарит.
>> не тянет большое количество поликовА, ни ты ли мне говорил про более ляма в яфе?
... сколько не тянет и на сколько мы хотим их обогнать? ...
LOD (уровни детализации) не выход разве? Нахрена рендерить объект с сотней тыщь полигонов мелкий по масштабу или удалённый на горизонте размером с несколько пикселей? Засерать его геометрией память и детализированными текстурами, если этого вообще видно не будет?>> не тянет большое количество поликовА, ни ты ли мне говорил про более ляма в яфе?
... сколько не тянет и на сколько мы хотим их обогнать? ...
На сколько хотим обогнать? Ты пользовался Блендером, когда уже вьюпорт тормозит, а жмёшь (http://blender-3d.ru/forum/hotkey/[url="modules/sections/index.php?op=viewarticle&artid=24"]http://blender-3d.ru/forum/hotkey/http://blender-3d.ru/forum/hotkey/[url="modules/sections/index.php?op=viewarticle&artid=24"][img]http://blender-3d.ru/forum/hotkey/f12.jpg) (http://blender-3d.ru/forum/go.php?url=aHR0cDovLyZxdW90O21vZHVsZXMvc2VjdGlvbnMvaW5kZXgucGhwP29wPXZpZXdhcnRpY2xlJmFydGlkPTI0JnF1b3Q7).jpg.jpg[/url].jpg[/img][/url], и оно считает? Вот нам туда.
>> и оно считает? Вот нам туда.Ясно.
... это можно пенсию пенсионер и фабрики рабочим ...
... и легче пикачу поймать чем нам туда ...
... речь ведь про поставку задачи, а не агитацию вроде ...
... то есть нужны цифры, сколько мерить в граммах, точно ...
... почему? ...
... допустим нас все устраивает кроме времени, тогда решение вопроса может лежать не только в модернизации кода, но и в улучшении Времени ...
>> Почему Яфа, написанная на С встречает проблему, связанную с количеством поликов?Опять вопрос: Почему самого разработчика это не интересует?
... тогда задача - разобраться почему Яфа встречает проблему связанную с количеством поликов? ...
... есть конкретные тесты которые это демонстрируют? ...
... есть описание уже известных проблем Яфы с количеством поликов? ...
... есть объяснение разработчиков по этому вопросу? ...
>> Ты понимаешь, вот зачем нам Qt5? В этом есть необходимость? Была необходимость в Qt4? Была необходимость в GTK3?Задача: рендерер Art Of Illusion на С++, способный вместить всю сцену Блендера. Разумеется, логично бы было портировать код, но для начала нужно понять принципы. Например, я упёрся в ThreadLocal. Что это за фигня в Джаве? Кто мне ответит? Не надо меня посылать на форумы, я там был. Я это пойму только разобравшись, как работают с ядрами и потоками С++ программисты на примерах их кодов.
... для чего нам осина если есть берёза?! ...
... вот что мне ещё ответить ...
... тебе нужно ли какое-то время для формулирования постановки задачи? ...
... на самом деле в правильной постановке задачи лежит половин решения задачи и вряд ли по-другому ...
... ещё желательно и даже очень сделать постановку задачи как разрешения выявленного противоречия ...
... постановка задачи - путь к решению противоречия, но выявление противоречия уже очень даже неплохо ...
... тут вроде как есть опасность погрузиться в суету ...
>> Я до сих пор не разобрался, как он это сделал...Это не совсем так. Здесь играют роль личные отношения. Ни для кого не секрет, что англоязычные проще находят общий язык. Доки по апи не блещут доступностью.
... это в тебе говорить токарь ...
... то есть опять же на слабо в узко предметной области ...
... это не плохо, но суть - догонять ...
... тогда спрошу как токарь токаря, сколько нужно инструкций процессора чтобы визуализировать одну точку? ...Чтобы ездить на автомобиле, вовсе нет необходимости знать устройство двигателя.
#include <map>
#include <string>
#include <algorithm>
#include <iostream>
#include <fx.h>
char buf[16];
struct point {
int x, y;
};
#define GRID_LEN 1 // размер зерна в холсте
class PaintWindow : public FXMainWindow {
FXDECLARE(PaintWindow)
typedef std::map<std::pair<int, int>, point> PointMap;
private:
FXCanvas *canvas;
FXLabel *count_label;
FXFont *big_font;
int isMouseDown = 0;
FXColor drawColor = FXRGB(255, 0, 0);
FXColor bgColor = FXRGB(0, 0, 0);
PointMap pixels;
void setpixel(FXEvent *event);
protected:
PaintWindow() { }
public:
enum {
ID_CANVAS = FXMainWindow::ID_LAST,
};
long onPaint(FXObject *, FXSelector, void *);
long onMouseDown(FXObject *, FXSelector, void *);
long onMouseUp(FXObject *, FXSelector, void *);
long onMouseMove(FXObject *, FXSelector, void *);
PaintWindow(FXApp *a);
virtual void create();
virtual ~PaintWindow();
};
FXDEFMAP(PaintWindow) PaintWindowMap[] = { // определяем обработчики событий
FXMAPFUNC(SEL_PAINT, PaintWindow::ID_CANVAS, PaintWindow::onPaint),
FXMAPFUNC(SEL_LEFTBUTTONPRESS, PaintWindow::ID_CANVAS, PaintWindow::onMouseDown),
FXMAPFUNC(SEL_RIGHTBUTTONPRESS, PaintWindow::ID_CANVAS, PaintWindow::onMouseDown),
FXMAPFUNC(SEL_LEFTBUTTONRELEASE, PaintWindow::ID_CANVAS, PaintWindow::onMouseUp),
FXMAPFUNC(SEL_RIGHTBUTTONRELEASE, PaintWindow::ID_CANVAS, PaintWindow::onMouseUp),
FXMAPFUNC(SEL_MOTION, PaintWindow::ID_CANVAS, PaintWindow::onMouseMove)
};
FXIMPLEMENT(PaintWindow, FXMainWindow, PaintWindowMap, ARRAYNUMBER(PaintWindowMap))
PaintWindow::PaintWindow(FXApp *a) : FXMainWindow(a, a->getAppName(), NULL, NULL,
DECOR_ALL,
0, 0, 800, 600) {
FXMenuBar *menubar = new FXMenuBar(this,LAYOUT_SIDE_TOP|LAYOUT_FILL_X);
menubar->setBackColor(FXRGB(208,203,201));
FXMenuPane *filemenu = new FXMenuPane(menubar);
new FXMenuCommand(filemenu,"&New\tCtl-N",NULL,NULL);
new FXMenuCommand(filemenu,"&Open\tCtl-O",NULL,NULL);
new FXMenuCommand(filemenu,"&Save\tCtl-S",NULL,NULL);
new FXMenuCommand(filemenu,"&Save as\t Shift-Ctl-S",NULL,NULL);
new FXMenuSeparator(filemenu);
new FXMenuCommand(filemenu,"&Quit\tCtl-Q\tQuit the application.",NULL,NULL);
new FXMenuTitle(menubar,"&File",NULL,filemenu);
FXMenuPane *scenemenu = new FXMenuPane(menubar);
new FXMenuCommand(scenemenu,"&Build",NULL,NULL);
new FXMenuCheck(scenemenu,"&Build on open",NULL);
new FXMenuSeparator(scenemenu);
new FXMenuCommand(scenemenu,"&Render",NULL,NULL);
new FXMenuCommand(scenemenu,"&IPR",NULL,NULL);
new FXMenuCheck(scenemenu,"&Auto Clear Log",NULL);
new FXMenuSeparator(scenemenu);
new FXMenuCommand(scenemenu,"&Clear Texture Cache",NULL,NULL);
new FXMenuCheck(scenemenu,"&Low memory triangles",NULL);
new FXMenuTitle(menubar,"&Scene",NULL,scenemenu);
FXMenuPane *imagemenu = new FXMenuPane(menubar);
new FXMenuCommand(imagemenu,"&Reset Zoom",NULL,NULL);
new FXMenuCommand(imagemenu,"&Fit to Window",NULL,NULL);
new FXMenuSeparator(imagemenu);
new FXMenuCommand(imagemenu,"&Save image",NULL,NULL);
new FXMenuTitle(menubar,"&Image",NULL,imagemenu);
FXMenuPane *helpmenu = new FXMenuPane(menubar);
new FXMenuCommand(helpmenu,"&About Sunflow",NULL,NULL);
new FXMenuCommand(helpmenu,"&About FOX-1.7",NULL,NULL);
new FXMenuTitle(menubar,"&Help",NULL,helpmenu);
FXHorizontalFrame *container=new FXHorizontalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED);
container->setBackColor(FXRGB(226,223,222));
FXHorizontalFrame *chartwell=new FXHorizontalFrame(container,FRAME_SUNKEN|LAYOUT_FILL_X|
LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT,
0,0,0,0,10,10,10,10);
canvas = new FXCanvas(chartwell, this, ID_CANVAS, LAYOUT_FILL_X|LAYOUT_FILL_Y);
//count_label = new FXLabel(chartwell, "...", NULL, LAYOUT_EXPLICIT, 34, 177, 133, 56);
}
PaintWindow::~PaintWindow() {
}
void PaintWindow::create() {
FXMainWindow::create();
show(PLACEMENT_SCREEN); //показываем окно в центре экрана
}
void PaintWindow::setpixel(FXEvent *event) {
int x = event->win_x;
int y = event->win_y;
x = (event->win_x + 2) / GRID_LEN;
y = (event->win_y + 2) / GRID_LEN;
std::pair<int, int> p = std::make_pair(x * GRID_LEN, y * GRID_LEN); // создаём хеш из двух координат
FXDCWindow dc(canvas);
bool add = event->click_button == 1; // если кнопка левая, то рисуем, правой - удаляем
dc.setForeground(add ? drawColor : bgColor);
if (add) {
point pixel;
pixel.x = x * GRID_LEN;
pixel.y = y * GRID_LEN;
pixels[p] = pixel;
} else {
pixels.erase(p);
}
dc.fillRectangle(x * GRID_LEN, y * GRID_LEN, GRID_LEN, GRID_LEN); // рисуем квадратики
sprintf(buf, "%lu px", pixels.size());
//count_label->setText(buf); // обновляем надпись
}
long PaintWindow::onMouseUp(FXObject *, FXSelector, void *ptr) { // при отпускании мыши
canvas->ungrab(); // отключаем перетаскивание в холсте
if (isMouseDown) {
FXDCWindow dc(canvas);
dc.setForeground(drawColor);
isMouseDown = 0;
}
return 1;
}
long PaintWindow::onMouseDown(FXObject *, FXSelector, void *ptr) { // при нажатии мыши
canvas->grab(); // включаем перетаскивание в холсте
setpixel((FXEvent *) ptr);
isMouseDown = 1;
return 1;
}
long PaintWindow::onMouseMove(FXObject *, FXSelector, void *ptr) {
if (isMouseDown) {
setpixel((FXEvent *) ptr);
}
return 1;
}
long PaintWindow::onPaint(FXObject *, FXSelector,
void *ptr) { //если окно сворачивается или выходит за пределы видимости, то его нужно перерисовать
FXEvent *ev = (FXEvent *) ptr;
FXDCWindow dc(canvas, ev);
dc.setForeground(bgColor);
dc.fillRectangle(ev->rect.x, ev->rect.y, ev->rect.w, ev->rect.h);
typedef PointMap::iterator it_type;
for (it_type iterator = pixels.begin();
iterator != pixels.end(); iterator++) { // перебираем все пиксели наносим их на холст
int x = iterator->second.x;
int y = iterator->second.y;
dc.setForeground(drawColor);
dc.fillRectangle(x, y, GRID_LEN, GRID_LEN);
}
return 1;
}
using namespace std;
void usage() {
cout << endl;
cout <<"Usage: sunflow [options] scenefile"<< endl;
cout << endl;
cout <<"Options:"<< endl;
cout << endl;
cout <<" -o filename Saves the output as the specified filename (png, hdr, tga)"<< endl;
cout <<" -nogui Don't open the frame showing rendering progress"<< endl;
cout <<" -ipr Render using progressive algorithm"<< endl;
cout <<" -sampler type Render using the specified algorithm"<< endl;
cout <<" -threads n Render using n threads"<< endl;
cout <<" -lopri Set thread priority to low (default)"<< endl;
cout <<" -hipri Set thread priority to high"<< endl;
cout <<" -smallmesh Load triangle meshes using triangles optimized for memory use"<< endl;
cout <<" -dumpkd Dump KDTree to an obj file for visualization"<< endl;
cout <<" -buildonly Do not call render method after loading the scene"<< endl;
cout <<" -showaa Display sampling levels per pixel for bucket renderer"<< endl;
cout <<" -nogi Disable any global illumination engines in the scene"<< endl;
cout <<" -nocaustics Disable any caustic engine in the scene"<< endl;
cout <<" -pathgi n Use path tracing with n samples to render global illumination"<< endl;
cout <<" -quick_ambocc d Applies ambient occlusion to the scene with specified maximum distance"<< endl;
cout <<" -quick_uvs Applies a surface uv visualization shader to the scene"<< endl;
cout <<" -quick_normals Applies a surface normal visualization shader to the scene"<< endl;
cout <<" -quick_id Renders using a unique color for each instance"<< endl;
cout <<" -quick_prims Renders using a unique color for each primitive"<< endl;
cout <<" -quick_gray Renders using a plain gray diffuse shader"<< endl;
cout <<" -quick_wire Renders using a wireframe shader"<< endl;
cout <<" -resolution w h Changes the render resolution to the specified width and height (in pixels)"<< endl;
cout <<" -aa min max Overrides the image anti-aliasing depths"<< endl;
cout <<" -samples n Overrides the image sample count (affects bucket and multipass samplers)"<< endl;
cout <<" -bucket n order Changes the default bucket size to n pixels and the default order"<< endl;
cout <<" -bake name Bakes a lightmap for the specified instance"<< endl;
cout <<" -bakedir dir Selects the type of lightmap baking: dir=view or ortho"<< endl;
cout <<" -filter type Selects the image filter to use"<< endl;
cout <<" -bench Run several built-in scenes for benchmark purposes"<< endl;
cout <<" -rtbench Run realtime ray-tracing benchmark"<< endl;
cout <<" -frame n Set frame number to the specified value"<< endl;
cout <<" -anim n1 n2 Render all frames between the two specified values (inclusive)"<< endl;
cout <<" -translate file Translate input scene to the specified filename"<< endl;
cout <<" -v verbosity Set the verbosity level: 0=none,1=errors,2=warnings,3=info,4=detailed"<< endl;
cout <<" -h Prints this message"<< endl;
}
char* getCmdOption(char ** begin, char ** end, const std::string & option)
{
char ** itr = std::find(begin, end, option);
if (itr != end && ++itr != end)
{
return *itr;
}
return 0;
}
bool cmdOptionExists(char** begin, char** end, const std::string& option)
{
return std::find(begin, end, option) != end;
}
int main(int argc, char * argv[])
{
if ( (argc <= 1) || (argv[argc-1] == NULL) ) {
FXApp application("Sunflow", "Sunflow");
application.init(argc, argv);
new PaintWindow(&application);
application.create();
return application.run();
}
if(cmdOptionExists(argv, argv+argc, "-t"))
{
cout << "flag = t" << endl;
}
if(cmdOptionExists(argv, argv+argc, "--help"))
{
usage();
}
char * numthreads = getCmdOption(argv, argv + argc, "-t");
if (numthreads)
{
cout << "threads = " << numthreads << endl;
}
char * filename = getCmdOption(argv, argv + argc, "-f");
if (filename)
{
cout << "filename = " << filename << endl;
}
return 0;
}
Чтобы ездить на автомобиле, вовсе нет необходимости знать устройство двигателя.Чтобы ездить - да , знаний устройства не нужно... но не чтобы модернизировать старый или создать новый двигатель :)
Как говорил Ленин: "Мы пойдём другим путём"ЦитироватьЧтобы ездить на автомобиле, вовсе нет необходимости знать устройство двигателя.Чтобы ездить - да , знаний устройства не нужно... но не чтобы модернизировать старый или создать новый двигатель :)
Фиг его знает, Ланухумыч... мне в школе на УПК рассказывали про АЛУ, УУ, шину данных, шину адреса и т.п. кибернетику :) ... было не очень интересно, и думал нахрен это не нужно :) один хрен, посути архитектура компов осталась та же... теперь понимаю, что это была полезная фундаментальная инфа...Я тебе ещё раз говорю, чтобы добавить фишку Блендеру не нужно изучать шины, и не нужно начинать писать новый редактор 3d с нуля. Нужно накапливать опыт. Потому и беру fox toolkit. Это такая маленькая фигня, что даже, если завтра её кто-то захочет поставить до горы раком, как это делают GTK и Qt, я смогу оригинал поддерживать самостоятельно. У меня совсем другие мысли. Мысли, как сохранить хорошие идеи...
>> Чем идея отличается от знания её осуществления?хороший вопрос, и очень правильный...
... мы же и боремся за идею, или точнее за её спасение ...
... и для этого есть ключ - постановка задачи, она же описание мечты, но более конкретная, формальная ...
... вопрос про визуализацию точки был конкретный, то есть что нужно для этого и сколько ...
>> Чем идея отличается от знания её осуществления?Я, наверное, туго всасываю. Вы мне про ноды для Поврея подобное чесали: концепция и тому подобное...
... мы же и боремся за идею, или точнее за её спасение ...
... и для этого есть ключ - постановка задачи, она же описание мечты, но более конкретная, формальная ...
... вопрос про визуализацию точки был конкретный, то есть что нужно для этого и сколько ...
В числах это выглядит примерно так: в 50 раз и более быстрее рендера Cycles.мож это и есть допинг с которым тебя на олимпиаду не пускают.....
>> в 50 раз и более быстрее рендера Cycles.Ты сделай скриншот кадра анимации, созданной в Cycles, и скажи, нахрена ты так старался?
... неплохо ...
... то есть также как Cycles, только быстрее? ...
фигасе!У тебя день рождения закончился?
ты чё нам от этого отказаться впариваешь?
на обед не позвалживу не богато,
... мои вопросы уточняющие, это нормальная практика описания постановки задачи ...Это другой вопрос.
... допустим у нас есть определённое количество программистов, которым мы должны выдать задание на модернизацию кода ...
... кроме как "фас и куси" по этой теме мне сейчас сказать им нечего ...
... то есть где и что делать-то? ...
>> сломлен.офигевааю...;D ;D ;D ;D ;D
... ты должен быть сломлен в двойне, тёще поклон не передал, на следующий день на обед не позвал ... ...
Внутри каждой большой задачи сидит маленькая, пытающаяся пробиться наружу. (с)Холивар будет, это закон. Этот закон скорей всего придумали те, кто переписывает кутю ,гэтэка и Блендер. У них свои цели, я стою у них на пути, меня надо дезориентировать...
LanuHum, хреново если начинается холивар из-за рендереров... на самом деле идеального рендерера нет и не будет... каждый заточен под конкретные задачи в большей или в меньшей степени... а ускорить виз можно включая мозг на уровне моделирования, текстурирования и композа, при желании...
Но это не значит, что твоя затея с новым рендерером плоха... есть желание и интерес - вперёд... вчера писал тебе, что смысл этого только в самообразовании (изучении C++ , если я правильно понял)
А идеальный рендер мне не нужен, мне нужно всего лишь в 50 раз быстрей чем Cycles... :)8) однако :) мозх побереги :)
>> Или, может, ты выяснишь со своей командой разработчиков, что такое threadlocal<threadcontext>?В тайне пытаюсь ArtOfIllusion воспроизвести на плюсах.
... хорошо, если не сложно и есть такая возможность напиши что делаешь и что не получается ...
public Raytracer(Scene scene, Camera camera)
{
this.scene = scene;
this.camera = camera;
factories = PluginRegistry.getPlugins(RTObjectFactory.class);
objectList = Collections.synchronizedList(new ArrayList<RTObject>());
lightList = Collections.synchronizedList(new ArrayList<RTLight>());
threadContext = new ThreadLocal<RaytracerContext>() {
protected RaytracerContext initialValue()
{
return new RaytracerContext(Raytracer.this);
}
};
}
threadContext = new ThreadLocal<RaytracerContext>() {
protected RaytracerContext initialValue()
{
https://geektimes.ru/post/278470/ЦитироватьА идеальный рендер мне не нужен, мне нужно всего лишь в 50 раз быстрей чем Cycles... :)8) однако :) мозх побереги :)
Да понял я, что ты из шизотерики не вылезал :) ...ничё, бывает, сам такой временами :)Неправильно сказать: "Дурак тот, кто из шизотерики вылез"
:) верноЕсли б ты только знал, сколько раз я уже всё бросал...
Ну не ломает же :) ...Да, нужно с ним разбираться. Сначала попытаюсь загружать меш из блендера, затем в него нужно впилить стекло.
Хватит околонаучного бреда...:) Ты чего думаешь делать дальше? Всерьёз возьмёшься за предложенный тобой последний рендерер на C++, или ...?
фот так sungreen чуваки свечку держат.... переживают....>> сломлен.офигевааю...;D ;D ;D ;D ;D
... ты должен быть сломлен в двойне, тёще поклон не передал, на следующий день на обед не позвал ... ...
обратись к врачу психиатру...скорее всего не в нас проблема... серьёзно.фот так sungreen чуваки свечку держат.... переживают....>> сломлен.офигевааю...;D ;D ;D ;D ;D
... ты должен быть сломлен в двойне, тёще поклон не передал, на следующий день на обед не позвал ... ...
у вас чё, губа не закатывается....
не могу с этим помочь.
......................
вы фот над моей МАМКОЙ постеблись.... а к своей хоть позвонили - гавнюки...
.........................
скокож в вас говна....
Самовар. ты РУССКИХ букв не понимаешь.я нациков КАК ТЫ не понимаю...
я нациков КАК ТЫ не понимаю...или кем не надо быть....
... поясни проблему ...>> Или, может, ты выяснишь со своей командой разработчиков, что такое threadlocal<threadcontext>?В тайне пытаюсь ArtOfIllusion воспроизвести на плюсах.
... хорошо, если не сложно и есть такая возможность напиши что делаешь и что не получается ...
Код на Джаве (/home/leonid/workspace/programming/aoi/java/AoIsrc302/Renderers/src/artofillusion/raytracer/Raytracer.java):КодНикак не пойму, что такоеpublic Raytracer(Scene scene, Camera camera)
{
this.scene = scene;
this.camera = camera;
factories = PluginRegistry.getPlugins(RTObjectFactory.class);
objectList = Collections.synchronizedList(new ArrayList<RTObject>());
lightList = Collections.synchronizedList(new ArrayList<RTLight>());
threadContext = new ThreadLocal<RaytracerContext>() {
protected RaytracerContext initialValue()
{
return new RaytracerContext(Raytracer.this);
}
};
}КодthreadContext = new ThreadLocal<RaytracerContext>() {
protected RaytracerContext initialValue()
{
>> В тайне пытаюсь ArtOfIllusion воспроизвести на плюсах.Про delete в С++ я знаю. И, главное, чтоб хоть как-то заработало, чтоб понять, как оно работает. В нерабочем коде я не могу разбираться.
... перенос кода это очень неблагодарная работа ...
... наверное нужно в этой затее учесть работу сборщика мусора в java и в самом простом варианте возможна утечка памяти ...
... то есть перенесённый код будет очень похож на правильный и будет даже работать, но недолго ...
... поясни проблему ...
Не пойму, что должен возвратит
Я ходил вот сюда:Сходи и сюда для разнообразия: http://www.enlight.ru/faq3d/content.htm
http://ray-tracing.ru/articles181.html
Ну и что? Это теория. А, когда я ковыряюсь в рабочем коде, я начинаю понимать, как это дерево строится. А, как написать этот код правильно согласно языку программирования - это уже другой вопрос.
Сходи и сюда для разнообразия: http://www.enlight.ru/faq3d/content.htmАга, это можно почитать. Благодарю.
Bdancer крут, не крут...Он просто оказался в нужное время в нужном месте.Это в каком же, интересно, месте я оказался-то?
А проблему в коде я показал, я не знаю откуда берётся и что создаёт этот ThreadLocal<RaytracerContext>() и почему оно вызывает initialValue(), которого в классе RaytracerContext я что-то не вижуhttps://docs.oracle.com/javase/8/docs/api/java/lang/ThreadLocal.html
>> и почему оно вызывает initialValue(), которого в классе RaytracerContext я что-то не вижуОписание метода разве не подразумевает понимание того, что мы собираемся делать?
... так в этом коде нет вызова, это описание метода, не так ли? ...
Это в каком же, интересно, месте я оказался-то?Я же написал: В НУЖНОМ. Я вот в ненужном для меня месте, а ты в нужном для тебя. Чё неясно-то? Хотел уже оскорбиться? :) :) :)
https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadLocal.htmlТы уже давным давно ещё на БУ мне признался, что ты страшный и злой. :)
... тогда спрошу как токарь токаря, сколько нужно инструкций процессора чтобы визуализировать одну точку? ...вопрос конкретный, конечно, но пока я его рассматриваю как риторический :)
Dim As Integer hor=800, vert=600, count '' определение целых переменных
Dim As Double start=Timer '' определение переменных с плавающей точкой
ScreenRes (hor, vert, 24) '' установка разрешения окна и глубины (число бит) цвета
'' функция получения случайного целого числа в диапозоне 0-255 для одной из компоненты RGB цвета
Function Col As Integer
Return Int(Rnd*255)
End Function
'' функция получения случайного целого числа в диапазоне от 0 до n
Function Poz(n As Integer) As Integer
Return Int(Rnd*n)
End Function
'' главный цикл
Do While inkey = "" '' пока не нажата любая клавиша
For count = 1 To 1000000 '' повторяем миллион раз
PSet (Poz(hor), Poz(vert)), RGB(Col, Col, Col) '' рисуем точку случайным цветом в случайной позиции
Next
'' выводим время отрисовки миллиона пикселей в заголовок окна
WindowTitle "Draw million pixels time: "+Str(Int((Timer-start)*100)/100)+" sec."
start=Timer '' присваиваем значение переменной из системного таймера
Loop '' продолжаем главный цикл сначала
End '' завершение работы
вопрос конкретный,конечно, по пока я его рассматриваю как риторический :)Есть у меня желание, нет, но С++ я ковыряю всё-равно.
Итак, вернёмся к нашим "тараканам"...если ещё желание у автора темы не пропало ковырять C++
Набросал маленькую программку на FreeBasic:
Если есть желание, повтори на C++, LanuHum
повтори на C++, LanuHumВот часть кода:
#include <iostream>
#include <vector>
#include <random>
using namespace std;
unsigned int hor = 800, vert = 600; // задаём размер изображения
unsigned long pixels = hor * vert; // вычисляем число пикселов
vector<unsigned int [4]> image(pixels); // создаём базу данных для чёрного изображения
int main(void) {
const int max_value = 255; // указываем максимальную величину цвета
unsigned long pixel_number = rand() % pixels; // выбираем случайный пиксел
unsigned int r, g, b, a; // объявляем переменные цветов и альфы
r = rand() % max_value; // случайный красный
g = rand() % max_value; // случайный зелёный
b = rand() % max_value; // случайный синий
a = rand() % max_value; // случайная альфа
image[pixel_number][0] = r; // заменяем в случайно выбранном пикселе чёрной картинки красный
image[pixel_number][1] = g; // заменяем в случайно выбранном пикселе чёрной картинки зелёный
image[pixel_number][2] = b; // заменяем в случайно выбранном пикселе чёрной картинки синий
image[pixel_number][3] = a; // заменяем в случайно выбранном пикселе чёрной картинки альфу
std::cout <<r<<" "<<g<<" "<<b<<" "<<a<< std::endl; // тестируем работоспособность функции просьбой вывести на экран полученный случайный цвет
return 0;
}
Меняем main(void) на RenderSimulator()
Теперь нужно отыскать в libfox, которая будет рисовать окно, таймер.
Вот часть кода:Не торопись. Жду целиком, чтобы собрать и протестировать скорость.
Не торопись. Жду целиком, чтобы собрать и протестировать скорость.Да, тут поторопишься, блин!
// распространять среди друзей и подруг строго запрещается!
// лицензия!!!
#include "fox-1.6/fx.h"
#include <time.h>
#include <iostream>
using namespace std;
class ImageWindow : public FXMainWindow{
FXDECLARE(ImageWindow)
protected:
ImageWindow(){}
private:
FXCanvas *canvas;
FXColor bgColor = FXRGB(0, 0, 0);
public:
enum {
ID_CANVAS = FXMainWindow::ID_LAST,
};
long onPaint(FXObject *, FXSelector, void *);
long onMouseDown(FXObject *, FXSelector, void *);
public:
ImageWindow(FXApp* a);
virtual void create();
virtual ~ImageWindow();
};
FXDEFMAP(ImageWindow) ImageWindowMap[] = {
FXMAPFUNC(SEL_PAINT, ImageWindow::ID_CANVAS, ImageWindow::onPaint),
FXMAPFUNC(SEL_LEFTBUTTONPRESS, ImageWindow::ID_CANVAS, ImageWindow::onMouseDown)
};
FXIMPLEMENT(ImageWindow, FXMainWindow, ImageWindowMap, ARRAYNUMBER(ImageWindowMap))
ImageWindow::ImageWindow(FXApp* a):FXMainWindow(a,"FOX Render",NULL,NULL,DECOR_ALL,0,0,850,600,0,0){
FXHorizontalFrame *container=new FXHorizontalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED);
container->setBackColor(FXRGB(226,223,222));
FXHorizontalFrame *chartwell=new FXHorizontalFrame(container,FRAME_SUNKEN|LAYOUT_FILL_X|
LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT,
0,0,0,0,10,10,10,10);
canvas = new FXCanvas(chartwell, this, ID_CANVAS, LAYOUT_FILL_X|LAYOUT_FILL_Y);
}
ImageWindow::~ImageWindow() {
}
void ImageWindow::create() {
FXMainWindow::create();
show(PLACEMENT_SCREEN);
}
long ImageWindow::onPaint(FXObject *, FXSelector,void *ptr) {
FXEvent *ev = (FXEvent *) ptr;
FXDCWindow dc(canvas, ev);
dc.setForeground(bgColor);
dc.fillRectangle(0,0,canvas->getWidth(),canvas->getHeight());
return 1;
}
timespec diff(timespec start, timespec end);
long ImageWindow::onMouseDown(FXObject *, FXSelector, void *ptr){
//timespec time1, time2;
//int temp;
//clock_gettime(CLOCK_MONOTONIC_RAW , &time1);
//for (int i = 0; i< 242000000; i++)
//temp+=temp;
//clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
//std::cout<<diff(time1,time2).tv_sec<<":"<<diff(time1,time2).tv_nsec<<std::endl;
long b = 0;
double sec = 20.0000567;
FXString name;
name = FXStringVal(sec);
this->setTitle(name);
return b;
}
int main(int argc,char *argv[]){
FXApp application("FoxTest","FoxTest");
application.init(argc,argv);
new ImageWindow(&application);
application.create();
return application.run();
}
Ну ты и намутил :) Нафига эта fox-1.6/fx.h ???Я не знаю, что такое graphics.h
А стандартная graphics.h разве не подойдёт?
Можешь переписать с комментариями как тут?
http://ci-plus-plus-snachala.ru/?p=67 (http://blender-3d.ru/forum/go.php?url=aHR0cDovL2NpLXBsdXMtcGx1cy1zbmFjaGFsYS5ydS8/cD02Nw==)
...а то тож хочу потихоньку начать врубаться ...
... будет разумным сразу разделить код на ту часть, которая отвечает за интерфейсные вещи и часть, которая обеспечивает формирование массива данных и прописать между ними взаимодействие ...Думается, как бы не пойти на поводу у советчиков. В С++ как и в С есть такая фишка, которая называется inline. Хочешь, чтобы было крайне быстро, то функцию вставляешь непосредственно в место её выполнения, а не пишешь либу с функцией, ссылаясь потом на либу. Нужно несколько раз - пишешь одну и ту же функцию несколько раз, именно там, где она требуется.
... то есть мешать все в одну кучу и связывать это с какой-то гуишной библиотекой крайне нежелательно ...
Ну ты и намутил :) Нафига эта fox-1.6/fx.h ???Человек хочет получить реальные результаты тестов по производительности, но при этом хочет взять что-то неопределённое, двоечником на С++ написанное, сравнить с гамбасом, а потом стучать себя в грудь и говорить, что разницы он не увидел: гамбас крут!
А стандартная graphics.h разве не подойдёт?
FOX Toolkit — кросс-платформенная библиотека инструментов с открытым исходным кодом (лицензия LGPL) для построения графического интерфейса пользователя.Это к тому, что я хочу наблюдать процесс рендера, смотреть как тайлы один за одним открываются... А, если гуёвина будет тормозить, не успевая за GPU, это неинтересно.
Один из самых быстрых пакетов, содержит большое число элементов GUI и поддержку OpenGL.
Можешь переписать с комментариями как тут?Сказать честно, не могу прокомментировать подробно. Неплохая книжонка для понимания кода cpp-za-21-den.pdf (Изучаем С++ за 21 день). Название вызывает смех, но там есть то, что позволит понять, что написано в моём коде.
Человек хочет получить реальные результаты тестов по производительности, но при этом хочет взять что-то неопределённое, двоечником на С++ написанное, сравнить с гамбасом, а потом стучать себя в грудь и говорить, что разницы он не увидел: гамбас крут!;D ;D ;D рассмешил ;D ;D ;D
''#Include "fbgfx.bi" '' это пока нафиг не нужно
Dim As Integer hor=800, vert=600, count '' определение натуральных (целых) переменных
Dim As Double start=Timer '' определение вещественных (с плавающей точкой) переменных
ScreenRes (hor, vert, 24) '' установка разрешения окна и глубины (число бит) цвета
'' функция получения случайного целого числа в диапазоне от 0 до n
Function Poz(n As Integer) As Integer
Return Rnd*n
End Function
'' главный цикл
Do While inkey = "" '' пока не нажата любая клавиша
For count = 1 To 1000000 '' повторяем миллион раз
PSet (Poz(hor), Poz(vert)), Rnd*&hFFFFFF '' рисуем точку случайным цветом в случайной позиции
Next
'' выводим время отрисовки миллиона пикселей в заголовок окна
WindowTitle "Draw million pixels time: "+Str(Int((Timer-start)*100)/100)+" sec."
start=Timer '' присваиваем значение переменной из системного таймера
Loop '' продолжаем главный цикл сначала
End '' завершение работы
Если не хочешь или не можешь написать эту простенькую прогу на Си, то так и скажи.Я не могу нарисовать окно непосредственно используя видеодрайвер. Доволен? Но, вот твои слова:
Не торопись. Жду целиком, чтобы собрать и протестировать скорость.Так вот теперь ты мне скажи, ты хочешь протестировать скорость или ты хочешь ткнуть в меня пальцем?
С чего ты взял, что я хочу протестить скорость?В. Высоцкий:
чтобы собрать и протестировать скорость.
А мне чё, да ни чё, осталось только материться
В общем, попробую сам написать на Си.Сказать честно, поняв твою цель, у меня и нет желания портировать её. Это лишние знания. Завтра я буду учиться ЧПУ, а послезавтра буду искать, почему я время не могу померять в этой грёбаной проге. :)
' PhotonMapping
#ifndef true
#define true -1
#define false 0
#endif
Type float As single 'double
Const As Integer xDimension = 512
Const As Integer yDimension = 512
Const As Integer nTypes = 2 ' two types of objects sphere and plane
Const As Integer MaxPhotons = 200
Const As Integer MaxPhotonRefections = 1
Const As float PhotonSize = 0.1
Const As float gInverseSquared = 1.0 / PhotonSize * PhotonSize
Const As float MilliSeconds = 500
Const As float gExposure = 1.0 / (1000 / MilliSeconds)
Const As Integer MaxRaytraceRefections = 12
#define nSpheres 3 ' number of spheres
#define nPlanes 6 ' number of planes (a box)
Dim Shared As float Ratio
Dim Shared As Integer gNObjects(1) = {nSpheres,nPlanes&}
Dim Shared As float gAmbient = 0
Dim Shared As float gOrigin(2)
Dim Shared As float gLight(2) = {0,1.0,4} 'x,y,z position
Dim Shared As float gSpheres(nSpheres-1,3) = {_
{-1.0,-1.0,4.0, 0.5} , _
{ 6.4, 0.0,2.8, 5.0} , _
{ 1.0,-1.0,4.0, 0.5}}
' x,y,z, position and radius
Dim Shared As float gPlanes(nPlanes-1,1) = {_
{0, 1.5}, _
{0, -1.5}, _
{1, -1.5}, _
{1, 1.5}, _
{2, 5.0}, _
{2, -1.0}}
Dim Shared As Integer NumberOfPhotons(1,5)
Dim Shared As float gPhotons(nTypes,nPlanes+nSpheres, _
MaxPhotons + MaxPhotons*MaxPhotonRefections, _
2,2) '3 * x,y,z
Dim Shared As Integer gIntersect
Dim Shared As Integer gType
Dim Shared As Integer gIndex
Dim Shared As float gDist2,gDist
Dim Shared As float gPoint(2)
Function min(a As float ,b As float ) As float
If b<a Then Return b
Return a
End Function
Function max(a As float ,b As float ) As float
If b>a Then Return b
Return a
End Function
Function rnd2 As float
Return (Rnd-Rnd)
End Function
Function SquaredDistance(a() As float , _
b() As float , _
d2 As float ) As Integer
Dim As float ab = a(0) - b(0)
Dim As float d = ab*ab
If (d > d2) Then Return false
ab = a(1) - b(1)
d += ab*ab
If (d > d2) Then Return false
ab = a(2) - b(2)
d += ab*ab
If (d > d2) Then Return false
gDist2 = d
Return true
End Function
Sub SurfaceNormal(r() As float , _
typ As Integer, _
idx As Integer, _
HitPoint() As float , _
O() As float )
Dim As float Normal(2),L
If (typ = 0) Then
Normal(0)=HitPoint(0)-gSpheres(idx,0)
Normal(1)=HitPoint(1)-gSpheres(idx,1)
Normal(2)=HitPoint(2)-gSpheres(idx,2)
Elseif (typ = 1) Then
Dim As Integer axis = gPlanes(idx,0)
Normal(axis) = O(axis) - gPlanes(idx,1)
Else
'beep
End If
l=Normal(0)*Normal(0) _
+Normal(1)*Normal(1) _
+Normal(2)*Normal(2)
If l Then l=1/Sqr(l)
r(0)=Normal(0)*l
r(1)=Normal(1)*l
r(2)=Normal(2)*l
End Sub
Sub Mirror2(Ret() As float, _
Direction() As float, _
HitPoint() As float, _
Normale() As float)
Dim As float L
HitPoint(0)+=Direction(0)*-0.1
HitPoint(1)+=Direction(1)*-0.1
HitPoint(2)+=Direction(2)*-0.1
L = Normale(0)*Direction(0) _
+ Normale(1)*Direction(1) _
+ Normale(2)*Direction(2)
L*=-2
Ret(0)=Direction(0)+L*Normale(0)
Ret(1)=Direction(1)+L*Normale(1)
Ret(2)=Direction(2)+L*Normale(2)
End Sub
Sub MirrorVec(Ret() As float ,_
Direction() As float , _
Origin() As float )
Dim As float L,Normale(2)
SurfaceNormal(Normale(),gType, gIndex, gPoint(), Origin())
gPoint(0)+=Direction(0)*-0.1
gPoint(1)+=Direction(1)*-0.1
gPoint(2)+=Direction(2)*-0.1
L = Normale(0)*Direction(0) _
+ Normale(1)*Direction(1) _
+ Normale(2)*Direction(2)
L*=-2
Ret(0)=Direction(0)+L*Normale(0)
Ret(1)=Direction(1)+L*Normale(1)
Ret(2)=Direction(2)+L*Normale(2)
End Sub
'
' Raytracing
'
Sub Raytrace(RayDirection() As float ,RayOrigin() As float )
gIntersect = false
gDist = 999999.9
If gNObjects(1)>0 Then
For idx As Integer =0 To gNObjects(1)-1
Dim As Integer axis = gPlanes(idx,0)
If RayDirection(axis)<>0 Then
Dim As float l = (gPlanes(idx,1) - RayOrigin(axis)) / RayDirection(axis)
If (l>0) And (l<gDist) Then
gType = 1
gIndex = idx
gDist = l
gIntersect = true
End If
End If
Next
End If
If gNObjects(0)>0 Then
Dim As float SphereDirection(2)
Dim As float A = RayDirection(0)*RayDirection(0) _
+ RayDirection(1)*RayDirection(1) _
+ RayDirection(2)*RayDirection(2)
A+=A
For idx As Integer =0 To gNObjects(0)-1
SphereDirection(0)=RayOrigin(0)-gSpheres(idx,0)
SphereDirection(1)=RayOrigin(1)-gSpheres(idx,1)
SphereDirection(2)=RayOrigin(2)-gSpheres(idx,2)
Dim As float R = gSpheres(idx,3)*gSpheres(idx,3)
Dim As float B = SphereDirection(0)*RayDirection(0) _
+ SphereDirection(1)*RayDirection(1) _
+ SphereDirection(2)*RayDirection(2)
B+=B
Dim As float C = SphereDirection(0)*SphereDirection(0) _
+ SphereDirection(1)*SphereDirection(1) _
+ SphereDirection(2)*SphereDirection(2)
C-=R
Dim As float D = B*B - 2*A*C
If (D>0.0) Then
Dim As float sign = iif(C < -0.0001,1.0,-1.0)
Dim As float l = (-B + sign*Sqr(D))/A
If (l>0.0) And (l<gDist) Then
gType = 0
gIndex = idx
gDist = l
gIntersect = true
End If
End If
Next
End If
End Sub
Sub AbsorbColor(ret() As float , _
rgbIn() As float , _
r As float ,g As float ,b As float )
Dim As float rgbOut(2)={r,g,b}
For c As Integer =0 To 2
If rgbOut(c)<rgbIn(c) Then
ret(c)=rgbOut(c)
Else
ret(c)=rgbIn(c)
End If
Next
End Sub
Sub GetColor(r() As float , _
rgbIn() As float , _
typ As Integer, _
idx As Integer)
If (typ=0) Then ' spheres
If idx=0 Then
AbsorbColor(r(),rgbIn(), 0.0,0.0,0.0)
Elseif idx=1 Then
AbsorbColor(r(),rgbIn(), 0.0,0.0,0.0)
elseif idx=2 then
AbsorbColor(r(),rgbIn(), 0.2,0.2,0.
End If
Elseif (typ=1) Then ' planes
If idx=0 Then
AbsorbColor(r(),rgbIn(), 0.1, 0.8, 0.1) ' right
Elseif idx=1 Then
AbsorbColor(r(),rgbIn(), 0.8, 0.1, 0.1) ' left
Elseif idx=2 Then
AbsorbColor(r(),rgbIn(), 0.5, 0.5, 0.0) ' floor
Elseif idx=3 Then
AbsorbColor(r(),rgbIn(), 0.2, 0.2, 0.2) ' ceil
Elseif idx=4 Then
AbsorbColor(r(),rgbIn(), 0.0, 0.0, 0.0) ' front
Elseif idx=5 Then
AbsorbColor(r(),rgbIn(), 0.0, 0.0, 0.0) ' behind camera
End If
End If
End Sub
'
' Photon Mapping
'
Sub GatherPhotons(energy() As float , _
HitPoint() As float , _
typ As Integer, _
idx As Integer)
Dim As float N(2)
Dim As float v(2)
Dim As float weight
Dim As float frgb(2)
SurfaceNormal(N(), typ, idx, HitPoint(), gOrigin())
For i As Integer = 0 To NumberOfPhotons(typ,idx)-1
' photon location
v(0)=gPhotons(typ,idx,i,0,0)
v(1)=gPhotons(typ,idx,i,0,1)
v(2)=gPhotons(typ,idx,i,0,2)
' in the near of an active photon ?
If (SquaredDistance(HitPoint(),v(),gInverseSquared)) Then
' photon direction
Dim As float cosin = N(0)*gPhotons(typ,idx,i,1,0) _
+ N(1)*gPhotons(typ,idx,i,1,1) _
+ N(2)*gPhotons(typ,idx,i,1,2)
weight = max(0.0, -cosin)
if weight then
weight *= (1.0 - sqr(gDist2)) * gExposure
if weight then
' photon energy
frgb(0)+=gPhotons(typ,idx,i,2,0)*weight
frgb(1)+=gPhotons(typ,idx,i,2,1)*weight
frgb(2)+=gPhotons(typ,idx,i,2,2)*weight
end if
end if
End If
Next
For j As Integer=0 To 2
energy(j)=max(0,min(1,frgb(j) ) )
Next
End Sub
Sub StorePhoton(typ As Integer, _
idx As Integer, _
l() As float ,_
d() As float , _
e() As float )
Dim As Integer Photon=NumberOfPhotons(typ,idx)
For i As Integer=0 To 2
gPhotons(typ,idx,Photon,0,i) = l(i) ' Location
gPhotons(typ,idx,Photon,1,i) = d(i) ' Direction
gPhotons(typ,idx,Photon,2,i) = e(i) ' Energy
Next
NumberOfPhotons(typ,idx)=Photon+1
End Sub
Sub ShadowPhoton(RayDirection() As float )
static As float BumpedPoint(2)
static As float ShadowPoint(2)
Static As float ShadowEnerg(2) = {-0.2,-0.2,-0.2}
Dim As float OldPoint(2) = {gPoint(0), gPoint(1),gPoint(2)}
Dim As Integer OldType = gType
Dim As Integer OldIndex = gIndex
Dim As float OldDist = gDist
BumpedPoint(0)=gPoint(0)+RayDirection(0)*0.000001
BumpedPoint(1)=gPoint(1)+RayDirection(1)*0.000001
BumpedPoint(2)=gPoint(2)+RayDirection(2)*0.000001
Raytrace(RayDirection(), BumpedPoint())
ShadowPoint(0)=BumpedPoint(0)+RayDirection(0)*gDist
ShadowPoint(1)=BumpedPoint(1)+RayDirection(1)*gDist
ShadowPoint(2)=BumpedPoint(2)+RayDirection(2)*gDist
StorePhoton(gType, gIndex, ShadowPoint(), RayDirection(), ShadowEnerg())
gPoint(0) = OldPoint(0)
gPoint(1) = OldPoint(1)
gPoint(2) = OldPoint(2)
gType = OldType
gIndex = OldIndex
gDist = OldDist
End Sub
Sub EmitPhotons
randomize 1 'timer
dim As float PhotonEnergy(2)
dim As float PhotonDirection(2)
dim As float PhotonOrigin(2),l
For typ As Integer = 0 To nTypes-1
For idx As Integer = 0 To gNObjects(typ)-1
NumberOfPhotons(typ,idx) = 0
Next
Next
For i As Integer = 0 To MaxPhotons-1
Dim As Integer Reflection = 0
' random photon Energy
PhotonEnergy(0)=rnd
PhotonEnergy(1)=rnd
PhotonEnergy(2)=rnd
#if 0
' normalize energy
l = PhotonEnergy(0)*PhotonEnergy(0) _
+ PhotonEnergy(1)*PhotonEnergy(1) _
+ PhotonEnergy(2)*PhotonEnergy(2)
if l then
l=1.0/sqr(l)
PhotonEnergy(0)*=l
PhotonEnergy(1)*=l
PhotonEnergy(2)*=l
end if
#endif
' radom photon Direction
PhotonDirection(0)= rnd2
PhotonDirection(1)= rnd2*2
PhotonDirection(2)= rnd2
#if 0
' normalize direction
l = PhotonDirection(0)*PhotonDirection(0) _
+ PhotonDirection(1)*PhotonDirection(1) _
+ PhotonDirection(2)*PhotonDirection(2)
if l then
l=1.0/sqr(l)
PhotonDirection(0)*=l
PhotonDirection(1)*=l
PhotonDirection(2)*=l
end if
#endif
' photon position origin from light
PhotonOrigin(0)=gLight(0)
PhotonOrigin(1)=gLight(1)
PhotonOrigin(2)=gLight(2)
Raytrace(PhotonDirection(), PhotonOrigin())
While (gIntersect<>0) And (Reflection < MaxPhotonRefections)
Reflection+=1
gPoint(0)=PhotonOrigin(0)+PhotonDirection(0)*gDist
gPoint(1)=PhotonOrigin(1)+PhotonDirection(1)*gDist
gPoint(2)=PhotonOrigin(2)+PhotonDirection(2)*gDist
GetColor(PhotonEnergy(),PhotonEnergy(),gType,gIndex)
#if 0
Dim As float l=1.0/Reflection
PhotonEnergy(0)*=l
PhotonEnergy(1)*=l
PhotonEnergy(2)*=l
#endif
StorePhoton(gType, gIndex, gPoint(), PhotonDirection(),PhotonEnergy())
ShadowPhoton(PhotonDirection())
MirrorVec(PhotonDirection(),PhotonDirection(),PhotonOrigin())
Raytrace(PhotonDirection(), gPoint())
PhotonOrigin(0)=gPoint(0)
PhotonOrigin(1)=gPoint(1)
PhotonOrigin(2)=gPoint(2)
Wend
Next
End Sub
Sub GetPixelColor(PixelRGB() As float , _
x As float ,y As float , z As float=1)
Dim As float RayDirection(2) = {x,y,z}
Raytrace(RayDirection(), gOrigin())
If (gIntersect) Then
gPoint(0)=gOrigin(0)+RayDirection(0)*gDist
gPoint(1)=gOrigin(1)+RayDirection(1)*gDist
gPoint(2)=gOrigin(2)+RayDirection(2)*gDist
GatherPhotons(PixelRGB(),gPoint(),gType,gIndex)
' If gType=0 or gIndex>3 Then
Dim As Integer nDivs=0,nReflection=0
Dim As float MirrorsRGB(2)
While ((gType=0 And gIndex<2) Or gIndex>3) And gIntersect And _
(nReflection<MaxRaytraceRefections)
nReflection+=1
MirrorVec(RayDirection(),RayDirection(),gOrigin())
Raytrace(RayDirection(), gPoint())
If (gIntersect) Then
Dim As float MirRGB(2)
nDivs+=1
gPoint(0)+=RayDirection(0)*gDist
gPoint(1)+=RayDirection(1)*gDist
gPoint(2)+=RayDirection(2)*gDist
GatherPhotons(MirRGB(),gPoint(),gType,gIndex)
MirrorsRGB(0)+=MirRGB(0)
MirrorsRGB(1)+=MirRGB(1)
MirrorsRGB(2)+=MirRGB(2)
End If
Wend
If nDivs>0 Then
MirrorsRGB(0)/=nDivs
MirrorsRGB(1)/=nDivs
MirrorsRGB(2)/=nDivs
PixelRGB(0)=PixelRGB(0)*0.25+MirrorsRGB(0)*0.75
PixelRGB(1)=PixelRGB(1)*0.25+MirrorsRGB(1)*0.75
PixelRGB(2)=PixelRGB(2)*0.25+MirrorsRGB(2)*0.75
End If
'End If
Else
PixelRGB(0)=1 ' !!! debug only !!!
PixelRGB(1)=0
PixelRGB(2)=1
End If
End Sub
Sub Render
Dim As Integer h,m,s,l,t
dim as float b(2),x,y
Dim As Double t1=Timer
WindowTitle " PhotonMapper rendering ..."
for t =0 to yDimension-1
Y = -(t/yDimension - 0.5)
screenlock
for l =0 to xDimension-1
X = (l/xDimension - 0.5)*Ratio
GetPixelColor(b(),x,y)
pset (l,t),rgb(b(0)*255,b(1)*255,b(2)*255)
next
screenunlock
next
s=timer-t1:h=s\3600:s-=h*3600:m=s\60:s-=m*60
WindowTitle "PhotonMapper done " & h & ":" & m & ":" & s
End Sub
'
' main
'
Ratio= iif(xDimension>yDimension, _
xDimension/yDimension, _
yDimension/xDimension)
Randomize Timer
ScreenRes xDimension,yDimension,24
EmitPhotons
Render
'Bsave "PhotonMapper.bmp",0
Sleep
#include <graphics.h>
#include <stdio.h>
int main( void)
{
//---------- Инициализация графики ----------//
int gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver,&gmode,"");
//---------- Конец инициализации -----------//
for (int i = 0; i < 1000000; i++)
{
putpixel(rand()%640,rand()%500,rand()%0xFFFF);
}
printf("End");
return 0;
}
Да я вполне согласен, что код FreеBasic может уступать коду С++, хотя компилятор gcc у обоих один и тот же :) Вообще речь не об этом... мне ж тоже интересно врубиться в Си.Я не вижу, что у freebasic в линуксе компилятор gcc. Отдельный пакет с бинарником fbc Для компиляции он и зызывается. В gcc для компиляции С++ кода используются оптимизации, которые ускоряют процесс, но по умолчанию отключены. Оптимизируется код freebasic или нет, я не знаю.
Я не вижу, что у freebasic в линуксе компилятор gccВообще используется https://ru.wikipedia.org/wiki/GNU_Binutils (http://blender-3d.ru/forum/go.php?url=aHR0cHM6Ly9ydS53aWtpcGVkaWEub3JnL3dpa2kvR05VX0JpbnV0aWxz)
Не думаю, что ты начал с простого. Вернее, может, и с простого, но закончится это ещё одной сторонней либой по рисованию окон. Одно дело пиксели покрасить, а другое дело, файловый диалог вызвать, чтобы выбрать файл для рендера, и пошло поехало...Да графический интерфейс можно любой навестить, как сделано в Pov-ray под Win... дело же не в нём, а в самом рендерере :)
>> Кстати, в том примере с пикселями у меня используется DirectX, потому так шустро... у тебя по идее это должен быть X11хрен его знает :) ... хотя, да, прочёл невнимательно...в справке так и написано: http://free-basic.ru/helprus/GfxLib.html (http://blender-3d.ru/forum/go.php?url=aHR0cDovL2ZyZWUtYmFzaWMucnUvaGVscHJ1cy9HZnhMaWIuaHRtbA==)
... наверное даже не x11, а opengl ...
' Интеграция OpenGL
#INCLUDE Once "GL/gl.bi"
'#INCLUDE Once "GL/glu.bi"
' Определение констант, которые важны для экрана
Const scrnX = 800
Const scrnY = 600
Const depth = 32
Const fullscreen = &h0 ' Полноэкранный режим ( &h0 = обычный, &h1 = полноэкранный )
Dim As String driver: Dim As Integer i: Dim As Double start
Screenres scrnX,scrnY,depth,,&h2 Or fullscreen '&h2 = режим OpenGL
ScreenInfo ,,,,,, driver
' Конфигурация OpenGL
glMatrixMode(GL_PROJECTION) ' Определение матрицы
glLoadIdentity
glViewport(0,0,scrnX,scrnY) ' Установка оси координат
glOrtho(0,scrnX,scrnY,0,-128,128)
glMatrixMode(GL_MODELVIEW) ' Отключить вывод невидимых частей
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
'glEnable GL_TEXTURE_2D ' Включение текстур
'glLoadIdentity
'glEnable(GL_DEPTH_TEST) ' Тест глубины
'glDepthFunc(GL_LESS)
'glEnable(GL_ALPHA_TEST) ' Тест Альфа
'glAlphaFunc(GL_GREATER, 0.1)
Do
glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT 'очищаем экран
' !! здесь различные команды !!
start = Timer
'glPointSize (rnd*10) 'размер точки
glBegin (GL_POINTS)
For i = 1 To 1000000
glColor3f (Rnd,Rnd,Rnd) ' RGB цвет в формате 0 до 1
glVertex2f (Rnd*scrnX, Rnd*scrnY) ' рисуем точку
Next i
glEnd
WindowTitle "Driver: "+driver+" Time: "+Str(Timer-start)
' !! здесь различные команды !!
glFlush ' Обработка команд
Flip
Loop Until MultiKey(&h01) ' Выход из цикла при нажатии Esc
SDL - либа слабая. Я не видел ни скроллеров в ней, ни сплиттеров. Её используют многие для вывода картинки рендера, но, у меня виды на будущее.Ланухумыч, ты сильно только не обижайся :), но я тебе ещё раз напомню про твою задумку с GUI. Пока даже непонятна суть рендерера, который ты планируешь. На сей раз с помощью видео: https://www.youtube.com/watch?v=OvAHirMoUWk
Я выбрал либу с большИм числом виджетов. В прок! :) Чтоб не переписывать потом, и не изобретать велосипед в поисках чего-то типа graphics.h. К фоксу я нашёл либу, использующую векторную графику Cairo, с помощью которой можно крутилки красивые нарисовать, как это делает GTK.
Samovar, ты мне объясни, почему для теста ты выбрал перерисовку пикселов?sungreen навёл на мысль, но согласен можно было протестировать математику на проце без сопроцессора, на проце с использованием сопроцессора... это просто для наглядности, хотя в итоге, ради расчёта цвета конкретного пикселя весь процесс рендеринга и затевается... но писать его, естественно, надо в какой-то иной кусок памяти, а затем иногда выводить этот кусок памяти или его фрагмент в видеобуфер для просмотра, чего там делается - быстрее всего это будет, вероятно, с помощью OpenGL.
Почему ты не взял просто какое-нибудь математическое действие, выполняемое миллион раз?
Дело в том, что я своей бестолковкой сразу связал перерисовку пикселов с процессом, который рано или поздно востребуется в рендере.
Посему поэтому сначала необходимо безо всяких планов на будущее тупо разобраться с алгоритмами рэйтрэйсинга и понять: как достигается скорость и как достигается экономичность на практике.Но вообще, хотелось бы, что бы ты уж что-то начал. Так даже будет проще врубиться.
#!BPY
"""
Name: 'Objective-C Header (.h)'
Blender: 244
Group: 'Export'
Tooltip: 'Exports .h file for use with OpenGL ES - Modified by Jody McAdams (jmcadams@digipen.edu). Original from iphonedevelopment.blogspot.com'
"""
import Blender
from Blender import *
import bpy
import bpy
import os
def write_obj(filepath):
out = file(filepath, 'w')
sce = bpy.data.scenes.active
ob = sce.objects.active
mesh = Mesh.New()
mesh.getFromObject(ob.name)
editmode = Window.EditMode()
if editmode: Window.EditMode(0)
has_quads = False
for f in mesh.faces:
if len(f) == 4:
has_quads = True
break
if has_quads:
oldmode = Mesh.Mode()
Mesh.Mode(Mesh.SelectModes['FACE'])
mesh.sel = True
tempob = sce.objects.new(mesh)
mesh.quadToTriangle(0) # more=0 shortest length
oldmode = Mesh.Mode(oldmode)
sce.objects.unlink(tempob)
Mesh.Mode(oldmode)
objectname = ob.getData(True)
basename = objectname.capitalize()
out.write('#import "GraphicsTypes.h"\n\n\n')
if (mesh.faceUV):
out.write('static const TexturedVertexData3D %sVertexData[] = {\n' % basename)
for face in mesh.faces:
for (vert, uvert) in zip(face.verts, face.uv):
out.write('\t{/*v:*/{%f, %f, %f}, ' % (vert.co.x, vert.co.z, -vert.co.y) )
out.write('/*n:*/{%f, %f, %f}, ' % (vert.no.x, vert.no.z, -vert.no.y))
out.write('/*t:*/{%f, %f}' % ( uvert.x, 1.0-uvert.y ) )
out.write('},\n')
out.write('};\n\n')
elif (mesh.vertexColors):
out.write('static const ColoredVertexData3D %sVertexData[] = {\n' % basename)
for face in mesh.faces:
for (vert, color) in zip(face.verts, face.col):
out.write('\t{/*v:*/{%f, %f, %f}, ' % (vert.co.x, vert.co.z, -vert.co.y) )
out.write('/*n:*/{%f, %f, %f}, ' % (vert.no.x, vert.no.z, -vert.no.y))
out.write('/*c:*/{%f, %f, %f, %f}' % ( color.r / 255.0, color.g / 255.0, color.b / 255.0, color.a / 255.0) )
out.write('},\n')
out.write('};\n\n')
else:
out.write
out.write('static const VertexData3D %sVertexData[] = {\n' % basename)
for face in mesh.faces:
for vert in face.verts:
out.write('\t{/*v:*/{%f, %f, %f}, ' % (vert.co.x, vert.co.z, -vert.co.y) )
out.write('/*n:*/{%f, %f, %f} ' % (vert.no.x, vert.no.z, -vert.no.y))
out.write('},\n')
out.write('};\n\n')
if editmode: Window.EditMode(1)
out.write('#define k%sNumberOfVertices\t%i\n' % (basename, len(mesh.faces) * 3) )
out.write('// Drawing Code:\n')
out.write('// glEnableClientState(GL_VERTEX_ARRAY);\n')
if (mesh.faceUV):
out.write('// glEnableClientState(GL_TEXTURE_COORD_ARRAY);\n')
elif (mesh.vertexColors):
out.write('// glEnableClientState(GL_COLOR_ARRAY);\n')
out.write('// glEnable(GL_COLOR_MATERIAL)\n')
out.write('// glEnableClientState(GL_NORMAL_ARRAY);\n')
out.write('// glVertexPointer(3, GL_FLOAT, sizeof(')
if (mesh.faceUV):
out.write('TexturedVertexData3D')
elif (mesh.vertexColors):
out.write('ColoredVertexData3D')
else:
out.write('VertexData3D')
out.write('), &%sVertexData[0].vertex);\n' % basename)
out.write('// glNormalPointer(GL_FLOAT, sizeof(')
if (mesh.faceUV):
out.write('TexturedVertexData3D')
elif (mesh.vertexColors):
out.write('ColoredVertexData3D')
else:
out.write('VertexData3D')
out.write('), &%sVertexData[0].normal);\n' % basename)
if (mesh.faceUV):
out.write('// glTexCoordPointer(2, GL_FLOAT, sizeof(TexturedVertexData3D), &%sVertexData[0].texCoord);\n' % basename)
elif (mesh.vertexColors):
out.write('// glColorPointer(4, GL_FLOAT, sizeof(ColoredVertexData3D), &%sVertexData[0].color);\n' % basename)
out.write('// glDrawArrays(GL_TRIANGLES, 0, k%sNumberOfVertices);\n' % basename)
out.write('// glDisableClientState(GL_VERTEX_ARRAY);\n')
if (mesh.faceUV):
out.write('// glDisableClientState(GL_TEXTURE_COORD_ARRAY);\n')
elif (mesh.vertexColors):
out.write('// glDisableClientState(GL_NORMAL_ARRAY);\n')
out.write('// glDisable(GL_COLOR_MATERIAL);\n')
out.write('// glDisableClientState(GL_NORMAL_ARRAY);\n\n\n')
out.close()
filename = os.path.splitext(Blender.Get('filename'))[0]
Blender.Window.FileSelector(write_obj, "Export", '%s.h' % filename)
/////////////////////////////////////////////////////////////////////////
//
// 00.h - Renderfunctions
//
// This file was created by the OpenGL-Export-Script for Blender.
//
// Export-Time: 03.08.2016, 02:21:13
//
// Script written by Michael Gantenbrinker.
//
/////////////////////////////////////////////////////////////////////////
#ifndef __00_H__
#define __00_H__
/////////////////////////////////////////////////////////////////////////
// DEFINES
#define NUM_MESHES 1
#define NUM_LIGHTS 0
/////////////////////////////////////////////////////////////////////////
// CONSTANTS
// Vertex-Array for each Mesh
const float fVertices_1[8][3] = { {1.000000f, 1.000000f, -1.000000f}, {1.000000f, -1.000000f, -1.000000f}, {-1.000000f, -1.000000f, -1.000000f}, {-1.000000f, 1.000000f, -1.000000f},
{1.000000f, 0.999999f, 1.000000f}, {0.999999f, -1.000001f, 1.000000f}, {-1.000000f, -1.000000f, 1.000000f}, {-1.000000f, 1.000000f, 1.000000f}
};
// Normal-Array for each Mesh
const float fNormals_1[8][3] = { {0.577349f, 0.577349f, -0.577349f}, {0.577349f, -0.577349f, -0.577349f}, {-0.577349f, -0.577349f, -0.577349f}, {-0.577349f, 0.577349f, -0.577349f},
{0.577349f, 0.577349f, 0.577349f}, {0.577349f, -0.577349f, 0.577349f}, {-0.577349f, -0.577349f, 0.577349f}, {-0.577349f, 0.577349f, 0.577349f}
};
// Triangle-Indices for each Mesh
// Quad-Indices for each Mesh
const unsigned long ulQuadIndices_1[6][4] = { {0, 1, 2, 3}, {4, 7, 6, 5}, {0, 4, 5, 1}, {1, 5, 6, 2}, {2, 6, 7, 3}, {4, 0, 3, 7} };
// Array with Vertex-Array-Pointers
const float* pVertexPointers[] = {&fVertices_1[0][0]};
// Array with Normal-Array-Pointers
const float* pNormalPointers[] = {&fNormals_1[0][0]};
// Array with TriangleIndex-Array-Pointers
const unsigned long* pTriangleIndexPointers[] = {0};
// Array with QuadIndex-Array-Pointers
const unsigned long* pQuadIndexPointers[] = {&ulQuadIndices_1[0][0]};
// Array with Vertex-Array-Lengths
const unsigned long ulVertexLengths[] = {8};
// Array with TriangleIndex-Array-Lengths
const unsigned long ulTriangleIndexLengths[] = {0};
// Array with QuadIndex-Array-Lengths
const unsigned long ulQuadIndexLengths[] = {6};
void Init()
{
}
void Render(int iWidth = 1024, int iHeight = 768)
{
// Setup Projektion-Matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double dAspectRatio = (double)iWidth / (double)iHeight;
gluPerspective(45.0f, dAspectRatio, 1.0f, 100.0f);
glViewport(0, 0, iWidth, iHeight);
gluLookAt(5.0f, 5.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
// Setup Lights
float lPos[] = {5.0f, 5.0f, 5.0f, 1.0f};
float lDir[] = {-0.707f, -0.707f, -0.707f};
glLightfv(GL_LIGHT0, GL_AMBIENT, StdColor_White);
glLightfv(GL_LIGHT0, GL_DIFFUSE, StdColor_BrightGrey);
glLightfv(GL_LIGHT0, GL_SPECULAR, StdColor_White);
glLightfv(GL_LIGHT0, GL_POSITION, lPos);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lDir);
glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 180.f);
glLightf (GL_LIGHT0, GL_SPOT_EXPONENT, 1.0f);
glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f);
glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.6f);
glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.06f);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// Setup Scene-Content
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float* fVertices = 0;
float* fNormals = 0;
unsigned long* ulTriangleIndices = 0;
unsigned long* ulQuadIndices = 0;
unsigned long* ulPtr = 0;
for(int i = 0; i < NUM_MESHES; i++)
{
fVertices = (float*)pVertexPointers[i];
fNormals = (float*)pNormalPointers[i];
ulTriangleIndices = (unsigned long*)pTriangleIndexPointers[i];
ulQuadIndices = (unsigned long*)pQuadIndexPointers[i];
if(ulTriangleIndices)
{
glBegin(GL_TRIANGLES);
unsigned long t = 0;
while(t < ulTriangleIndexLengths[i]*3)
{
ulPtr = &ulTriangleIndices[t];
glNormal3fv(&fNormals[ulPtr[0]*3]);
glVertex3fv(&fVertices[ulPtr[0]*3]);
glNormal3fv(&fNormals[ulPtr[1]*3]);
glVertex3fv(&fVertices[ulPtr[1]*3]);
glNormal3fv(&fNormals[ulPtr[2]*3]);
glVertex3fv(&fVertices[ulPtr[2]*3]);
t += 3;
}
glEnd();
}
if(ulQuadIndices)
{
glBegin(GL_QUADS);
unsigned long q = 0;
while(q < ulQuadIndexLengths[i]*4)
{
ulPtr = &ulQuadIndices[q];
glNormal3fv(&fNormals[ulPtr[0]*3]);
glVertex3fv(&fVertices[ulPtr[0]*3]);
glNormal3fv(&fNormals[ulPtr[1]*3]);
glVertex3fv(&fVertices[ulPtr[1]*3]);
glNormal3fv(&fNormals[ulPtr[2]*3]);
glVertex3fv(&fVertices[ulPtr[2]*3]);
glNormal3fv(&fNormals[ulPtr[3]*3]);
glVertex3fv(&fVertices[ulPtr[3]*3]);
q += 4;
}
glEnd();
}
}
}
#endif /* __00_H__ */
1. Всегда можно найти место на просторах сети, где подскажут конкретно по существу проблемы, потому что достаточное количество литературы и примеров.1. Согласен, что инфы много больше... но больше и путаницы, как у меня вышло графической библиотекой от Bolrand.
2. Указатели и ссылки - это реально круто. Манипуляция данными происходит по адресам этих данных в оперативке. В этом зарыта скорость выполнения.
3. ООП разгружает мозг, раскладывая всё по полочкам. Я поверил на слово Страуструпу, когда прочитал в книге его рекомендации почему не стоит использовать С там, где это совсем не требуется, почему не стоит на С++ писать как на С, используя структуры, отказываясь от классов и тому подобное...
int a;
int *p;
p = &a;
*p = 123;
dim a as integer
dim p as integer ptr
p = @a
*p = 123
Ланухумыч, у тебя есть желание продолжать заниматься самообразованием? Или проще накопить денег на тот же Win+V-Ray + железо (или иной рендерер под винду) и рендерить относительно шустро, без всех этих заморочек? :)Всё идёт по расписанию. :)
Морис просит помочь интегрировать мой код в официальную версию аддона "render_povray", там Python.Это очень хорошая новость. Мои поздравления!
У меня в голове сейчас такая каша, но я ещё успеваю думать про эту тему, ибо как ни странно, но желание у меня пока ещё осталось. :)Понял... :)
Для меня это не очень хорошая новость. Дело в том, что я написал импорт повреевской сцены в блендер с целью, о которой меня просили на офсайте поврея. Там люди боятся блендера, но хотят использовать его возможности для просчёта физики. Мой коннектор теперь может загружать повреевские объекты, чтобы в блендере накинуть на них ткань и прочее. Морису эта идея понравилась, он перенёс импорт в официальную версию, но ему теперь подавай импорт с материалами, блин. Зачем ему это, я не знаю, но обижать его не хочется, тем более, что моё имя фигурирует в списке разработчиков официальной версии. Нужно держать марку фирмы :)ЦитироватьМорис просит помочь интегрировать мой код в официальную версию аддона "render_povray", там Python.Это очень хорошая новость. Мои поздравления!
for (int i = 0; i< 242000000; i++)
temp+=temp;
#include "fox-1.6/fx.h"
#include <time.h>
#include <iostream>
using namespace std;
class ImageWindow : public FXMainWindow{
FXDECLARE(ImageWindow)
protected:
ImageWindow(){}
FXStatusBar *statusbar;
private:
FXCanvas *canvas;
FXColor bgColor = FXRGB(0, 0, 0);
public:
enum {
ID_CANVAS = FXMainWindow::ID_LAST,
};
long onPaint(FXObject *, FXSelector, void *);
long onMouseDown(FXObject *, FXSelector, void *);
public:
ImageWindow(FXApp* a);
virtual void create();
virtual ~ImageWindow();
};
FXDEFMAP(ImageWindow) ImageWindowMap[] = {
FXMAPFUNC(SEL_PAINT, ImageWindow::ID_CANVAS, ImageWindow::onPaint),
FXMAPFUNC(SEL_LEFTBUTTONPRESS, ImageWindow::ID_CANVAS, ImageWindow::onMouseDown)
};
FXIMPLEMENT(ImageWindow, FXMainWindow, ImageWindowMap, ARRAYNUMBER(ImageWindowMap))
ImageWindow::ImageWindow(FXApp* a):FXMainWindow(a,"FOX Render",NULL,NULL,DECOR_ALL,0,0,850,600,0,0){
FXHorizontalFrame *container=new FXHorizontalFrame(this,LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_RAISED);
container->setBackColor(FXRGB(226,223,222));
FXHorizontalFrame *chartwell=new FXHorizontalFrame(container,FRAME_SUNKEN|LAYOUT_FILL_X|
LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT,
0,0,0,0,10,10,10,10);
canvas = new FXCanvas(chartwell, this, ID_CANVAS, LAYOUT_FILL_X|LAYOUT_FILL_Y);
//statusbar=new FXStatusBar(this,LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|STATUSBAR_WITH_DRAGCORNER);
//statusbar->getStatusLine()->setNormalText("");
}
ImageWindow::~ImageWindow() {}
void ImageWindow::create() {
FXMainWindow::create();
show(PLACEMENT_SCREEN);
}
long ImageWindow::onPaint(FXObject *, FXSelector,void *ptr) {
FXEvent *ev = (FXEvent *) ptr;
FXDCWindow dc(canvas, ev);
dc.setForeground(bgColor);
dc.fillRectangle(0,0,canvas->getWidth(),canvas->getHeight());
return 1;
}
timespec diff(timespec start, timespec end);
long ImageWindow::onMouseDown(FXObject *, FXSelector, void *ptr){
timespec time1, time2;
int temp = 0;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
for (int i = 0; i< 242000000; i++)
temp+=1;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
long b = 0;
FXString name, ftemp;
name = FXStringVal(diff(time1,time2).tv_nsec);
ftemp = FXStringVal(temp);
this->setTitle("Render Time: "+name+" nanosecond "+ftemp);
//statusbar->getStatusLine()->setNormalText("Render Time: "+name+" nanosecond");
//statusbar->repaint();
return b;
}
timespec diff(timespec start, timespec end)
{
timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}
int main(int argc,char *argv[]){
FXApp application("FoxTest","FoxTest");
application.init(argc,argv);
new ImageWindow(&application);
application.create();
return application.run();
}
Вот интересного научного отечественного по теме почитать:Спасибо, почитаю. Тут динозавры твои есть. Но, мы до GPU ещё не добрались. :)
http://www.graphicon.ru/html/2013/papers/207-210.pdf
http://istina.msu.ru/media/dissertations/dissertation/8be/5fa/9651265/08_frolov_diss_compressed.pdf
Тут динозавры твои есть.Это одна из известных сцены для теста рендерера, как и Sponza Atrium. Качал отсюда: http://www.3drender.com/challenges/ (http://blender-3d.ru/forum/go.php?url=aHR0cDovL3d3dy4zZHJlbmRlci5jb20vY2hhbGxlbmdlcy8=)
Но, мы до GPU ещё не добрались. :)Пусть инфа поваляется тут :) Случайно наткнулся...
Я пока не освоил make, чтоб собрать предложенную тобой стороннюю библиотеку для GUI.
Я пока не освоил make, чтоб собрать предложенную тобой стороннюю библиотеку для GUI. http://free-basic.ru/aboutmakefile.html (http://blender-3d.ru/forum/go.php?url=aHR0cDovL2ZyZWUtYmFzaWMucnUvYWJvdXRtYWtlZmlsZS5odG1s)Зачем тебе это надо? Устанавливаешь MinGW и по иструкции: configure, make, make install.
Полезная вещь... ковыряю потихоньку. http://rus-linux.net/nlib.php?name=/MyLDP/algol/gnu_make/gnu_make_3-79_russian_manual.html (http://blender-3d.ru/forum/go.php?url=aHR0cDovL3J1cy1saW51eC5uZXQvbmxpYi5waHA/bmFtZT0vTXlMRFAvYWxnb2wvZ251X21ha2UvZ251X21ha2VfMy03OV9ydXNzaWFuX21hbnVhbC5odG1s)
может, что и не так делаю... потихоньку разберусь ...
В принципе, если возможно прикрутить ту хрень, которую я использовал для интернала и добавить семплов+AA, то теоретически можно получить подобие Суслика на GLSL.Какую хрень и куда прикрутить? Что-то я плохо ориентируюсь в твоих данных.
Прикольно сделано, но мне пока не понятно ... Отсутствуют знания GLSLДа, прикольно. Только непонятно, как сохранять видео...
Да это просто прототип в BGE :) Но можно попробовать и тут: добавить актуатор Game->Sсreenshot и менять имя файла скриптом на Python. Но я в Python не шарю...Прикольно сделано, но мне пока не понятно ... Отсутствуют знания GLSLДа, прикольно. Только непонятно, как сохранять видео...
Да это просто прототип в BGE :) Но можно попробовать и тут: добавить актуатор Game->Sсreenshot и менять имя файла скриптом на Python. Но я в Python не шарю...Я перевёл некоторые реплики на бленартисте. Тут даже объекты созданы шейдерами. Блендер здесь просто в роли окна openGL. Скрин, может, и можно сделать, но не для чего. Прежде надо и GLSL изучить, и скриптописание в BGE. Но, опять же таки скриншотить проблемно в FullHD. Или это можно развернуть в полный экран. Я что-то не смог. Игра запускается только из меню, а при запущенной игре кнопки не работают.
Изменять вектор отражения случайным образом по полусфере для каждого семпла луча. Затем из них вычислить среднее значение - это и будет цвет пикселя вторичного освещения. Но это,естественно, будет уже дольше вычисляться, чем зеркальные отражения :)В принципе, если возможно прикрутить ту хрень, которую я использовал для интернала и добавить семплов+AA, то теоретически можно получить подобие Суслика на GLSL.Какую хрень и куда прикрутить? Что-то я плохо ориентируюсь в твоих данных.
Да это просто прототип в BGE :) Но можно попробовать и тут: добавить актуатор Game->Sсreenshot и менять имя файла скриптом на Python. Но я в Python не шарю...Я перевёл некоторые реплики на бленартисте. Тут даже объекты созданы шейдерами. Блендер здесь просто в роли окна openGL. Скрин, может, и можно сделать, но не для чего. Прежде надо и GLSL изучить, и скриптописание в BGE. Но, опять же таки скриншотить проблемно в FullHD. Или это можно развернуть в полный экран. Я что-то не смог. Игра запускается только из меню, а при запущенной игре кнопки не работают.
А зачем нажимать кнопку, чтобы получить скриншот?Кнопку нужно жать, чтоб развернуть в полный экран.
Справа в параметрах рендеринга надо выставить разрешение Standalone Player (или включить галку Desktop), включить галку Fullscreen и нажать кнопку StartЦитироватьА зачем нажимать кнопку, чтобы получить скриншот?Кнопку нужно жать, чтоб развернуть в полный экран.
Надо вникнуть в вопрос... То, что объекты созданы шейдерами, пока не сильно отпугивает, если пробовать сделать подобное на Си или Freebasic...GLSL и есть урезанный С. В принципе, можно попробовать. Нужно подумать. Я где-то видел уроки на русском по опенгл. Там есть, как загружать объекты в сцену и как вставлять коды шейдеров в код OpenGL. Реалтайм, конечно, не получится...
Ага, вот ссылка:Не, малёха не то, но тоже нужно...
https://triplepointfive.github.io/ogltutor/ (http://blender-3d.ru/forum/go.php?url=aHR0cHM6Ly90cmlwbGVwb2ludGZpdmUuZ2l0aHViLmlvL29nbHR1dG9yLw==)
ну и вот:
http://pmg.org.ru/nehe/ (http://blender-3d.ru/forum/go.php?url=aHR0cDovL3BtZy5vcmcucnUvbmVoZS8=)
Кто-то уже что-то пытался...https://code.google.com/archive/p/glsl-raytracer/downloadsЭто очень даже хорошо. Я собрал этот рэйтрэйсер. У нас, можно сказать, уже почти всё есть для изучения языка GLSL.
Тем не менее, мне удалось записать последовательность .png с помощью BGE и без Python.Очень хочется посмотреть, как ты без Python будешь помещать в сцену объекты и присваивать им шейдеры. Я, честно сказать, ничего не знаю про актуаторы, ибо никогда не интересовался движком BGE, но, когда увижу как у тебя вместо кубика в этой сцене будет ходить зеркальный человек в реалтайме, то актуаторы станут для меня смыслом жизни... :)
Чтоб отбить интерес к GLSLДело в том, что эту игрушку всё же можно реализовать, написав простой аддон, как мне кажется. Я уже прикручивал PySide к Блендеру, но тогда это было для других целей, я писал редактор карт цвета для Поврея.
Но конечно, возник вопрос про рендер полигональных объектовКак видишь, в сцене полигональные объекты - шестереньки. Другой вопрос: я не вижу нигде в ссылках стекла с преломлением.
Ещё один OpenGL рейтрейсер в копилкуВторая ссылка интересная. Там используется в винде окно GLFW3. Я этим уже давно интересуюсь. GLFW3 - это продвинутая альтернатива FreeGlut. FreeGlut - морально устарел, давно заброшен. GLFW3 поддерживает версии OpenGL - 4.x
https://www.youtube.com/watch?v=ycSOnGzbNO4
https://github.com/StanEpp/OpenGL_Raytracing
Oc-treeЭто тут:
Забудьте про это, октодерево неэффективно и сложно. Вот тут приводится сравнение множества статей по тваверсу октодеревьев http://tog.acm.org/resources/RTNews/html/rtnv12n2.html#art4.
:) Простой рейтрейсер на Python https://gist.github.com/sevko/c3ed2430e96b89dd3177Да, насмотрелся я уже на все эти рейтрейсеры. Отчасти, начал понимать тех, кто начал и не дописал. Какое же всё глючное! Я не про коды рейтрейсеров, а про тулкиты и всякие либы, которые, якобы, можно использовать для серьёзных проектов. SDL - виснет. Qt ошибки сегментирования выдаёт на ровном месте: сменил положение камеры, вместо пяти, в примере, поставил 10 - ошибка сегментирования. Как камеру анимировать? С Qt проблемы и раньше встречал, но, думал, случайно, нет - это закон. Наверное, поэтому и нет ни одного, хоть самого простого, но без глюков, трёхмерного редактора на Qt. Собрал OpenGL-raytracer на GLFW3 - чёрное окно. Я эти шейдеры два дня прикручивал, выискивая пути с обратными слешами, а оно, раз, и глюк. Qt-creator - г... создал проект, сборка не находит инклудов, в CodeBlock мне не удалось собрать ни одного проекта, написанных для CodeBlock. Разумеется, это всё каким-то замысловатым образом решается грамотными программистами, но нах это предлагать новичкам, если оно не готово работать из коробки - х.з.
:) Рейтрейсер на JavaScript https://habrahabr.ru/post/112944/
Samovar, не давай мне больше ссылок, не сбивай меня с курса.Как угодно, но замечу, что это была твоя идея - написать рейтрейсер...
Ты не обижайся, но моя идея не подразумевала написание рейтрейсера с нуля. Я сразу об этом объяснил sungreen, когда он спросил:"А, с нуля, слабо?" Я сразу говорил, что хочу использовать уже готовое, написанное на С\С++. И присобачить туда уже готовое, работающее, но неэффективно, ибо, написано на Java. Именно, полноценное, а ни тестовые варианты, сбивающие с толку.ЦитироватьSamovar, не давай мне больше ссылок, не сбивай меня с курса.Как угодно, но замечу, что это была твоя идея - написать рейтрейсер...
Тогда создам другую тему по рейтрейсеру на FB...
Ланухумыч, да делай что хочешь, только меня не зови уже быть тебе "советчиком", потому, что я в этой теме не шарю, как и писал тебе до этого... Луше СамСуСаму напиши и пригласи поучаствовать... Он активно интересовался этой твоей темой.Я СамСуСаму писал, он молчит. Я уже привык к тому, что любые мои действия не поддерживаются. Я ж нелюдь. :) И хочу того, чего другие не хотят...