1 // Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #ifndef __C_VIDEO_2_SOFTWARE_H_INCLUDED__
\r
6 #define __C_VIDEO_2_SOFTWARE_H_INCLUDED__
\r
8 #include "SoftwareDriver2_compile_config.h"
\r
9 #include "IBurningShader.h"
\r
10 #include "CNullDriver.h"
\r
13 #include "irrString.h"
\r
14 #include "SIrrCreationParameters.h"
\r
21 class CBurningVideoDriver : public CNullDriver, public IMaterialRendererServices
\r
26 CBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter);
\r
29 virtual ~CBurningVideoDriver();
\r
31 //! queries the features of the driver, returns true if feature is available
\r
32 virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const _IRR_OVERRIDE_;
\r
34 //! Create render target.
\r
35 virtual IRenderTarget* addRenderTarget() _IRR_OVERRIDE_;
\r
37 //! sets transformation
\r
38 virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) _IRR_OVERRIDE_;
\r
41 virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;
\r
43 virtual bool setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor,
\r
44 f32 clearDepth, u8 clearStencil) _IRR_OVERRIDE_;
\r
47 virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;
\r
48 virtual void setScissor(int x, int y, int width, int height);
\r
50 virtual bool beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil,
\r
51 const SExposedVideoData& videoData, core::rect<s32>* sourceRect) _IRR_OVERRIDE_;
\r
53 #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
\r
54 virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color,
\r
55 const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
\r
58 if (backBuffer) flag |= ECBF_COLOR;
\r
59 if (zBuffer) flag |= ECBF_DEPTH;
\r
60 return beginScene(flag, color, 1.f, 0, videoData, sourceRect);
\r
62 virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, bool clearZBuffer, SColor color);
\r
65 virtual bool endScene() _IRR_OVERRIDE_;
\r
67 //! Only used by the internal engine. Used to notify the driver that
\r
68 //! the window was resized.
\r
69 virtual void OnResize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;
\r
71 //! returns size of the current render target
\r
72 virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const _IRR_OVERRIDE_;
\r
74 //! deletes all dynamic lights there are
\r
75 virtual void deleteAllDynamicLights() _IRR_OVERRIDE_;
\r
77 //! adds a dynamic light, returning an index to the light
\r
78 //! \param light: the light data to use to create the light
\r
79 //! \return An index to the light, or -1 if an error occurs
\r
80 virtual s32 addDynamicLight(const SLight& light) _IRR_OVERRIDE_;
\r
82 //! Turns a dynamic light on or off
\r
83 //! \param lightIndex: the index returned by addDynamicLight
\r
84 //! \param turnOn: true to turn the light on, false to turn it off
\r
85 virtual void turnLightOn(s32 lightIndex, bool turnOn) _IRR_OVERRIDE_;
\r
87 //! returns the maximal amount of dynamic lights the device can handle
\r
88 virtual u32 getMaximalDynamicLightAmount() const _IRR_OVERRIDE_;
\r
90 //! Sets the dynamic ambient light color. The default color is
\r
91 //! (0,0,0,0) which means it is dark.
\r
92 //! \param color: New color of the ambient light.
\r
93 virtual void setAmbientLight(const SColorf& color) _IRR_OVERRIDE_;
\r
95 //! draws a vertex primitive list
\r
96 virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
\r
97 const void* indexList, u32 primitiveCount,
\r
98 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) _IRR_OVERRIDE_;
\r
100 //! draws a vertex primitive list in 2d
\r
101 virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount,
\r
102 const void* indexList, u32 primitiveCount,
\r
103 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) _IRR_OVERRIDE_;
\r
106 //! draws an 2d image
\r
107 //virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, bool useAlphaChannelOfTexture) _IRR_OVERRIDE_;
\r
109 /* NullDriver calls
\r
110 draw2DImage(texture, destPos,
\r
111 core::rect<s32>(core::position2d<s32>(0, 0), core::dimension2di(texture->getOriginalSize())),
\r
113 SColor(255, 255, 255, 255),
\r
114 useAlphaChannelOfTexture
\r
117 //! 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.
\r
118 virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
\r
119 const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
\r
120 SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;
\r
122 //! Draws a part of the texture into the rectangle.
\r
123 virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
\r
124 const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
\r
125 const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;
\r
127 //! Draws a 3d line.
\r
128 virtual void draw3DLine(const core::vector3df& start,
\r
129 const core::vector3df& end, SColor color_start) _IRR_OVERRIDE_;
\r
131 //! draw an 2d rectangle
\r
132 //virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,
\r
133 // const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;
\r
135 /* NullDriver calls
\r
136 draw2DRectangle(pos, color, color, color, color, clip);
\r
139 //!Draws an 2d rectangle with a gradient.
\r
140 virtual void draw2DRectangle(const core::rect<s32>& pos,
\r
141 SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
\r
142 const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;
\r
144 //! Draws a 2d line.
\r
145 virtual void draw2DLine(const core::position2d<s32>& start,
\r
146 const core::position2d<s32>& end,
\r
147 SColor color=SColor(255,255,255,255)) _IRR_OVERRIDE_;
\r
149 //! Draws a single pixel
\r
150 virtual void drawPixel(u32 x, u32 y, const SColor & color) _IRR_OVERRIDE_;
\r
152 //! \return Returns the name of the video driver. Example: In case of the DirectX8
\r
153 //! driver, it would return "Direct3D8.1".
\r
154 virtual const wchar_t* getName() const _IRR_OVERRIDE_;
\r
156 //! Returns type of video driver
\r
157 virtual E_DRIVER_TYPE getDriverType() const _IRR_OVERRIDE_;
\r
159 //! get color format of the current color buffer
\r
160 virtual ECOLOR_FORMAT getColorFormat() const _IRR_OVERRIDE_;
\r
162 //! Returns the transformation set by setTransform
\r
163 virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const _IRR_OVERRIDE_;
\r
165 //! Creates a render target texture.
\r
166 virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
\r
167 const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN
\r
168 #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
\r
169 , const bool useStencil = false
\r
174 virtual void clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil) _IRR_OVERRIDE_;
\r
176 //! Returns an image created from the last rendered frame.
\r
177 virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER) _IRR_OVERRIDE_;
\r
179 //! Returns the maximum amount of primitives (mostly vertices) which
\r
180 //! the device is able to render with one drawIndexedTriangleList
\r
182 virtual u32 getMaximalPrimitiveCount() const _IRR_OVERRIDE_;
\r
184 //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
\r
185 //! this: First, draw all geometry. Then use this method, to draw the shadow
\r
186 //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
\r
187 virtual void drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail=true, u32 debugDataVisible=0) _IRR_OVERRIDE_;
\r
189 //! Fills the stencil shadow with color. After the shadow volume has been drawn
\r
190 //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
\r
191 //! to draw the color of the shadow.
\r
192 virtual void drawStencilShadow(bool clearStencilBuffer=false,
\r
193 video::SColor leftUpEdge = video::SColor(0,0,0,0),
\r
194 video::SColor rightUpEdge = video::SColor(0,0,0,0),
\r
195 video::SColor leftDownEdge = video::SColor(0,0,0,0),
\r
196 video::SColor rightDownEdge = video::SColor(0,0,0,0)) _IRR_OVERRIDE_;
\r
198 //! Enable the 2d override material
\r
199 virtual void enableMaterial2D(bool enable = true) _IRR_OVERRIDE_;
\r
201 //! Returns the graphics card vendor name.
\r
202 virtual core::stringc getVendorInfo() _IRR_OVERRIDE_;
\r
204 //! Returns the maximum texture size supported.
\r
205 virtual core::dimension2du getMaxTextureSize() const _IRR_OVERRIDE_;
\r
207 //! Check if the driver supports creating textures with the given color format
\r
208 virtual bool queryTextureFormat(ECOLOR_FORMAT format) const _IRR_OVERRIDE_;
\r
210 #if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
\r
211 //! Used by some SceneNodes to check if a material should be rendered in the transparent render pass
\r
212 virtual bool needsTransparentRenderPass(const irr::video::SMaterial& material) const _IRR_OVERRIDE_;
\r
215 IDepthBuffer * getDepthBuffer () { return DepthBuffer; }
\r
216 IStencilBuffer * getStencilBuffer () { return StencilBuffer; }
\r
218 //! Adds a new material renderer to the VideoDriver, using pixel and/or
\r
219 //! vertex shaders to render geometry.
\r
220 virtual s32 addShaderMaterial(const c8* vertexShaderProgram,
\r
221 const c8* pixelShaderProgram,
\r
222 IShaderConstantSetCallBack* callback,
\r
223 E_MATERIAL_TYPE baseMaterial,
\r
224 s32 userData) _IRR_OVERRIDE_;
\r
226 //! Adds a new material renderer to the VideoDriver, based on a high level shading
\r
227 //! language. Currently only HLSL in D3D9 is supported.
\r
228 virtual s32 addHighLevelShaderMaterial(
\r
229 const c8* vertexShaderProgram,
\r
230 const c8* vertexShaderEntryPointName = 0,
\r
231 E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
\r
232 const c8* pixelShaderProgram = 0,
\r
233 const c8* pixelShaderEntryPointName = 0,
\r
234 E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
\r
235 const c8* geometryShaderProgram = 0,
\r
236 const c8* geometryShaderEntryPointName = "main",
\r
237 E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
\r
238 scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
\r
239 scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
\r
240 u32 verticesOut = 0,
\r
241 IShaderConstantSetCallBack* callback = 0,
\r
242 E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
\r
244 #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
\r
245 , E_GPU_SHADING_LANGUAGE shadingLang = EGSL_DEFAULT
\r
249 //IMaterialRendererService
\r
251 virtual void setBasicRenderStates(const SMaterial& material,
\r
252 const SMaterial& lastMaterial,
\r
253 bool resetAllRenderstates) _IRR_OVERRIDE_;
\r
255 //pass BaseMaterialID
\r
256 void setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType);
\r
258 //! Return an index constant for the vertex shader based on a name.
\r
259 virtual s32 getVertexShaderConstantID(const c8* name) _IRR_OVERRIDE_;
\r
260 virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;
\r
261 virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;
\r
262 virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
\r
263 virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;
\r
265 //! Return an index constant for the pixel shader based on a name.
\r
266 virtual s32 getPixelShaderConstantID(const c8* name) _IRR_OVERRIDE_;
\r
267 virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;
\r
268 virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;
\r
269 virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
\r
271 virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;
\r
273 #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
\r
274 virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count)
\r
276 return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count);
\r
278 virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count)
\r
280 return setVertexShaderConstant(getVertexShaderConstantID(name), (const s32*)bools, count);
\r
282 virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count)
\r
284 return setVertexShaderConstant(getVertexShaderConstantID(name), ints, count);
\r
287 virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count)
\r
289 return setPixelShaderConstant(getPixelShaderConstantID(name), floats, count);
\r
291 virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count)
\r
293 return setPixelShaderConstant(getPixelShaderConstantID(name), (const s32*)bools, count);
\r
295 virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count)
\r
297 return setPixelShaderConstant(getPixelShaderConstantID(name), ints, count);
\r
300 //! Get pointer to the IVideoDriver interface
\r
301 /** \return Pointer to the IVideoDriver interface */
\r
302 virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;
\r
308 //! sets a render target
\r
309 void setRenderTargetImage2(video::IImage* color, video::IImage* depth=0, video::IImage* stencil=0);
\r
311 //! sets the current Texture
\r
312 //bool setTexture(u32 stage, video::ITexture* texture);
\r
314 virtual ITexture* createDeviceDependentTexture(const io::path& name, IImage* image) _IRR_OVERRIDE_;
\r
315 virtual ITexture* createDeviceDependentTextureCubemap(const io::path& name, const core::array<IImage*>& image) _IRR_OVERRIDE_;
\r
317 video::CImage* BackBuffer;
\r
318 video::IImagePresenter* Presenter;
\r
321 core::rect<s32>* SceneSourceRect;
\r
323 video::ITexture* RenderTargetTexture;
\r
324 video::IImage* RenderTargetSurface;
\r
325 core::dimension2d<u32> RenderTargetSize;
\r
326 sVec4 RatioRenderTargetScreen; // Smaller Render Target
\r
328 IBurningShader* CurrentShader;
\r
329 IBurningShader* BurningShader[ETR2_COUNT];
\r
331 IDepthBuffer* DepthBuffer;
\r
332 IStencilBuffer* StencilBuffer;
\r
336 extend Matrix Stack
\r
337 -> combined CameraProjection
\r
338 -> combined CameraProjectionWorld
\r
339 -> ClipScale from NDC to DC Space
\r
341 enum E_TRANSFORMATION_STATE_BURNING_VIDEO
\r
343 ETS_VIEW_PROJECTION = ETS_COUNT,
\r
344 ETS_PROJ_MODEL_VIEW,
\r
346 ETS_NORMAL, //3x3 ModelView Tansposed Inverse
\r
348 ETS_COUNT_BURNING = 16
\r
351 // align manually to 16 byte start address
\r
353 enum E_TRANSFORMATION_FLAG
\r
357 ETF_TEXGEN_CAMERA_SPHERE = 4,
\r
358 ETF_TEXGEN_CAMERA_REFLECTION = 8,
\r
359 ETF_TEXGEN_WRAP = 16,
\r
360 ETF_TEXGEN_MASK = ETF_TEXGEN_CAMERA_SPHERE | ETF_TEXGEN_CAMERA_REFLECTION | ETF_TEXGEN_WRAP
\r
362 size_t TransformationStack; // 0 .. 3D , 1 .. 2D
\r
363 core::matrix4 ALIGN(16) Transformation[2][ETS_COUNT_BURNING];
\r
364 size_t TransformationFlag[2][ETS_COUNT_BURNING]; // E_TRANSFORMATION_FLAG
\r
367 void setRenderStates2DMode(const video::SColor& color,const video::ITexture* texture,bool useAlphaChannelOfTexture);
\r
368 void setRenderStates3DMode();
\r
370 //ETS_CLIPSCALE, // moved outside to stay at 16 matrices
\r
371 f32 Transformation_ETS_CLIPSCALE[2][4];
\r
372 void transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO state);
\r
374 //core::recti ViewPort;
\r
375 AbsRectangle Scissor;
\r
378 SVertexCache VertexCache;
\r
380 int VertexCache_reset (const void* vertices, u32 vertexCount,
\r
381 const void* indices, u32 indexCount,
\r
382 E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType,
\r
383 E_INDEX_TYPE iType);
\r
384 void VertexCache_get (s4DVertexPair* face[4] );
\r
386 void VertexCache_map_source_format();
\r
387 void VertexCache_fill ( const u32 sourceIndex,const u32 destIndex );
\r
388 s4DVertexPair* VertexCache_getVertex ( const u32 sourceIndex ) const;
\r
391 // culling & clipping
\r
392 //size_t inline clipToHyperPlane (s4DVertexPair* burning_restrict dest, const s4DVertexPair* burning_restrict source, const size_t inCount, const sVec4 &plane );
\r
393 //size_t inline clipToFrustumTest ( const s4DVertex * v ) const;
\r
395 size_t clipToFrustum( const size_t vIn /*, const size_t clipmask_for_face*/ );
\r
398 // holds transformed, clipped vertices for a triangle. triangle expands on clipping
\r
399 // Buffer is in in pairs of 4DVertex (0 ... ndc, 1 .. dc and projected)
\r
400 SAligned4DVertex Clipper;
\r
401 SAligned4DVertex Clipper_temp;
\r
404 #ifdef SOFTWARE_DRIVER_2_LIGHTING
\r
405 void lightVertex_eye ( s4DVertex *dest, u32 vertexargb );
\r
408 //! Sets the fog mode.
\r
409 virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start,
\r
410 f32 end, f32 density, bool pixelFog, bool rangeFog) _IRR_OVERRIDE_;
\r
413 void ndc_2_dc_and_project (s4DVertexPair* dest,const s4DVertexPair* source, const size_t vIn ) const;
\r
415 //const is misleading. **v is const that true, but not *v..
\r
416 f32 screenarea_inside (const s4DVertexPair* burning_restrict const face[] ) const;
\r
417 s32 lodFactor_inside ( const s4DVertexPair* burning_restrict const face[], const size_t tex, const f32 dc_area, const f32 lod_bias ) const;
\r
418 void select_polygon_mipmap_inside ( s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b ) const;
\r
420 void getCameraPosWorldSpace();
\r
421 SBurningShaderEyeSpace EyeSpace;
\r
422 SBurningShaderMaterial Material;
\r
424 static const sVec4 NDCPlane[6+2];
\r
426 //! Built-in 2D quad for 2D rendering.
\r
427 S3DVertex Quad2DVertices[4];
\r
428 interlaced_control Interlaced;
\r
430 #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
\r
431 core::array<IRenderTarget*> RenderTargets;
\r
433 inline bool getWriteZBuffer(const SMaterial& material) const
\r
435 return material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent());
\r
437 virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData = 0)
\r
439 return createDeviceDependentTexture(name, surface);
\r
445 } // end namespace video
\r
446 } // end namespace irr
\r