Commit 2ca8282e authored by lukeph's avatar lukeph

-- added VBO support --

-so far only the openGL driver is supported, will add dx tomorrow or the next day

-right now to use, go: MeshBuffer->setHardwareMappingHint(EHM_STATIC); but this will be automatic when complete

-code needs a clean up, and the design isn't fixed, I just wanted to get stuff happening :)

-works well with hardware skinning :)

(design: http://img220.imageshack.us/img220/1931/vbo8xy8.png)

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1095 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 51f7a358
...@@ -18,7 +18,7 @@ namespace scene ...@@ -18,7 +18,7 @@ namespace scene
{ {
public: public:
//! constructor //! constructor
CMeshBuffer() // everything's default constructed CMeshBuffer():ChangedID(1),MappingHint(EHM_NEVER) // everything's default constructed
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("SMeshBuffer"); setDebugName("SMeshBuffer");
...@@ -41,13 +41,13 @@ namespace scene ...@@ -41,13 +41,13 @@ namespace scene
virtual const void* getVertices() const virtual const void* getVertices() const
{ {
return Vertices.const_pointer(); return Vertices.const_pointer();
} }
//! returns pointer to vertices //! returns pointer to vertices
virtual void* getVertices() virtual void* getVertices()
{ {
return Vertices.pointer(); return Vertices.pointer();
} }
//! returns amount of vertices //! returns amount of vertices
virtual u32 getVertexCount() const virtual u32 getVertexCount() const
...@@ -109,27 +109,27 @@ namespace scene ...@@ -109,27 +109,27 @@ namespace scene
virtual const core::vector3df& getPosition(u32 i) const virtual const core::vector3df& getPosition(u32 i) const
{ {
return Vertices[i].Pos; return Vertices[i].Pos;
} }
//! returns position of vertex i //! returns position of vertex i
virtual core::vector3df& getPosition(u32 i) virtual core::vector3df& getPosition(u32 i)
{ {
return Vertices[i].Pos; return Vertices[i].Pos;
} }
//! returns normal of vertex i //! returns normal of vertex i
virtual const core::vector3df& getNormal(u32 i) const virtual const core::vector3df& getNormal(u32 i) const
{ {
return Vertices[i].Normal; return Vertices[i].Normal;
} }
//! returns normal of vertex i //! returns normal of vertex i
virtual core::vector3df& getNormal(u32 i) virtual core::vector3df& getNormal(u32 i)
{ {
return Vertices[i].Normal; return Vertices[i].Normal;
} }
//! append the vertices and indices to the current buffer //! append the vertices and indices to the current buffer
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices)
{ {
...@@ -170,6 +170,29 @@ namespace scene ...@@ -170,6 +170,29 @@ namespace scene
BoundingBox.addInternalBox(other->getBoundingBox()); BoundingBox.addInternalBox(other->getBoundingBox());
} }
//! get the current hardware mapping hint
virtual const E_HARDWARE_MAPPING getHardwareMappingHint() const
{
return MappingHint;
}
//! set the hardware mapping hint, for driver
virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint )
{
MappingHint=NewMappingHint;
}
//! flags the mesh as changed, reloads hardware buffers
virtual void setDirty() {ChangedID++;}
virtual const u32 getChangedID() const {return ChangedID;}
u32 ChangedID;
//! hardware mapping hint
E_HARDWARE_MAPPING MappingHint;
//! Material for this meshbuffer. //! Material for this meshbuffer.
video::SMaterial Material; video::SMaterial Material;
//! Vertices of this buffer //! Vertices of this buffer
......
...@@ -55,6 +55,20 @@ namespace scene ...@@ -55,6 +55,20 @@ namespace scene
}; };
enum E_HARDWARE_MAPPING
{
//! Don't load in hardware
EHM_NEVER=0,
//! Rarely changed
EHM_STATIC,
//! Sometimes changed
EHM_DYNAMIC,
//! Always changed
EHM_STREAM
};
//! Struct for holding a mesh with a single material //! Struct for holding a mesh with a single material
/** SMeshBuffer is a simple implementation of a MeshBuffer. */ /** SMeshBuffer is a simple implementation of a MeshBuffer. */
...@@ -76,11 +90,11 @@ namespace scene ...@@ -76,11 +90,11 @@ namespace scene
//! returns pointer to vertex data. The data is an array of vertices. Which vertex //! returns pointer to vertex data. The data is an array of vertices. Which vertex
//! type is used can be determined with getVertexType(). //! type is used can be determined with getVertexType().
virtual const void* getVertices() const = 0; virtual const void* getVertices() const = 0;
//! returns pointer to vertex data. The data is an array of vertices. Which vertex //! returns pointer to vertex data. The data is an array of vertices. Which vertex
//! type is used can be determined with getVertexType(). //! type is used can be determined with getVertexType().
virtual void* getVertices() = 0; virtual void* getVertices() = 0;
//! returns amount of vertices //! returns amount of vertices
virtual u32 getVertexCount() const = 0; virtual u32 getVertexCount() const = 0;
...@@ -120,6 +134,21 @@ namespace scene ...@@ -120,6 +134,21 @@ namespace scene
//! append the meshbuffer to the current buffer //! append the meshbuffer to the current buffer
virtual void append(const IMeshBuffer* const other) = 0; virtual void append(const IMeshBuffer* const other) = 0;
//! get the current hardware mapping hint
virtual const E_HARDWARE_MAPPING getHardwareMappingHint() const = 0;
//! set the hardware mapping hint, for driver
virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint ) = 0;
//! flags the mesh as changed, reloads hardware buffers
virtual void setDirty() = 0;
virtual const u32 getChangedID() const = 0;
u32 HardwareHint;
}; };
} // end namespace scene } // end namespace scene
......
...@@ -16,7 +16,7 @@ namespace scene ...@@ -16,7 +16,7 @@ namespace scene
struct SSharedMeshBuffer : public IMeshBuffer struct SSharedMeshBuffer : public IMeshBuffer
{ {
//! constructor //! constructor
SSharedMeshBuffer() : IMeshBuffer(), Vertices(0) SSharedMeshBuffer() : IMeshBuffer(), ChangedID(1),MappingHint(Never), Vertices(0)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("SSharedMeshBuffer"); setDebugName("SSharedMeshBuffer");
...@@ -127,6 +127,31 @@ namespace scene ...@@ -127,6 +127,31 @@ namespace scene
//! append the meshbuffer to the current buffer //! append the meshbuffer to the current buffer
virtual void append(const IMeshBuffer* const other) {} virtual void append(const IMeshBuffer* const other) {}
//! get the current hardware mapping hint
virtual const E_HARDWARE_MAPPING getHardwareMappingHint() const
{
return MappingHint;
}
//! set the hardware mapping hint, for driver
virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint )
{
MappingHint=NewMappingHint;
}
//! flags the mesh as changed, reloads hardware buffers
virtual void setDirty() {ChangedID++;}
virtual const u32 getChangedID() const {return ChangedID;}
u32 ChangedID;
// hardware mapping hint
E_HARDWARE_MAPPING MappingHint;
video::SMaterial Material; //! material of this meshBuffer video::SMaterial Material; //! material of this meshBuffer
core::array<video::S3DVertex> *Vertices;//! Shared Array of vertices core::array<video::S3DVertex> *Vertices;//! Shared Array of vertices
core::array<u16> Indices; //! Array of Indices core::array<u16> Indices; //! Array of Indices
......
...@@ -19,7 +19,7 @@ namespace scene ...@@ -19,7 +19,7 @@ namespace scene
//! S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime //! S3DVertex2TCoords, S3DVertex and S3DVertexTangents at runtime
struct SSkinMeshBuffer : public IMeshBuffer struct SSkinMeshBuffer : public IMeshBuffer
{ {
SSkinMeshBuffer(video::E_VERTEX_TYPE vt=video::EVT_STANDARD) : VertexType(vt) SSkinMeshBuffer(video::E_VERTEX_TYPE vt=video::EVT_STANDARD) : ChangedID(1),MappingHint(EHM_NEVER),VertexType(vt)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("SSkinMeshBuffer"); setDebugName("SSkinMeshBuffer");
...@@ -210,10 +210,10 @@ struct SSkinMeshBuffer : public IMeshBuffer ...@@ -210,10 +210,10 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Pos; return Vertices_2TCoords[i].Pos;
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents[i].Pos; return Vertices_Tangents[i].Pos;
default: default:
return Vertices_Standard[i].Pos; return Vertices_Standard[i].Pos;
} }
} }
//! returns position of vertex i //! returns position of vertex i
virtual core::vector3df& getPosition(u32 i) virtual core::vector3df& getPosition(u32 i)
...@@ -224,10 +224,10 @@ struct SSkinMeshBuffer : public IMeshBuffer ...@@ -224,10 +224,10 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Pos; return Vertices_2TCoords[i].Pos;
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents[i].Pos; return Vertices_Tangents[i].Pos;
default: default:
return Vertices_Standard[i].Pos; return Vertices_Standard[i].Pos;
} }
} }
//! returns normal of vertex i //! returns normal of vertex i
virtual const core::vector3df& getNormal(u32 i) const virtual const core::vector3df& getNormal(u32 i) const
...@@ -238,10 +238,10 @@ struct SSkinMeshBuffer : public IMeshBuffer ...@@ -238,10 +238,10 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Normal; return Vertices_2TCoords[i].Normal;
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents[i].Normal; return Vertices_Tangents[i].Normal;
default: default:
return Vertices_Standard[i].Normal; return Vertices_Standard[i].Normal;
} }
} }
//! returns normal of vertex i //! returns normal of vertex i
virtual core::vector3df& getNormal(u32 i) virtual core::vector3df& getNormal(u32 i)
...@@ -252,17 +252,45 @@ struct SSkinMeshBuffer : public IMeshBuffer ...@@ -252,17 +252,45 @@ struct SSkinMeshBuffer : public IMeshBuffer
return Vertices_2TCoords[i].Normal; return Vertices_2TCoords[i].Normal;
case video::EVT_TANGENTS: case video::EVT_TANGENTS:
return Vertices_Tangents[i].Normal; return Vertices_Tangents[i].Normal;
default: default:
return Vertices_Standard[i].Normal; return Vertices_Standard[i].Normal;
} }
} }
//! append the vertices and indices to the current buffer //! append the vertices and indices to the current buffer
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) {} virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) {}
//! append the meshbuffer to the current buffer //! append the meshbuffer to the current buffer
virtual void append(const IMeshBuffer* const other) {} virtual void append(const IMeshBuffer* const other) {}
//! get the current hardware mapping hint
virtual const E_HARDWARE_MAPPING getHardwareMappingHint() const
{
return MappingHint;
}
//! set the hardware mapping hint, for driver
virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint )
{
MappingHint=NewMappingHint;
}
//! flags the mesh as changed, reloads hardware buffers
virtual void setDirty() {ChangedID++;}
virtual const u32 getChangedID() const {return ChangedID;}
u32 ChangedID;
// hardware mapping hint
E_HARDWARE_MAPPING MappingHint;
//ISkinnedMesh::SJoint *AttachedJoint; //ISkinnedMesh::SJoint *AttachedJoint;
core::matrix4 Transformation; core::matrix4 Transformation;
......
...@@ -214,6 +214,7 @@ bool CNullDriver::beginScene(bool backBuffer, bool zBuffer, SColor color) ...@@ -214,6 +214,7 @@ bool CNullDriver::beginScene(bool backBuffer, bool zBuffer, SColor color)
bool CNullDriver::endScene( s32 windowId, core::rect<s32>* sourceRect ) bool CNullDriver::endScene( s32 windowId, core::rect<s32>* sourceRect )
{ {
FPSCounter.registerFrame(os::Timer::getRealTime(), PrimitivesDrawn); FPSCounter.registerFrame(os::Timer::getRealTime(), PrimitivesDrawn);
updateAllHardwareBuffers();
return true; return true;
} }
...@@ -1246,10 +1247,84 @@ void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb) ...@@ -1246,10 +1247,84 @@ void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb)
if (!mb) if (!mb)
return; return;
drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES); //IVertexBuffer and IIndexBuffer later
SHWBufferLink *HWBuffer=getBufferLink(mb);
if (HWBuffer)
drawHardwareBuffer(HWBuffer);
else
drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES);
} }
CNullDriver::SHWBufferLink *CNullDriver::getBufferLink(const scene::IMeshBuffer* mb)
{
if (!isHardwareBufferRecommend(mb))
return 0;
/*
u32 startIndex=0;
for (u32 n=0;n<HWBufferLinks.size();n+=30)
{
if (HWBufferLinks[n]->MeshBuffer < mb)
startIndex=n;
}
*/
//search for hardware links
for (u32 n=0;n<HWBufferLinks.size();++n)
{
SHWBufferLink *Link=HWBufferLinks[n];
if (Link->MeshBuffer==mb)
{
((scene::IMeshBuffer*)mb)->HardwareHint=n;
return Link;
}
}
return createHardwareBuffer(mb); //no hardware links, and mesh wants one, create it
}
//! Update all hardware buffers, remove unused ones
void CNullDriver::updateAllHardwareBuffers()
{
for (u32 n=0;n<HWBufferLinks.size();++n)
{
SHWBufferLink *Link=HWBufferLinks[n];
Link->LastUsed++;
if (Link->LastUsed>1000)
{
deleteHardwareBuffer(Link);
delete Link;
HWBufferLinks.erase(n);
}
}
}
//! Remove all hardware buffers
void CNullDriver::removeAllHardwareBuffers()
{
for (u32 n=0;n<HWBufferLinks.size();++n)
{
deleteHardwareBuffer(HWBufferLinks[n]);
delete HWBufferLinks[n];
}
HWBufferLinks.clear();
}
bool CNullDriver::isHardwareBufferRecommend(const scene::IMeshBuffer* mb)
{
if (mb->getHardwareMappingHint()==scene::EHM_NEVER)
return false;
if (mb->getVertexCount()<500) //todo: tweak and make user definable
return false;
return true;
}
//! Only used by the internal engine. Used to notify the driver that //! Only used by the internal engine. Used to notify the driver that
//! the window was resized. //! the window was resized.
......
...@@ -30,6 +30,8 @@ namespace video ...@@ -30,6 +30,8 @@ namespace video
class IImageLoader; class IImageLoader;
class IImageWriter; class IImageWriter;
class CNullDriver : public IVideoDriver, public IGPUProgrammingServices class CNullDriver : public IVideoDriver, public IGPUProgrammingServices
{ {
public: public:
...@@ -72,7 +74,7 @@ namespace video ...@@ -72,7 +74,7 @@ namespace video
virtual ITexture* addTexture(const core::dimension2d<s32>& size, const c8* name, ECOLOR_FORMAT format = ECF_A8R8G8B8); virtual ITexture* addTexture(const core::dimension2d<s32>& size, const c8* name, ECOLOR_FORMAT format = ECF_A8R8G8B8);
//! sets a render target //! sets a render target
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color); bool clearZBuffer, SColor color);
//! sets a viewport //! sets a viewport
...@@ -148,7 +150,7 @@ namespace video ...@@ -148,7 +150,7 @@ namespace video
bool useAlphaChannelOfTexture=false); bool useAlphaChannelOfTexture=false);
//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.
virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false);
...@@ -165,17 +167,17 @@ namespace video ...@@ -165,17 +167,17 @@ namespace video
SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
const core::rect<s32>* clip = 0); const core::rect<s32>* clip = 0);
//! Draws a 2d line. //! Draws a 2d line.
virtual void draw2DLine(const core::position2d<s32>& start, virtual void draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end, const core::position2d<s32>& end,
SColor color=SColor(255,255,255,255)); SColor color=SColor(255,255,255,255));
//! Draws a non filled concyclic reqular 2d polyon. //! Draws a non filled concyclic reqular 2d polyon.
virtual void draw2DPolygon(core::position2d<s32> center, virtual void draw2DPolygon(core::position2d<s32> center,
f32 radius, video::SColor Color, s32 vertexCount); f32 radius, video::SColor Color, s32 vertexCount);
virtual void setFog(SColor color=SColor(0,255,255,255), bool linearFog=true, virtual void setFog(SColor color=SColor(0,255,255,255), bool linearFog=true,
f32 start=50.0f, f32 end=100.0f, f32 start=50.0f, f32 end=100.0f,
f32 density=0.01f, bool pixelFog=false, bool rangeFog=false); f32 density=0.01f, bool pixelFog=false, bool rangeFog=false);
//! returns screen size //! returns screen size
...@@ -222,9 +224,9 @@ namespace video ...@@ -222,9 +224,9 @@ namespace video
//! Fills the stencil shadow with color. After the shadow volume has been drawn //! Fills the stencil shadow with color. After the shadow volume has been drawn
//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
//! to draw the color of the shadow. //! to draw the color of the shadow.
virtual void drawStencilShadow(bool clearStencilBuffer=false, virtual void drawStencilShadow(bool clearStencilBuffer=false,
video::SColor leftUpEdge = video::SColor(0,0,0,0), video::SColor leftUpEdge = video::SColor(0,0,0,0),
video::SColor rightUpEdge = video::SColor(0,0,0,0), video::SColor rightUpEdge = video::SColor(0,0,0,0),
video::SColor leftDownEdge = video::SColor(0,0,0,0), video::SColor leftDownEdge = video::SColor(0,0,0,0),
video::SColor rightDownEdge = video::SColor(0,0,0,0)); video::SColor rightDownEdge = video::SColor(0,0,0,0));
...@@ -240,11 +242,11 @@ namespace video ...@@ -240,11 +242,11 @@ namespace video
virtual const SLight& getDynamicLight(u32 idx) const; virtual const SLight& getDynamicLight(u32 idx) const;
//! Removes a texture from the texture cache and deletes it, freeing lot of //! Removes a texture from the texture cache and deletes it, freeing lot of
//! memory. //! memory.
virtual void removeTexture(ITexture* texture); virtual void removeTexture(ITexture* texture);
//! Removes all texture from the texture cache and deletes them, freeing lot of //! Removes all texture from the texture cache and deletes them, freeing lot of
//! memory. //! memory.
virtual void removeAllTextures(); virtual void removeAllTextures();
//! Creates a render target texture. //! Creates a render target texture.
...@@ -256,7 +258,7 @@ namespace video ...@@ -256,7 +258,7 @@ namespace video
//! Creates an 1bit alpha channel of the texture based of an color key position. //! Creates an 1bit alpha channel of the texture based of an color key position.
virtual void makeColorKeyTexture(video::ITexture* texture, core::position2d<s32> colorKeyPixelPos) const; virtual void makeColorKeyTexture(video::ITexture* texture, core::position2d<s32> colorKeyPixelPos) const;
//! Creates a normal map from a height map texture. //! Creates a normal map from a height map texture.
//! \param amplitude: Constant value by which the height information is multiplied. //! \param amplitude: Constant value by which the height information is multiplied.
virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const; virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const;
...@@ -271,23 +273,69 @@ namespace video ...@@ -271,23 +273,69 @@ namespace video
//! Returns if a texture creation flag is enabled or disabled. //! Returns if a texture creation flag is enabled or disabled.
virtual bool getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const; virtual bool getTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag) const;
//! Creates a software image from a file. //! Creates a software image from a file.
virtual IImage* createImageFromFile(const char* filename); virtual IImage* createImageFromFile(const char* filename);
//! Creates a software image from a file. //! Creates a software image from a file.
virtual IImage* createImageFromFile(io::IReadFile* file); virtual IImage* createImageFromFile(io::IReadFile* file);
//! Creates a software image from a byte array. //! Creates a software image from a byte array.
//! \param useForeignMemory: If true, the image will use the data pointer //! \param useForeignMemory: If true, the image will use the data pointer
//! directly and own it from now on, which means it will also try to delete [] the //! directly and own it from now on, which means it will also try to delete [] the
//! data when the image will be destructed. If false, the memory will by copied. //! data when the image will be destructed. If false, the memory will by copied.
virtual IImage* createImageFromData(ECOLOR_FORMAT format, virtual IImage* createImageFromData(ECOLOR_FORMAT format,
const core::dimension2d<s32>& size, void *data, const core::dimension2d<s32>& size, void *data,
bool ownForeignMemory=true, bool deleteForeignMemory = true); bool ownForeignMemory=true, bool deleteForeignMemory = true);
//! Draws a mesh buffer //! Draws a mesh buffer
virtual void drawMeshBuffer(const scene::IMeshBuffer* mb); virtual void drawMeshBuffer(const scene::IMeshBuffer* mb);
struct SHWBufferLink
{
SHWBufferLink(const scene::IMeshBuffer *_MeshBuffer):MeshBuffer(_MeshBuffer),ChangedID(0),LastUsed(0),Mapped(scene::EHM_NEVER)
{
if (MeshBuffer)
MeshBuffer->grab();
}
virtual ~SHWBufferLink()
{
if (MeshBuffer)
MeshBuffer->drop();
}
const scene::IMeshBuffer *MeshBuffer;
u32 ChangedID;
u32 LastUsed;
scene::E_HARDWARE_MAPPING Mapped;
};
//! Gets hardware buffer link from a meshbuffer (may create or update buffer)
virtual SHWBufferLink *getBufferLink(const scene::IMeshBuffer* mb);
//! updates hardware buffer if needed (only some drivers can)
virtual bool updateHardwareBuffer(SHWBufferLink *HWBuffer) {}
//! Create hardware buffer from mesh (only some drivers can)
virtual SHWBufferLink *createHardwareBuffer(const scene::IMeshBuffer* mb) {return 0;}
//! Draw hardware buffer (only some drivers can)
virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer) {}
//! Delete hardware buffer (only some drivers can)
virtual void deleteHardwareBuffer(SHWBufferLink *HWBuffer) {}
//! Update all hardware buffers, remove unused ones
virtual void updateAllHardwareBuffers();
//! Remove all hardware buffers
virtual void removeAllHardwareBuffers();
//! is vbo recommended on this mesh?
virtual bool isHardwareBufferRecommend(const scene::IMeshBuffer* mb);
//! Only used by the internal engine. Used to notify the driver that //! Only used by the internal engine. Used to notify the driver that
//! the window was resized. //! the window was resized.
virtual void OnResize(const core::dimension2d<s32>& size); virtual void OnResize(const core::dimension2d<s32>& size);
...@@ -307,8 +355,8 @@ namespace video ...@@ -307,8 +355,8 @@ namespace video
//! Returns pointer to the IGPUProgrammingServices interface. //! Returns pointer to the IGPUProgrammingServices interface.
virtual IGPUProgrammingServices* getGPUProgrammingServices(); virtual IGPUProgrammingServices* getGPUProgrammingServices();
//! Adds a new material renderer to the VideoDriver, using pixel and/or //! Adds a new material renderer to the VideoDriver, using pixel and/or
//! vertex shaders to render geometry. //! vertex shaders to render geometry.
virtual s32 addShaderMaterial(const c8* vertexShaderProgram = 0, virtual s32 addShaderMaterial(const c8* vertexShaderProgram = 0,
const c8* pixelShaderProgram = 0, const c8* pixelShaderProgram = 0,
...@@ -316,7 +364,7 @@ namespace video ...@@ -316,7 +364,7 @@ namespace video
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0); s32 userData=0);
//! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the
//! programs from files. //! programs from files.
virtual s32 addShaderMaterialFromFiles(io::IReadFile* vertexShaderProgram = 0, virtual s32 addShaderMaterialFromFiles(io::IReadFile* vertexShaderProgram = 0,
io::IReadFile* pixelShaderProgram = 0, io::IReadFile* pixelShaderProgram = 0,
...@@ -324,7 +372,7 @@ namespace video ...@@ -324,7 +372,7 @@ namespace video
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0); s32 userData=0);
//! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the //! Like IGPUProgrammingServices::addShaderMaterial(), but tries to load the
//! programs from files. //! programs from files.
virtual s32 addShaderMaterialFromFiles(const c8* vertexShaderProgramFileName = 0, virtual s32 addShaderMaterialFromFiles(const c8* vertexShaderProgramFileName = 0,
const c8* pixelShaderProgramFileName = 0, const c8* pixelShaderProgramFileName = 0,
...@@ -341,46 +389,46 @@ namespace video ...@@ -341,46 +389,46 @@ namespace video
//! Returns name of the material renderer //! Returns name of the material renderer
virtual const char* getMaterialRendererName(u32 idx) const; virtual const char* getMaterialRendererName(u32 idx) const;
//! Adds a new material renderer to the VideoDriver, based on a high level shading //! Adds a new material renderer to the VideoDriver, based on a high level shading
//! language. Currently only HLSL in D3D9 is supported. //! language. Currently only HLSL in D3D9 is supported.
virtual s32 addHighLevelShaderMaterial( virtual s32 addHighLevelShaderMaterial(
const c8* vertexShaderProgram, const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName = 0, const c8* vertexShaderEntryPointName = 0,
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const c8* pixelShaderProgram = 0, const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = 0, const c8* pixelShaderEntryPointName = 0,
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
IShaderConstantSetCallBack* callback = 0, IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0); s32 userData=0);
//! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description),
//! but tries to load the programs from files. //! but tries to load the programs from files.
virtual s32 addHighLevelShaderMaterialFromFiles( virtual s32 addHighLevelShaderMaterialFromFiles(
const c8* vertexShaderProgram, const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName = "main", const c8* vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const c8* pixelShaderProgram = 0, const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = "main", const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
IShaderConstantSetCallBack* callback = 0, IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0); s32 userData=0);
//! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description), //! Like IGPUProgrammingServices::addShaderMaterial() (look there for a detailed description),
//! but tries to load the programs from files. //! but tries to load the programs from files.
virtual s32 addHighLevelShaderMaterialFromFiles( virtual s32 addHighLevelShaderMaterialFromFiles(
io::IReadFile* vertexShaderProgram, io::IReadFile* vertexShaderProgram,
const c8* vertexShaderEntryPointName = "main", const c8* vertexShaderEntryPointName = "main",
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1, E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
io::IReadFile* pixelShaderProgram = 0, io::IReadFile* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = "main", const c8* pixelShaderEntryPointName = "main",
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1, E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
IShaderConstantSetCallBack* callback = 0, IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID, E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData=0); s32 userData=0);
//! Clears the ZBuffer. //! Clears the ZBuffer.
virtual void clearZBuffer(); virtual void clearZBuffer();
//! Returns an image created from the last rendered frame. //! Returns an image created from the last rendered frame.
...@@ -389,7 +437,7 @@ namespace video ...@@ -389,7 +437,7 @@ namespace video
//! Writes the provided image to disk file //! Writes the provided image to disk file
virtual bool writeImageToFile(IImage* image, const char* filename, u32 param = 0); virtual bool writeImageToFile(IImage* image, const char* filename, u32 param = 0);
//! Sets the name of a material renderer. //! Sets the name of a material renderer.
virtual void setMaterialRendererName(s32 idx, const char* name); virtual void setMaterialRendererName(s32 idx, const char* name);
//! Creates material attributes list from a material, usable for serialization and more. //! Creates material attributes list from a material, usable for serialization and more.
...@@ -460,7 +508,7 @@ namespace video ...@@ -460,7 +508,7 @@ namespace video
{ {
if (x < 0) x = pitch-1; if (x >= pitch) x = 0; if (x < 0) x = pitch-1; if (x >= pitch) x = 0;
if (y < 0) y = height-1; if (y >= height) y = 0; if (y < 0) y = height-1; if (y >= height) y = 0;
return (f32) getAverage ( p[(y * pitch) + x] ); return (f32) getAverage ( p[(y * pitch) + x] );
} }
...@@ -495,12 +543,17 @@ namespace video ...@@ -495,12 +543,17 @@ namespace video
core::dimension2d<s32> size; core::dimension2d<s32> size;
}; };
core::array<SSurface> Textures; core::array<SSurface> Textures;
core::array<video::IImageLoader*> SurfaceLoader; core::array<video::IImageLoader*> SurfaceLoader;
core::array<video::IImageWriter*> SurfaceWriter; core::array<video::IImageWriter*> SurfaceWriter;
core::array<SLight> Lights; core::array<SLight> Lights;
core::array<SMaterialRenderer> MaterialRenderers; core::array<SMaterialRenderer> MaterialRenderers;
core::array<SHWBufferLink*> HWBufferLinks;
io::IFileSystem* FileSystem; io::IFileSystem* FileSystem;
core::rect<s32> ViewPort; core::rect<s32> ViewPort;
......
...@@ -506,60 +506,281 @@ void COpenGLDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matri ...@@ -506,60 +506,281 @@ void COpenGLDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matri
} }
} }
bool COpenGLDriver::updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer)
//! draws a vertex primitive list
void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType)
{ {
if (!primitiveCount || !vertexCount) if (!HWBuffer)
return; return false;
if (!checkPrimitiveCount(primitiveCount)) if (!VertexBufferObjectExtension)
return; return false;
CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType); const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;
const void* vertices=mb->getVertices();
u32 vertexCount=mb->getVertexCount();
E_VERTEX_TYPE vType=mb->getVertexType();
u32 vertexSize = getVertexPitchFromType(vType);
// convert colors to gl color format. //buffer vertex data, and convert colours...
vertexCount *= 4; //reused as color component count core::array<c8> buffer(vertexSize * vertexCount);
ColorBuffer.set_used(vertexCount); memcpy(buffer.pointer(), vertices, vertexSize * vertexCount);
u32 i;
switch (vType) // in order to convert the colours into opengl format (RGBA)
switch (vType)
{ {
case EVT_STANDARD: case EVT_STANDARD:
{ {
const S3DVertex* p = reinterpret_cast<const S3DVertex*>(vertices); const S3DVertex* pb = reinterpret_cast<const S3DVertex*>(buffer.pointer());
for ( i=0; i<vertexCount; i+=4) const S3DVertex* po = reinterpret_cast<const S3DVertex*>(vertices);
for (u32 i=0; i<vertexCount; i++)
{ {
p->Color.toOpenGLColor(&ColorBuffer[i]); po[i].Color.toOpenGLColor((u8*)&(pb[i].Color.color));
++p;
} }
} }
break; break;
case EVT_2TCOORDS: case EVT_2TCOORDS:
{ {
const S3DVertex2TCoords* p = reinterpret_cast<const S3DVertex2TCoords*>(vertices); const S3DVertex2TCoords* pb = reinterpret_cast<const S3DVertex2TCoords*>(buffer.pointer());
for ( i=0; i<vertexCount; i+=4) const S3DVertex2TCoords* po = reinterpret_cast<const S3DVertex2TCoords*>(vertices);
for (u32 i=0; i<vertexCount; i++)
{ {
p->Color.toOpenGLColor(&ColorBuffer[i]); po[i].Color.toOpenGLColor((u8*)&(pb[i].Color.color));
++p;
} }
} }
break; break;
case EVT_TANGENTS: case EVT_TANGENTS:
{ {
const S3DVertexTangents* p = reinterpret_cast<const S3DVertexTangents*>(vertices); const S3DVertexTangents* pb = reinterpret_cast<const S3DVertexTangents*>(buffer.pointer());
for ( i=0; i<vertexCount; i+=4) const S3DVertexTangents* po = reinterpret_cast<const S3DVertexTangents*>(vertices);
for (u32 i=0; i<vertexCount; i++)
{ {
p->Color.toOpenGLColor(&ColorBuffer[i]); po[i].Color.toOpenGLColor((u8*)&(pb[i].Color.color));
++p;
} }
} }
break; break;
default:
{
return false;
}
} }
// draw everything //get or create buffer
bool newBuffer=false;
if (!HWBuffer->vbo_verticesID)
{
extGlGenBuffers(1, &HWBuffer->vbo_verticesID);
newBuffer=true;
}
extGlBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID );
//copy data to graphics card
if (!newBuffer)
extGlBufferSubData(GL_ARRAY_BUFFER, 0, vertexCount * vertexSize, buffer.const_pointer());
else
{
if (HWBuffer->Mapped==scene::EHM_STATIC)
extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, buffer.const_pointer(), GL_STATIC_DRAW);
else if (HWBuffer->Mapped==scene::EHM_DYNAMIC)
extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, buffer.const_pointer(), GL_DYNAMIC_DRAW);
else //scene::EHM_STREAM
extGlBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, buffer.const_pointer(), GL_STREAM_DRAW);
}
extGlBindBuffer(GL_ARRAY_BUFFER, 0);
return true;
}
bool COpenGLDriver::updateIndexHardwareBuffer(SHWBufferLink_opengl *HWBuffer)
{
if (!HWBuffer)
return false;
if(!VertexBufferObjectExtension)
return false;
const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;
const u16* indices=mb->getIndices();
u32 indexCount= mb->getIndexCount();
u32 indexSize = 2;
//get or create buffer
bool newBuffer=false;
if (!HWBuffer->vbo_indicesID)
{
extGlGenBuffers(1, &HWBuffer->vbo_indicesID);
newBuffer=true;
}
extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID);
//copy data to graphics card
if (!newBuffer)
extGlBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indexCount * indexSize, indices);
else
{
if (HWBuffer->Mapped==scene::EHM_STATIC)
extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STATIC_DRAW);
else if (HWBuffer->Mapped==scene::EHM_DYNAMIC)
extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_DYNAMIC_DRAW);
else //scene::EHM_STREAM
extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STREAM_DRAW);
}
extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
return true;
}
//! updates hardware buffer if needed
bool COpenGLDriver::updateHardwareBuffer(SHWBufferLink *HWBuffer)
{
if (!HWBuffer) return false;
if (HWBuffer->ChangedID != HWBuffer->MeshBuffer->getChangedID()
|| !((SHWBufferLink_opengl*)HWBuffer)->vbo_indicesID
|| !((SHWBufferLink_opengl*)HWBuffer)->vbo_verticesID)
{
HWBuffer->ChangedID = HWBuffer->MeshBuffer->getChangedID();
if (!updateVertexHardwareBuffer((SHWBufferLink_opengl*)HWBuffer)) return false;
if (!updateIndexHardwareBuffer((SHWBufferLink_opengl*)HWBuffer)) return false;
}
}
//! Create hardware buffer from mesh
COpenGLDriver::SHWBufferLink *COpenGLDriver::createHardwareBuffer(const scene::IMeshBuffer* mb)
{
if (!mb) return 0;
if (mb->getHardwareMappingHint()==scene::EHM_NEVER) return 0;
SHWBufferLink_opengl *HWBuffer=new SHWBufferLink_opengl(mb);
//add to list, in order of their meshbuffer pointer
u32 n;
for (n=0;n<HWBufferLinks.size();++n)
if (HWBufferLinks[n]->MeshBuffer > HWBuffer->MeshBuffer)
break;
if (n<HWBufferLinks.size())
HWBufferLinks.insert(HWBuffer,n);
else
HWBufferLinks.push_back(HWBuffer);
HWBuffer->ChangedID=HWBuffer->MeshBuffer->getChangedID();
HWBuffer->Mapped=mb->getHardwareMappingHint();
HWBuffer->LastUsed=0;
HWBuffer->vbo_verticesID=0;
HWBuffer->vbo_indicesID=0;
if (!updateHardwareBuffer(HWBuffer))
{
deleteHardwareBuffer(HWBuffer);
HWBufferLinks.erase(n);
delete HWBuffer;
return 0;
}
return HWBuffer;
}
void COpenGLDriver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer)
{
SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer;
if (HWBuffer->vbo_verticesID)
{
extGlDeleteBuffers(1, &HWBuffer->vbo_verticesID);
HWBuffer->vbo_verticesID=0;
}
if (HWBuffer->vbo_indicesID)
{
extGlDeleteBuffers(1, &HWBuffer->vbo_indicesID);
HWBuffer->vbo_indicesID=0;
}
}
//! Draw hardware buffer
void COpenGLDriver::drawHardwareBuffer(SHWBufferLink *_HWBuffer)
{
if (!_HWBuffer) return;
SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer;
const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;
updateHardwareBuffer(HWBuffer); //check if update is needed
HWBuffer->LastUsed=0;//reset count
extGlBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID);
extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID);
drawVertexPrimitiveList(0, mb->getVertexCount(), 0, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES);
extGlBindBuffer(GL_ARRAY_BUFFER, 0);
extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
//! draws a vertex primitive list
void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType)
{
if (!primitiveCount || !vertexCount)
return;
if (!checkPrimitiveCount(primitiveCount))
return;
CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType);
if (vertices)
{
// convert colors to gl color format.
vertexCount *= 4; //reused as color component count
ColorBuffer.set_used(vertexCount);
u32 i;
switch (vType)
{
case EVT_STANDARD:
{
const S3DVertex* p = reinterpret_cast<const S3DVertex*>(vertices);
for ( i=0; i<vertexCount; i+=4)
{
p->Color.toOpenGLColor(&ColorBuffer[i]);
++p;
}
}
break;
case EVT_2TCOORDS:
{
const S3DVertex2TCoords* p = reinterpret_cast<const S3DVertex2TCoords*>(vertices);
for ( i=0; i<vertexCount; i+=4)
{
p->Color.toOpenGLColor(&ColorBuffer[i]);
++p;
}
}
break;
case EVT_TANGENTS:
{
const S3DVertexTangents* p = reinterpret_cast<const S3DVertexTangents*>(vertices);
for ( i=0; i<vertexCount; i+=4)
{
p->Color.toOpenGLColor(&ColorBuffer[i]);
++p;
}
}
break;
}
}
// draw everything
setRenderStates3DMode(); setRenderStates3DMode();
if (MultiTextureExtension) if (MultiTextureExtension)
...@@ -572,13 +793,17 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun ...@@ -572,13 +793,17 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES)) if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES))
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_NORMAL_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]); if (vertices) glColorPointer(4, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]);
switch (vType) switch (vType)
{ {
case EVT_STANDARD: case EVT_STANDARD:
glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), &(reinterpret_cast<const S3DVertex*>(vertices))[0].Pos); glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), &(reinterpret_cast<const S3DVertex*>(vertices))[0].Pos);
glNormalPointer(GL_FLOAT, sizeof(S3DVertex), &(reinterpret_cast<const S3DVertex*>(vertices))[0].Normal); glNormalPointer(GL_FLOAT, sizeof(S3DVertex), &(reinterpret_cast<const S3DVertex*>(vertices))[0].Normal);
glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(reinterpret_cast<const S3DVertex*>(vertices))[0].TCoords); glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(reinterpret_cast<const S3DVertex*>(vertices))[0].TCoords);
if (!vertices) glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(S3DVertex), &(reinterpret_cast<const S3DVertex*>(vertices))[0].Color);
if (MultiTextureExtension && CurrentTexture[1]) if (MultiTextureExtension && CurrentTexture[1])
{ {
extGlClientActiveTexture(GL_TEXTURE1_ARB); extGlClientActiveTexture(GL_TEXTURE1_ARB);
...@@ -591,6 +816,9 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun ...@@ -591,6 +816,9 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), &(reinterpret_cast<const S3DVertex2TCoords*>(vertices))[0].Normal); glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), &(reinterpret_cast<const S3DVertex2TCoords*>(vertices))[0].Normal);
// texture coordinates // texture coordinates
glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(reinterpret_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords); glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(reinterpret_cast<const S3DVertex2TCoords*>(vertices))[0].TCoords);
if (!vertices) glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), &(reinterpret_cast<const S3DVertex2TCoords*>(vertices))[0].Color);
if (MultiTextureExtension) if (MultiTextureExtension)
{ {
extGlClientActiveTexture(GL_TEXTURE1_ARB); extGlClientActiveTexture(GL_TEXTURE1_ARB);
...@@ -603,6 +831,9 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun ...@@ -603,6 +831,9 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), &(reinterpret_cast<const S3DVertexTangents*>(vertices))[0].Normal); glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), &(reinterpret_cast<const S3DVertexTangents*>(vertices))[0].Normal);
// texture coordinates // texture coordinates
glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(reinterpret_cast<const S3DVertexTangents*>(vertices))[0].TCoords); glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(reinterpret_cast<const S3DVertexTangents*>(vertices))[0].TCoords);
if (!vertices) glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), &(reinterpret_cast<const S3DVertexTangents*>(vertices))[0].Color);
if (MultiTextureExtension) if (MultiTextureExtension)
{ {
extGlClientActiveTexture(GL_TEXTURE1_ARB); extGlClientActiveTexture(GL_TEXTURE1_ARB);
...@@ -695,6 +926,7 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun ...@@ -695,6 +926,7 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY);
} }
...@@ -864,10 +1096,10 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect ...@@ -864,10 +1096,10 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect
{ {
if (!clipRect->isValid()) if (!clipRect->isValid())
return; return;
glEnable(GL_SCISSOR_TEST); glEnable(GL_SCISSOR_TEST);
const core::dimension2d<s32>& renderTargetSize = getCurrentRenderTargetSize(); const core::dimension2d<s32>& renderTargetSize = getCurrentRenderTargetSize();
glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y, glScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height-clipRect->LowerRightCorner.Y,
clipRect->getWidth(), clipRect->getHeight()); clipRect->getWidth(), clipRect->getHeight());
} }
...@@ -959,7 +1191,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, ...@@ -959,7 +1191,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture,
glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y)); glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.UpperLeftCorner.Y));
glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y)); glVertex2f(GLfloat(poss.LowerRightCorner.X), GLfloat(poss.LowerRightCorner.Y));
glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y)); glVertex2f(GLfloat(poss.UpperLeftCorner.X), GLfloat(poss.LowerRightCorner.Y));
...@@ -1509,7 +1741,7 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh ...@@ -1509,7 +1741,7 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
const core::dimension2d<s32>& renderTargetSize = getCurrentRenderTargetSize(); const core::dimension2d<s32>& renderTargetSize = getCurrentRenderTargetSize();
m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-renderTargetSize.Height), -1.0, 1.0); m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-renderTargetSize.Height), -1.0, 1.0);
m.setTranslation(core::vector3df(-1,1,0)); m.setTranslation(core::vector3df(-1,1,0));
createGLMatrix(glmat, m); createGLMatrix(glmat, m);
...@@ -1517,7 +1749,7 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh ...@@ -1517,7 +1749,7 @@ void COpenGLDriver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
glTranslatef (0.375, 0.375, 0.0); glTranslatef (0.375, 0.375, 0.0);
glMatrixMode(GL_TEXTURE); glMatrixMode(GL_TEXTURE);
glLoadIdentity(); glLoadIdentity();
...@@ -2242,7 +2474,7 @@ void COpenGLDriver::clearZBuffer() ...@@ -2242,7 +2474,7 @@ void COpenGLDriver::clearZBuffer()
glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT);
glDepthMask(enabled); glDepthMask(enabled);
} }
//! Returns an image created from the last rendered frame. //! Returns an image created from the last rendered frame.
IImage* COpenGLDriver::createScreenShot() IImage* COpenGLDriver::createScreenShot()
......
...@@ -106,6 +106,30 @@ namespace video ...@@ -106,6 +106,30 @@ namespace video
//! sets transformation //! sets transformation
virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat); virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat);
struct SHWBufferLink_opengl : public SHWBufferLink
{
SHWBufferLink_opengl(const scene::IMeshBuffer *_MeshBuffer): SHWBufferLink(_MeshBuffer), vbo_verticesID(0),vbo_indicesID(0){}
GLuint vbo_verticesID; //tmp
GLuint vbo_indicesID; //tmp
};
bool COpenGLDriver::updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer);
bool COpenGLDriver::updateIndexHardwareBuffer(SHWBufferLink_opengl *HWBuffer);
//! updates hardware buffer if needed
virtual bool updateHardwareBuffer(SHWBufferLink *HWBuffer);
//! Create hardware buffer from mesh
virtual SHWBufferLink *createHardwareBuffer(const scene::IMeshBuffer* mb);
//! Delete hardware buffer (only some drivers can)
virtual void deleteHardwareBuffer(SHWBufferLink *HWBuffer);
//! Draw hardware buffer
virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer);
//! draws a vertex primitive list //! draws a vertex primitive list
virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType); virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType);
...@@ -324,6 +348,10 @@ namespace video ...@@ -324,6 +348,10 @@ namespace video
void createMaterialRenderers(); void createMaterialRenderers();
core::stringw Name; core::stringw Name;
core::matrix4 Matrices[ETS_COUNT]; core::matrix4 Matrices[ETS_COUNT];
core::array<u8> ColorBuffer; core::array<u8> ColorBuffer;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment