nsf gamedevЖурнал

Журнал

11 июня 2010

http://www.realworldtech.com/forums/index.cfm?action=detail&i… &roomid=2

Ctrl+F, Linus Torvalds, наслаждайтесь.

Заранее добавлю, что в теме замечен и Walter Bright, автор языка D, являющегося попыткой сделать С++ "правильно".

А теперь мои размышления на эту тему:

Помню как ясный день и сейчас свой опыт ковыряния опен сорс С++ проектов и схожих Си проектов одновременно. Была у меня такая необходимость. И как вы догадываетесь большинство опен сорс программ написаны ленивой ручкой в свободное от повседневных тягот время, а поэтому не содержат ни документации (хотя она чаще есть, чем ее нет, если проект хоть чуточку используется людьми), ни комментариев (с этим вообще все плохо). Но задача есть, разобраться с кодом нужно, поэтому вооружаемся grep'ом на перевес и начинаем активно смотреть, что же в коде происходит. Вы когда-нибудь пробовали такое делать с C++ кодом? Только честно. Ой, а тут метод, а какому классу он принадлежит? А что это за аргументы у функции, не вызывают ли они перегруженный вариант случайно? Ой, а этот метод состоит из одной строчки и вызывает такой метод у другого класса, о боже мой, куда я попал. Ну и так далее. Не сложно догадаться, что понять происходящее внутри Си программы значительно проще. А теперь вспомните великую мудрость, что программа чаще читается, чем пишется и задумайтесь, для чего все эти упоминаемые в треде С++ фичи, которые мы все так любим? Ведь они для того, чтобы проще писать код, не так ли? А куда дели мудрость?

Однако, Линус взамен С++ предлагает взять нам мифический "real language with real features", вот только его не существует. Такой вот де-факто парадокс, если хочется всех этих самых фич, то С++ лучшее, что есть на сегодня по многим параметрам. А среди немаловажных свойств такого несуществующего языка должны быть: хорошие компиляторы, сопутствующие библиотеки, человеческие ресурсы aka программисты и прочее прочее, далеко не прямо связанное с самим языком. Вспомните такой опен сорс проект игровой направленности как OpenMW (открытая реализация движка TES III: Morrowing), ведь они решили делать переход с D на C++ именно по причинам приведенным выше. Линус одобряет Go от гугла и напоминает, что он вроде хороший, но не зря же его назвали экспериментальным и он чертовски прав! Кто ж его не одобрит? Молодцы товарищи Кен Томпсон и Роб Пайк (обратите внимание как хорошо русское слово "молодец" описывает ситуацию имея в своем составе корень "молод"). Рано еще, рано, но ведь когда-нибудь это должно свершиться! "Дайте нам новый язык, чтобы был как Си, но для современных нужд!" - скандируют массы. Где же ты, о великий создатель языка будущего?!

А нету... А жаль...

Ссылка | Комментарии [2]

5 июня 2010

Мне правда жаль будущее поколение молодых мозго***в. Решил я как-то значицо написать супер крутой коллбэк в стиле С++0x, да не сдавался до конца..

#include <stdio.h>
#include <functional>

//-------------------------------------------------------------------------
// Our main callback class, can be binded to function or member function
// of a particular class easily(?)
//-------------------------------------------------------------------------
template <typename Ret, typename ...Args>
struct funcptr_def {
  typedef Ret (*type)(Args...);
};

template <typename Signature>
struct callback;

template <typename Ret, typename ...Args>
struct callback<Ret(Args...)> {
  typedef typename funcptr_def<Ret, Args..., void*>::type function_ptr_type;

  function_ptr_type fptr;
  void *data;

  void bind(function_ptr_type fptr, void *data = 0)
  {
    this->fptr = fptr;
    this->data = data;
  }

  Ret call(Args ...args)
  {
    return (*fptr)(std::forward<Args>(args)..., data);
  }
};

//-------------------------------------------------------------------------
// Helper binder
//-------------------------------------------------------------------------

template <int ...> struct int_tuple {};

template <int I, typename IntTuple, typename ...Types>
struct make_indices_impl;

template <int I, int ...Indices, typename T, typename ...Types>
struct make_indices_impl<I, int_tuple<Indices...>, T, Types...>
{
  typedef typename make_indices_impl<I+1, int_tuple<Indices..., I>, Types...>::type type;
};

template <int I, int ...Indices>
struct make_indices_impl<I, int_tuple<Indices...>> {
  typedef int_tuple<Indices...> type;
};

template <typename ...Types>
struct make_indices : make_indices_impl<0, int_tuple<>, Types...> {};

//-------------------------------------------------------------------------

template <typename T>
void *get_void_ptr(T &&arg)
{
  return arg;
}

template <typename T, typename ...Args>
void *get_void_ptr(T &&arg, Args &&...args)
{
  return get_void_ptr(std::forward<Args>(args)...);
}

//-------------------------------------------------------------------------

template <typename Ret>
struct callback_helper_impl {
  template <typename T, typename MemberFunctionPtr, typename ...Args, int ...Indices>
  static Ret callback_run(T *object, MemberFunctionPtr m, const std::tuple<Args&...>& args, int_tuple<Indices...>)
  {
    return (object->*m)(std::get<Indices>(args)...);
  }
};

template <typename Signature, typename MemberSignature, MemberSignature FunctionPtr>
struct callback_helper;

template <typename Ret, typename ...Args, typename T, typename ...MemArgs, Ret(T::*MemberFunction)(MemArgs...)>
struct callback_helper<Ret(Args...), decltype(MemberFunction), MemberFunction> {
  typedef typename make_indices<MemArgs...>::type indices;

  static Ret function(Args ...args)
  {
    T *object = (T*)get_void_ptr(args...);
    return callback_helper_impl<Ret>::callback_run(object, MemberFunction, std::tie(args...), indices());
  }
};

// for convenience (orly?!!?111 omgwtfbbq)
#define WRAP_METHOD(f) decltype(f), f

//-------------------------------------------------------------------------
// Example class
//-------------------------------------------------------------------------
struct dog_t {
  void bark(int a, int b)
  {
    printf("bark! %d %d\n", a, b);
  }
};

//-------------------------------------------------------------------------
// Example function
//-------------------------------------------------------------------------
void say_hello(int a, int b, void *notused)
{
  printf("Hello! %d %d\n", a, b);
}


int main(int argc, char **argv)
{
  dog_t dog;
  callback<void (int, int)> cb;

  int i = 1;

  // function
  cb.bind(say_hello);
  cb.call(i, 2);

  // member function
  cb.bind(callback_helper<void (int, int, void*), WRAP_METHOD(&dog_t::bark)>::function, &dog);
  cb.call(i, 2);

  return 0;
}

27 мая 2010

Зачем это нужно? История умалчивает. Медитируйте. :)

#include <cstdio>
#include <cstdint>
#include <new>
#include <utility>

// class represents space for a type with manual construction and destruction
// (also can PODify any class, e.g. convert full featured Class to POD type)
template <typename T>
struct storage {
  template <typename ...Args>
  void construct(Args &&...args)  { new (buf) T(std::forward<Args>(args)...); }

  void destruct() { get()->~T(); }

  T *operator->() { return get(); }
  T &operator*() { return *get(); }

  T *get() { return reinterpret_cast<T*>(buf); }

  uint8_t buf[sizeof(T)];
};

struct WeirdClassWithLotsOfData {
  // have no default constructor
  WeirdClassWithLotsOfData(int a, int b, int c): a(a), b(b), c(c)
  {
    for (size_t i = 0; i < 100; ++i)
      d[i] = i;
    printf("Weird class constructed: %d %d %d\n", a, b, c);
  }

  ~WeirdClassWithLotsOfData()
  {
    printf("Weird class destroyed: %d %d %d\n", a, b, c);
  }

  void say_hello()
  {
    printf("Hello: %d %d %d\n", a, b, c);
  }

  int a, b, c;
  int d[100];
};

// allocate space for all data in one malloc
struct PackOfWeirdness {
  storage<WeirdClassWithLotsOfData> objects[5];

  PackOfWeirdness()
  {
    // do weird initialization
    for (int i = 4; i >= 0; --i)
      objects[i].construct(i+1, i+2, i+3);
  }

  ~PackOfWeirdness()
  {
    for (size_t i = 0; i < 5; ++i)
      objects[i].destruct();
  }

  void reinit()
  {
    for (size_t i = 0; i < 5; ++i) {
      objects[i].destruct();
      objects[i].construct(i+1, i*i, i*i*i);
    }
  }
};

int main(int argc, char **argv)
{
  printf("Before pack of weirdness\n");
  {
    auto pack = new PackOfWeirdness;
    for (size_t i = 0; i < 5; ++i)
      pack->objects[i]->say_hello();
    pack->reinit();
    delete pack;
  }
  printf("After pack of weirdness\n");
  return 0;
}

Ссылка

6 ноя 2007

Только что состоялся первый билд модифицированного open source рендера yafray (http://yafray.org). А также первый успешный тест!
Теперь yafray может рендерить лайтмапы!!!
Я (скорей всего уже завтра) продолжу улучшать эту модифицированную версию. Если кому это интересно, пожалуйста отпишитесь в комментариях, я тогда буду более подробно освещать все действия. А также если кто-то желает помочь - отпишитесь в комментариях опять же или лучше найдите меня на #gamedev @ IRCNET.RU.

Yafray имеет очень удобный интерфейс как в виде библиотеки, так и консольный с своим форматом файла (xml). Поэтому я надеюсь сделать из него хороший опенсорс лайтмап рендер.
Насчет всяких фич типа radiosity не уверен, но буду работать понемногу.

Вот небольшой отчет с скринами..
BLENDER
1. Мини сцена отрендерена блендером
http://d2k5upload.parahelix.org/files/1194369232_lightmap_blender.jpg

2. Лайтмап полученный встроенными средствами в blender
http://d2k5upload.parahelix.org/files/1194369275_lightmap_blender_lm.jpg
http://img128.imageshack.us/img128/1601/lightmapblenderlmsf9.jpg (copy)

3. Отрендеренная блендером сцена с натянутым лайтмапом (который п. 2)
http://d2k5upload.parahelix.org/files/1194369255_lightmap_blender… ghtmapped.jpg
http://img128.imageshack.us/img128/4229/lightmapblenderlightmapkt8.jpg (copy)

4. Тоже что и п. 3, только отрендерено yafray'ем.
http://d2k5upload.parahelix.org/files/1194369265_lightmap_blender… ed_yafray.jpg

yafray
5. Мини сцена отрендерена yafray'ем.
http://d2k5upload.parahelix.org/files/1194369427_lightmap_yafray.jpg

6. Лайтмап сгенерированный модифицированным мной yafray'ем (пока криво, но это первый билд!)
http://d2k5upload.parahelix.org/files/1194369440_lightmap_yafray_lm.jpg
http://img134.imageshack.us/img134/8913/lightmapyafraylmzl2.jpg (copy)

7. Отрендеренная yafray'ем сцена с натянутым лайтмапом (который п. 6)
http://d2k5upload.parahelix.org/files/1194369432_lightmap_yafray_… ghtmapped.jpg
http://img87.imageshack.us/img87/3290/lightmapyafraylightmappsj8.jpg (copy)

8. Тоже что и п. 7, только отрендерено блендером
http://d2k5upload.parahelix.org/files/1194369436_lightmap_yafray_… d_blender.jpg

Жду ваших комментариев :)

Ссылка

2 ноя 2007

Решил создать своё персональное сообщество для того, чтобы делиться опытом с остальными любителями и профессионалами в геймдеве :) Я интересуюсь геймдевом уже давно и у меня накопился ряд мыслей, которые неплохо было бы изложить в виде статеек. Что в ближайшее время я постараюсь и сделать. Надеюсь вам будет интересно. %)

Первая статья будет о текстурировании ландшафта.
Далее планирую одну статейку о convolution kernel image processing/filtering.
И потом немного о blender'е в качестве универсального редактора для game контента.

Ссылка

Архив 

Следующие записи