Sorry giving this idea again, but, I really would like SFML Team to implement DirectX as beckend.
I did some testing with my lib(Simple Tool For Games[STFG] - its not published yet...) and SFML.
DirectX is 10x times faster.
I tested this with drawing some number of rectangles.
You write your own lib using DirectX, don't publish the code, come up with a very synthetic benchmark and claim that DirectX is 10x faster than OpenGL?
First of all... unless you implemented your drawing exactly as SFML did, it already isn't a fair comparison, because SFML might be able to do things that your lib doesn't and you wrote the test so it would run using both libraries.
You can have part that renders rectangle. I'm not sure if this is anything similar to SFML Code beacuse im not inrested in SFML stuff or even OGL.
Code:
void Window::draw(st::g2d::RectangleShape& recta)
{
if (this->m_opened)
{
VOID* pStored;
st::Color fillColor(recta.getFillColor().r, recta.getFillColor().g, recta.getFillColor().b,
recta.getFillColor().a);
DWORD clr = D3DCOLOR_RGBA(fillColor.r, fillColor.g, fillColor.b, fillColor.a);
float m_x = recta.getPosition().x;
float m_y = recta.getPosition().y;
float m_width = recta.getSize().x;
float m_height = recta.getSize().y;
D3DXMATRIX trans;
D3DXMatrixTransformation2D(&trans,
&D3DXVECTOR2(recta.getOrigin().x + recta.getPosition().x, recta.getOrigin().y + recta.getPosition().y),
0.0f,
&D3DXVECTOR2(recta.getScale().x, recta.getScale().y),
&D3DXVECTOR2(recta.getOrigin().x + recta.getPosition().x, recta.getOrigin().y + recta.getPosition().y),
recta.getRotation(),
&D3DXVECTOR2(NULL, NULL));
this->m_device->SetTransform(D3DTS_WORLD, &(trans));
st::Vertex drawRect[] =
{
{ m_x, m_y, 0.0f, clr, },
{ m_x + m_width, m_y, 0.0f, clr, },
{ m_x, m_y + m_height, 0.0f, clr, },
{ m_x + m_width, m_y, 0.0f, clr, },
{ m_x + m_width, m_y + m_height, 0.0f, clr, },
{ m_x, m_y + m_height, 0.0f, clr, }
};
this->m_vBufferQuad->Lock(NULL, NULL, (void**)&pStored, NULL);
memcpy(pStored, drawRect, sizeof(drawRect));
this->m_vBufferQuad->Unlock();
this->m_device->SetStreamSource(NULL, this->m_vBufferQuad, NULL, sizeof(st::Vertex));
this->m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
}
}
(I deleted all comments
)
And there were two projects... Not all in one... Derp...
One used STFG and one SFML, I can post source for both projects if its rly needed...
What people seem to forget when comparing DirectX and OpenGL is that in the former case, you choose which API to use before writing even your first line of code. What happens if your library uses DirectX 11 and you have 10 year old hardware? Yeah... it doesn't work anymore. SFML will work on hardware that runs OpenGL 1.5 which dates all the way back to the last millenium. To make your comparison a bit more fair, you would have to make it use DirectX 7.
It's really easy to check if DirectX 9 or 10 or 11 or whatever is supported.
I don't see why not implementing DirectX as other beckend.
Sonkun is already working on an experimental DirectX implementation. Whether this is necessary is still up for discussion. The one advantage I can think of is enabling future support for platforms that are prevented from providing OpenGL support. Other than that, I don't see any real advantage DirectX would provide when OpenGL can be used as well.
Btw, it would be nice to have sf::Array in SFML System Module
Have you heard of the standard template library? In particular the containers library. Doing a bit of research before suggesting something that is already a language library feature helps sometimes...
You must be joking!!! (sarcastic, of course I know that...)
But this really is cool:
#ifndef STFG_ARRAY_H
#define STFG_ARRAY_H
#include <assert.h>
namespace st
{
template <typename TYPE>
class Array
{
public:
Array()
{
m_data = NULL;
m_size = 0;
m_maxSize = 0;
}
Array(const Array <TYPE>& a)
{
for(int i = 0; i < a.m_size; i++)
this->add(a.m_data[i]);
}
~Array()
{
this->removeAll();
}
const TYPE& operator[](int nIndex) const
{
return this->getAt(nIndex);
}
TYPE& operator[](int nIndex)
{
return this->getAt(nIndex);
}
Array& operator=(const Array <TYPE>& a)
{
if(this == &a)
return *this;
this->removeAll();
for(int i = 0; i < a.m_size; i++)
this->add( a.m_data[i] );
return *this;
}
HRESULT setSize(int nNewMaxSize)
{
int nOldSize = m_size;
if(nOldSize > nNewMaxSize)
{
assert(m_data);
if(m_data)
{
for(int i = nNewMaxSize; i < nOldSize; ++i)
m_data[i].~TYPE();
}
}
HRESULT hr = this->setSizeInternal(nNewMaxSize);
if(nOldSize < nNewMaxSize)
{
assert(m_data);
if(m_data)
{
for(int i = nOldSize; i < nNewMaxSize; ++i)
::new(&m_data[i]) TYPE;
}
}
return hr;
}
HRESULT add(const TYPE& value)
{
HRESULT hr;
if(FAILED(hr = this->setSizeInternal(m_size + 1)))
return hr;
assert(m_data != NULL);
::new(&m_data[m_size])TYPE;
m_data[m_size] = value;
++m_size;
return S_OK;
}
HRESULT insert(int nIndex, const TYPE& value)
{
HRESULT hr;
if(nIndex < 0 || nIndex > m_size )
{
assert(false);
return E_INVALIDARG;
}
if(FAILED(hr = this->setSizeInternal(m_size + 1)))
return hr;
MoveMemory(&m_data[nIndex + 1], &m_data[nIndex], sizeof(TYPE) * (m_size - nIndex));
::new(&m_data[nIndex])TYPE;
m_data[nIndex] = value;
++m_size;
return S_OK:
}
HRESULT setAt(int nIndex, const TYPE& value)
{
//Validate arguments
if(nIndex < 0 || nIndex >= m_size )
{
assert(false);
return E_INVALIDARG;
}
m_data[nIndex] = value;
return S_OK;
}
TYPE& getAt(int nIndex) const
{
assert(nIndex >= 0 && nIndex < m_size);
return m_data[nIndex];
}
int getSize() const
{
return m_size;
}
TYPE* getData()
{
return this->m_data;
}
bool contains(const TYPE& value)
{
return (-1 != this->indexOf(value));
}
int indexOf(const TYPE& value)
{
return (m_nSize > 0) ? this->indexOf(value, 0, m_nSize) : -1;
}
int indexOf(const TYPE& value, int iStart)
{
return this->indexOf(value, iStart, m_size - iStart);
}
int indexOf(const TYPE& value, int nIndex, int nNumElements)
{
if(iStart < 0 || iStart >= m_size || nNumElements < 0 || iStart + nNumElements > m_size)
{
assert(false);
return -1;
}
for(int i = iStart; i < (iStart + nNumElements); i++)
{
if(value == m_data[i])
return i;
}
return -1;
}
int lastIndexOf(const TYPE& value)
{
return (this->m_size > 0) ? this->lastIndexOf(value, m_nSize - 1, m_nSize) : -1;
}
int lastIndexOf(const TYPE& value, int nIndex)
{
return this->lastIndexOf(value, nIndex, nIndex + 1);
}
int lastIndexOf(const TYPE& value, int nIndex, int nNumElements)
{
if(iEnd < 0 || iEnd >= m_size || nNumElements < 0 || iEnd - nNumElements < 0)
{
assert(false);
return -1;
}
for(int i = iEnd; i > (iEnd - nNumElements); i--)
{
if(value == m_data[i])
return i;
}
return -1;
}
HRESULT remove(int nIndex)
{
if(nIndex < 0 || nIndex >= m_size)
{
assert(false);
return E_INVALIDARG;
}
m_data[nIndex].~TYPE();
MoveMemory(&m_data[nIndex], &m_data[nIndex + 1], sizeof(TYPE) * (m_size - (nIndex + 1)));
--m_size;
return S_OK;
}
void removeAll()
{
this->setSize(0);
}
void reset()
{
this->m_size = 0;
}
protected:
TYPE* m_data;
int m_size;
int m_maxSize;
HRESULT setSizeInternal(int nNewMaxSize)
{
if(nNewMaxSize < 0 || (nNewMaxSize > INT_MAX / sizeof(TYPE)))
{
assert(false);
return E_INVALIDARG;
}
if(nNewMaxSize == 0)
{
if(m_data)
{
free(m_data);
m_data = NULL;
}
m_maxSize = 0;
m_size = 0;
}
else if(m_data == NULL || nNewMaxSize > m_maxSize)
{
int nGrowBy = (m_maxSize == 0) ? 16 : m_maxSize;
if((UINT)m_maxSize + (UINT)nGrowBy > (UINT)INT_MAX)
nGrowBy = INT_MAX - m_maxSize;
nNewMaxSize = __max(nNewMaxSize, m_maxSize + nGrowBy);
if(sizeof(TYPE) > UINT_MAX / (UINT)nNewMaxSize)
return E_INVALIDARG;
TYPE* pDataNew = (TYPE*)realloc(m_data, nNewMaxSize * sizeof(TYPE));
if(pDataNew == NULL)
return E_OUTOFMEMORY;
m_data = pDataNew;
m_maxSize = nNewMaxSize;
}
return S_OK;
}
};
}
#endif //STFG_ARRAY_H
(Again I removed all comments)
This STFG_Array.h is actually made by my friend who is also in the STFG Team.