ПрограммированиеФорумОбщее

Линус Торвальдс ненавидит С++. А мы с вами? (2 стр)

Страницы: 1 2 3 430 Следующая »
#15
18:06, 28 июня 2010

Beginner
С текстурами сложнее, давай, я с шейдерами пример приведу?

интерфейс ID3D11DeviceContext:

void PSSetShader(
  [in]  ID3D11PixelShader *pPixelShader,
  [in]  ID3D11ClassInstance *const *ppClassInstances,
  [in]  UINT NumClassInstances
);

.

Объект типа ID3D11DeviceContext - деталь реализации, следовательно, должен быть скрыт от пользователя интерфейсом IContext. Объект типа ID3D11PixelShader - деталь реализации, следовательно, должен быть скрыт от пользователя интерфейсом IPixelShader. Теперь попробуй дать юзеру возможность забиндить IPixelShader в IContext.

Придешь в итоге либо к двойной диспетчеризации, либо к QueryInterface, либо к дескрипторам и сишному стилю программирования.

#16
18:11, 28 июня 2010

crsib
>> Ну, по крайней мере они решаются гораздо красивей.
Ежику понятно, что IDevice служит фабрикой для IPixelShader / ITexture.

Судя по всему, ты предлагаешь в реализацию IPixelShader передавать указатель на реализацию девайса? Да, вопрос это решает, только как в этом случае "кончаются наши проблемы с глубокой связанностью", если связанность возрастает при этом в несколько раз? :)

#17
18:13, 28 июня 2010

Теже грабли только в профиль или я реально тупой?
Обертке над API (где-то я это уже писал) ты даешь команду сбиндить пиксельный шейдер -> BindShader( myIDPixelShader ); обертка его ранее создала,привязала настроила по умолчанию или по конфигам и еще что хош и вынесла этот айди за пределы,к клиенту
ну и биндить она разумеется умеет
и девайс знает
а интерфейс что у OpenGL что у DirectX одинаковый - BindTexture(int),BindShader(int) итак далее
вопрос что означают эти айди и кто хранит-не по теме)

#18
18:15, 28 июня 2010

Э, нифига не понял.
А что изменилось? И какое отношение DeviceContext имеет к Device (за исключением того, что контекст порождается девайсом)?
Или ты о ID3D11ClassInstance? Дык он имеет отношение только к особенностям HLSL 5.0. А не к интерфейсу PixelShader.

А, ты наверное о том, что появился лишний интерфейс? Причем у API. И какое отношение это имеет к двойной диспетчеризации? И чем в локальном случае QueryInterface отличается от new YaRealizaciaIPixelShader в методе девайса?

UPD: новые посты
>Судя по всему, ты предлагаешь в реализацию IPixelShader передавать указатель на реализацию девайса?
Боже храни королеву от этого.

#19
18:15, 28 июня 2010

Beginner
Если "рендеру нужно прибиндить текстуру по айди", то ты уже используешь сишный стиль программирования и дескрипторы (ты называешь их "айдишниками"). Т.е. текстура для тебя - не объект, она не открывает пользователю никаких методов. Все методы сосредоточены в девайсе, и ты передаешь им дескрипторы.

Это сертифицированный процедурный сишный WinAPI-style подход, что какбе подтверждает мысль Торвальдса.

#20
18:17, 28 июня 2010

winter
> она не открывает пользователю никаких методов.
Она может предоставлять методы, специфичные именно для текстуры. Bind специфичен для девайса

#21
18:21, 28 июня 2010

в директ жеж вроде **::SetTexture(блабла, IDirect3DBaseTexture *);... и никаких ID...
дык это не моя неопытность оказывается? риальне есть такая проблема, когда передаётся интерфейс в интерфейс... а там нужна реализация.. и необходимо (фу) приводить интерфейс к реализации?

#22
18:23, 28 июня 2010

crsib

class IDevice
{
    virtual ITexture* CreateTexture() = 0;
    virtual void      Bind         (const ITexture &tex) = 0;
};

class ITexture
{
    // no API details here!!
};

Теперь юзеру потребно забиндить текстуру на девайс! Он вызывает device->Bind(tex). И что мы имеем внутри реализации метода Bind()?

void DeviceDX::Bind(const ITexture &tex)
{
    // опа, что мне делать с этим абстрактным интерфейсом?
}

Т.е. юзер может передать девайсу только то, что получил сам - абстрактный интерфейс текстуры. А нужна конкретика, DX-specific детали. Вот тут и приходит на помощь double dispatching.

#23
18:25, 28 июня 2010

falc0n
>> риальне есть такая проблема, когда передаётся интерфейс в интерфейс... а там нужна реализация.. и необходимо (фу) приводить интерфейс к реализации?
Конечно, такая проблема есть, про это и речь. И наличие этой проблемы подтверждает обоснованность претензий Торвальдса... Просто еще не все присутствующие до конца поняли суть проблемы.

#24
18:28, 28 июня 2010

Ну я как с ней столкнулся, решил что просто прогать нихрена не умею, и плохую архитектуру составил))
ну в итоге оставил приведение интерфейса реализации ("числокостылей++")...

#25
18:31, 28 июня 2010

winter
Странный диспатчинг, бро. Чем не нравится такое?:

class Device;
class Texture
{
private:
  virtual void BindToOwner() = 0;
  friend class Device;
}
class Device
{
  ITexture *CreateTexture();
  void Bind(Texture *tex)
  {
    tex->BindToOwner();
  }
}

class DXTexture : public Texture
{
  DXTexture(DXDevice *owner)
  {
    this.owner = owner;
  }
  void BindToOwner()
  {
    owner->Bind(this);
  }
  DXDevice *owner;
}

class DXDevice : public Device
{
  void Bind(DXTexture *tex)
  {
    tex->NativeMethod();
  }
}

корявенько немного, но, надеюсь, суть понятна.

#26
18:32, 28 июня 2010

falc0n
Эта проблема возникает каждый раз, когда ты выставляешь "наружу" системы два сильно связанных компонента, обернутых интерфейсами.
По идее, сильно связанные компоненты вообще не должны иметь интерфейсов. Если бы мы работали исключительно с Device_DX и PixelShader_DX, проблем, сам понимаешь, не было бы. Но мы дали эти компоненты юзеру, "выставили" их "наружу", обернули интерфейсами, и тут же получили по башке за сильную связанность.

#27
18:36, 28 июня 2010

winter
по-моему, более принципиальная проблема, когда тебе нужно сблендить, например, две текстуры. сферический пример в вакууме, разумеется, но попробуй-ка реши:

class Texture
{
  virtual void Blend(Texture *other)
};

class DXTexture : public Texture
{
  void Blend(Texture *other)
  {
    other-> //wtf?!
  }
};

но и это, в принципе, можно решить:

class Texture
{
  virtual void Blend(Texture *other)  = 0;
  virtual void BindAsRenderTarget() = 0;
  virtual void Bind() = 0;
};

class DXTexture : public Texture
{
  void Blend(Texture *other)
  {
    other->BindAsRenderTarget();
    this->Bind();
    renderer->RenderQuad();
  }
  virtual void BindAsRenderTarget()
  {
    renderer->BindRenderTarget(this);
  }
  virtual void Bind()
  {
    renderer->Bind(this);
  }
};
#28
18:38, 28 июня 2010

ОМФГ

winter
> Т.е. юзер может передать девайсу только то, что получил сам - абстрактный
> интерфейс текстуры

Для девайса это уже не совсем абстрактный интерфейс. Девайс так или иначе может гарантировать, что интерфейс был произведен им. Соответственно тайпкаст более чем оправдан. Двойная диспетчеризация нужна тогда, когда мы не знаем на этапе компиляции, к какому типу приводить. И это не этот случай.

Есть, кстати, более элегантные способы двойной диспетчеризации. Но их упоминание на этом форуме, увы, плохая примета...

UPD:
Метод  Suslik тоже хорош)

#29
18:38, 28 июня 2010

Ага,тото...
Ну...я даже не представляю зачем мне объект текстуры...да даже шейдера...настроить его может связка обертка-менеджер данного ресурса...использовать обертка..
В голову не приходит зачем мне надо передать объект текстуры да и шейдера куда-то
конечно это не по-христиански,не по ООП...

не,походу я еше не дорос до вашей весовой категории,и мне не понятны ваши проблемы)

Страницы: 1 2 3 430 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.