Added speedometer.

NOTE: to use the speedometer, a patched version of irrlicht is needed. The replacement
files are included here, we hope that the necessary functions will be included in the
next irrlicht release (STK will still compile without a patched irrlicht version,
but not display the speedometer).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3781 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2009-07-27 11:56:09 +00:00
parent 987e230ca0
commit 368604f379
17 changed files with 4835 additions and 111 deletions

View File

@ -0,0 +1,13 @@
The files in this directory should replace the corresponding
files in an irrlicht-1.5 distribution. They add a new function
draw2DPolygon (with different parameters than the existing
function with the same name). The new function is used to
draw the speedometer, and the track display with the kart
symbols on it.
If an unpatched version of irrlicht is used, STK will still
compile, but the above mentioned elements will be missing.
We hope that this function (or a similar one) will be
included in the next irrlicht release, making the use of
a patched version unnecessary.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,432 @@
// Copyright (C) 2002-2008 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in Irrlicht.h
#ifndef __C_VIDEO_OPEN_GL_H_INCLUDED__
#define __C_VIDEO_OPEN_GL_H_INCLUDED__
#include "IrrCompileConfig.h"
#if defined(_IRR_WINDOWS_API_)
// include windows headers for HWND
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#elif defined(_IRR_USE_OSX_DEVICE_)
#include "CIrrDeviceMacOSX.h"
#endif
#include "SIrrCreationParameters.h"
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "CNullDriver.h"
#include "IMaterialRendererServices.h"
#include "COpenGLExtensionHandler.h"
#if defined(_IRR_WINDOWS_API_)
#include <GL/gl.h>
#include "glext.h"
#include "wglext.h"
#ifdef _MSC_VER
#pragma comment(lib, "OpenGL32.lib")
#pragma comment(lib, "GLu32.lib")
#endif
#elif defined(_IRR_USE_OSX_DEVICE_)
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#endif
#include <OpenGL/gl.h>
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#include "glext.h"
#endif
#elif defined(_IRR_USE_SDL_DEVICE_)
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#define GLX_GLXEXT_LEGACY 1
#else
#define GL_GLEXT_PROTOTYPES 1
#define GLX_GLXEXT_PROTOTYPES 1
#endif
#define NO_SDL_GLEXT
#include <SDL/SDL_opengl.h>
#include "glext.h"
#else
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#define GL_GLEXT_LEGACY 1
#define GLX_GLXEXT_LEGACY 1
#else
#define GL_GLEXT_PROTOTYPES 1
#define GLX_GLXEXT_PROTOTYPES 1
#endif
#include <GL/gl.h>
#include <GL/glx.h>
#if defined(_IRR_OPENGL_USE_EXTPOINTER_)
#include "glext.h"
#undef GLX_ARB_get_proc_address // avoid problems with local glxext.h
#include "glxext.h"
#endif
#endif
namespace irr
{
namespace video
{
class COpenGLTexture;
class COpenGLDriver : public CNullDriver, public IMaterialRendererServices, public COpenGLExtensionHandler
{
public:
#if defined(_IRR_WINDOWS_API_) || defined(_IRR_USE_LINUX_DEVICE_) || defined(_IRR_USE_SDL_DEVICE_)
COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io);
#endif
#ifdef _IRR_USE_OSX_DEVICE_
COpenGLDriver(const SIrrlichtCreationParameters& params,
io::IFileSystem* io, CIrrDeviceMacOSX *device);
#endif
#ifdef _IRR_WINDOWS_API_
//! inits the windows specific parts of the open gl driver
bool initDriver(SIrrlichtCreationParameters params);
#endif
//! destructor
virtual ~COpenGLDriver();
//! clears the zbuffer
virtual bool beginScene(bool backBuffer=true, bool zBuffer=true,
SColor color=SColor(255,0,0,0),
void* windowId=0,
core::rect<s32>* sourceRect=0);
//! presents the rendered scene on the screen, returns false if failed
virtual bool endScene();
//! sets transformation
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
GLuint vbo_verticesSize; //tmp
GLuint vbo_indicesSize; //tmp
};
bool updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer);
bool 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
virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
const void* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType);
//! queries the features of the driver, returns true if feature is available
virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
{
return FeatureEnabled[feature] && COpenGLExtensionHandler::queryFeature(feature);
}
//! Sets a material. All 3d drawing functions draw geometry now
//! using this material.
//! \param material: Material to be used from now on.
virtual void setMaterial(const SMaterial& material);
//! 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,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false);
//! draws a set of 2d images, using a color and the alpha
/** channel of the texture if desired. The images are drawn
beginning at pos and concatenated in one line. All drawings
are clipped against clipRect (if != 0).
The subtextures are defined by the array of sourceRects
and are chosen by the indices given.
\param texture: Texture to be drawn.
\param pos: Upper left 2d destination position where the image will be drawn.
\param sourceRects: Source rectangles of the image.
\param indices: List of indices which choose the actual rectangle used each time.
\param clipRect: Pointer to rectangle on the screen where the image is clipped to.
This pointer can be 0. Then the image is not clipped.
\param color: Color with which the image is colored.
Note that the alpha component is used: If alpha is other than 255, the image will be transparent.
\param useAlphaChannelOfTexture: If true, the alpha channel of the texture is
used to draw the image. */
virtual void draw2DImage(const video::ITexture* texture,
const core::position2d<s32>& pos,
const core::array<core::rect<s32> >& sourceRects,
const core::array<s32>& indices,
const core::rect<s32>* clipRect=0,
SColor color=SColor(255,255,255,255),
bool useAlphaChannelOfTexture=false);
//! Draws a part of the texture into the rectangle.
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false);
//! draw an 2d rectangle
virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,
const core::rect<s32>* clip = 0);
//!Draws an 2d rectangle with a gradient.
virtual void draw2DRectangle(const core::rect<s32>& pos,
SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
const core::rect<s32>* clip = 0);
//!Draws a 2d polygon with optional colors per vertex and a texture.
virtual void draw2DPolygon(const core::array<core::vector2df> &vertices,
const core::array<video::SColor> *colors=NULL,
const video::ITexture *texture=NULL,
bool useAlphaChannelOfTexture=false,
const core::array<core::vector2di> *coordinates=NULL);
//! Draws a 2d line.
virtual void draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end,
SColor color=SColor(255,255,255,255));
//! Draws a single pixel
virtual void drawPixel(u32 x, u32 y, const SColor & color);
//! Draws a 3d line.
virtual void draw3DLine(const core::vector3df& start,
const core::vector3df& end,
SColor color = SColor(255,255,255,255));
//! \return Returns the name of the video driver. Example: In case of the Direct3D8
//! driver, it would return "Direct3D8.1".
virtual const wchar_t* getName() const;
//! deletes all dynamic lights there are
virtual void deleteAllDynamicLights();
//! adds a dynamic light
virtual void addDynamicLight(const SLight& light);
//! returns the maximal amount of dynamic lights the device can handle
virtual u32 getMaximalDynamicLightAmount() const;
//! Sets the dynamic ambient light color. The default color is
//! (0,0,0,0) which means it is dark.
//! \param color: New color of the ambient light.
virtual void setAmbientLight(const SColorf& color);
//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
//! this: First, draw all geometry. Then use this method, to draw the shadow
//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
virtual void drawStencilShadowVolume(const core::vector3df* triangles, s32 count, bool zfail);
//! Fills the stencil shadow with color. After the shadow volume has been drawn
//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
//! to draw the color of the shadow.
virtual void drawStencilShadow(bool clearStencilBuffer=false,
video::SColor leftUpEdge = 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 rightDownEdge = video::SColor(0,0,0,0));
//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area);
//! Sets the fog mode.
virtual void setFog(SColor color, bool linearFog, f32 start,
f32 end, f32 density, bool pixelFog, bool rangeFog);
//! Only used by the internal engine. Used to notify the driver that
//! the window was resized.
virtual void OnResize(const core::dimension2d<s32>& size);
//! Returns type of video driver
virtual E_DRIVER_TYPE getDriverType() const;
//! get color format of the current color buffer
virtual ECOLOR_FORMAT getColorFormat() const;
//! Returns the transformation set by setTransform
virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const;
//! Can be called by an IMaterialRenderer to make its work easier.
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
bool resetAllRenderstates);
//! Sets a vertex shader constant.
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1);
//! Sets a pixel shader constant.
virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1);
//! Sets a constant for the vertex shader based on a name.
virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count);
//! Sets a constant for the pixel shader based on a name.
virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count);
//! sets the current Texture
//! Returns whether setting was a success or not.
bool setTexture(u32 stage, const video::ITexture* texture);
//! disables all textures beginning with the optional fromStage parameter. Otherwise all texture stages are disabled.
//! Returns whether disabling was successful or not.
bool disableTextures(u32 fromStage=0);
//! Adds a new material renderer to the VideoDriver, using
//! extGLGetObjectParameteriv(shaderHandle, GL_OBJECT_COMPILE_STATUS_ARB, &status)
//! pixel and/or vertex shaders to render geometry.
virtual s32 addShaderMaterial(const c8* vertexShaderProgram, const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial, s32 userData);
//! Adds a new material renderer to the VideoDriver, using GLSL to render geometry.
virtual s32 addHighLevelShaderMaterial(const c8* vertexShaderProgram, const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget, const c8* pixelShaderProgram, const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget, IShaderConstantSetCallBack* callback, E_MATERIAL_TYPE baseMaterial,
s32 userData);
//! Returns pointer to the IGPUProgrammingServices interface.
virtual IGPUProgrammingServices* getGPUProgrammingServices();
//! Returns a pointer to the IVideoDriver interface. (Implementation for
//! IMaterialRendererServices)
virtual IVideoDriver* getVideoDriver();
//! Returns the maximum amount of primitives (mostly vertices) which
//! the device is able to render with one drawIndexedTriangleList
//! call.
virtual u32 getMaximalPrimitiveCount() const;
virtual ITexture* addRenderTargetTexture(const core::dimension2d<s32>& size,
const c8* name);
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color);
//! Clears the ZBuffer.
virtual void clearZBuffer();
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot();
//! checks if an OpenGL error has happend and prints it
//! for performance reasons only available in debug mode
bool testGLError();
//! Set/unset a clipping plane.
//! There are at least 6 clipping planes available for the user to set at will.
//! \param index: The plane index. Must be between 0 and MaxUserClipPlanes.
//! \param plane: The plane itself.
//! \param enable: If true, enable the clipping plane else disable it.
virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable=false);
//! Enable/disable a clipping plane.
//! There are at least 6 clipping planes available for the user to set at will.
//! \param index: The plane index. Must be between 0 and MaxUserClipPlanes.
//! \param enable: If true, enable the clipping plane else disable it.
virtual void enableClipPlane(u32 index, bool enable);
//! Returns the graphics card vendor name.
virtual core::stringc getVendorInfo() {return vendorName;}
ITexture* createDepthTexture(ITexture* texture, bool shared=true);
void removeDepthTexture(ITexture* texture);
private:
void uploadClipPlane(u32 index);
//! inits the parts of the open gl driver used on all platforms
bool genericDriverInit(const core::dimension2d<s32>& screenSize, bool stencilBuffer);
//! returns a device dependent texture from a software surface (IImage)
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const char* name);
//! creates a transposed matrix in supplied GLfloat array to pass to OpenGL
inline void createGLMatrix(GLfloat gl_matrix[16], const core::matrix4& m);
inline void createGLTextureMatrix(GLfloat gl_matrix[16], const core::matrix4& m);
//! Set GL pipeline to desired texture wrap modes of the material
void setWrapMode(const SMaterial& material);
//! sets the needed renderstates
void setRenderStates3DMode();
//! sets the needed renderstates
void setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel);
// returns the current size of the screen or rendertarget
virtual const core::dimension2d<s32>& getCurrentRenderTargetSize() const;
void createMaterialRenderers();
core::stringw Name;
core::matrix4 Matrices[ETS_COUNT];
core::array<u8> ColorBuffer;
//! enumeration for rendering modes such as 2d and 3d for minizing the switching of renderStates.
enum E_RENDER_MODE
{
ERM_NONE = 0, // no render state has been set yet.
ERM_2D, // 2d drawing rendermode
ERM_3D // 3d rendering mode
};
E_RENDER_MODE CurrentRenderMode;
//! bool to make all renderstates reset if set to true.
bool ResetRenderStates;
bool Transformation3DChanged;
bool AntiAlias;
SMaterial Material, LastMaterial;
COpenGLTexture* RenderTargetTexture;
const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES];
core::array<ITexture*> DepthTextures;
s32 LastSetLight;
core::array<core::plane3df> UserClipPlane;
core::array<bool> UserClipPlaneEnabled;
core::dimension2d<s32> CurrentRendertargetSize;
core::stringc vendorName;
core::matrix4 TextureFlipMatrix;
//! Color buffer format
ECOLOR_FORMAT ColorFormat;
#ifdef _IRR_WINDOWS_API_
HDC HDc; // Private GDI Device Context
HWND Window;
HGLRC HRc; // Permanent Rendering Context
#elif defined(_IRR_USE_LINUX_DEVICE_)
GLXDrawable Drawable;
#elif defined(_IRR_USE_OSX_DEVICE_)
CIrrDeviceMacOSX *_device;
#endif
};
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_OPENGL_
#endif

View File

@ -440,6 +440,14 @@ void IrrDriver::removeMesh(scene::IMesh *mesh)
{
m_scene_manager->getMeshCache()->removeMesh(mesh);
} // removeMesh
// ----------------------------------------------------------------------------
/** Removes a texture from irrlicht's texture cache.
* \param t The texture to remove.
*/
void IrrDriver::removeTexture(video::ITexture *t)
{
m_video_driver->removeTexture(t);
} // removeTexture
// ----------------------------------------------------------------------------
/** Adds an animated mesh to the scene.
@ -450,6 +458,7 @@ scene::IAnimatedMeshSceneNode *IrrDriver::addAnimatedMesh(scene::IAnimatedMesh *
return m_scene_manager->addAnimatedMeshSceneNode(mesh);
} // addAnimatedMesh
// ----------------------------------------------------------------------------
/** Adds a sky dome. Documentation from irrlicht:
* A skydome is a large (half-) sphere with a panoramic texture on the inside

View File

@ -94,6 +94,7 @@ public:
scene::ISceneNode *addSkyBox(const std::vector<std::string> &texture_names);
void removeNode(scene::ISceneNode *node);
void removeMesh(scene::IMesh *mesh);
void removeTexture(video::ITexture *t);
scene::IAnimatedMeshSceneNode
*addAnimatedMesh(scene::IAnimatedMesh *mesh);
scene::ICameraSceneNode
@ -110,6 +111,12 @@ public:
void beginRenderToTexture(const core::dimension2di &dimension,
const std::string &name);
video::ITexture *endRenderToTexture();
void draw2dTriangle(const core::vector2df &a, const core::vector2df &b,
const core::vector2df &c,
const video::ITexture *texture = NULL,
const video::SColor *ca=NULL, const video::SColor *cb=NULL,
const video::SColor *cc=NULL);
}; // IrrDriver
extern IrrDriver *irr_driver;

View File

@ -202,6 +202,28 @@ int XMLNode::get(const std::string &attribute, Vec3 *value) const
return 1;
} // get(Vec3)
// ----------------------------------------------------------------------------
int XMLNode::get(const std::string &attribute, video::SColor *color) const
{
std::string s;
if(!get(attribute, &s)) return 0;
std::vector<std::string> v = StringUtils::split(s,' ');
if(v.size()<3 || v.size()>4) return 0;
if(v.size()==3)
{
color->setRed (atoi(v[0].c_str()));
color->setGreen(atoi(v[1].c_str()));
color->setBlue (atoi(v[2].c_str()));
}
else
color->set(atoi(v[0].c_str()),
atoi(v[1].c_str()),
atoi(v[2].c_str()),
atoi(v[3].c_str()));
return 1;
} // get(SColor)
// ----------------------------------------------------------------------------
int XMLNode::get(const std::string &attribute, video::SColorf *color) const
{

View File

@ -56,6 +56,7 @@ public:
int get(const std::string &attribute, core::vector2df *value) const;
int get(const std::string &attribute, core::vector3df *value) const;
int get(const std::string &attribute, video::SColorf *value) const;
int get(const std::string &attribute, video::SColor *value) const;
int get(const std::string &attribute, std::vector<std::string> *value) const;
int get(const std::string &attribute, std::vector<float> *value) const;
int get(const std::string &attribute, std::vector<int> *value) const;

View File

@ -196,7 +196,7 @@ public:
// Functions to access the current kart properties (which might get changed,
// e.g. mass increase or air_friction increase depending on attachment etc.)
// -------------------------------------------------------------------------
const Vec3 &getColor () const {return m_kart_properties->getColor();}
const video::SColor &getColor () const {return m_kart_properties->getColor();}
float getMass () const
{
return m_kart_properties->getMass()

View File

@ -69,8 +69,9 @@ KartProperties::KartProperties() : m_icon_material(0)
m_gravity_center_shift = Vec3(UNDEFINED);
m_has_skidmarks = true;
m_version = 0;
m_color.setValue(1.0f, 0.0f, 0.0f);
m_engine_sfx_type = SFXManager::SOUND_ENGINE_SMALL;
m_color = video::SColor(255, 0, 0, 0);
m_shape = 32; // close enough to a circle.
m_engine_sfx_type = SFXManager::SOUND_ENGINE_SMALL;
} // KartProperties
//-----------------------------------------------------------------------------
@ -183,8 +184,9 @@ void KartProperties::getAllData(const lisp::Lisp* lisp)
lisp->get("name", m_name);
lisp->get("icon-file", m_icon_file);
lisp->get("shadow-file", m_shadow_file);
lisp->get("rgb", m_color);
Vec3 c;
lisp->get("rgb", c);
m_color.set(255, (int)(255*c.getX()), (int)(255*c.getY()), (int)(255*c.getZ()));
lisp->get("engine-power", m_engine_power, 3);
lisp->get("time-full-steer", m_time_full_steer);
lisp->get("time-full-steer-ai", m_time_full_steer_ai);

View File

@ -23,6 +23,9 @@
#include <string>
#include <vector>
#include "irrlicht.h"
using namespace irr;
#include "audio/sfx_manager.hpp"
#include "karts/kart_model.hpp"
#include "lisp/lisp.hpp"
@ -30,7 +33,6 @@
#include "utils/vec3.hpp"
class Material;
class ssgEntity;
/** This class stores the properties of a kart. This includes size, name,
* identifier, physical properties etc. It is atm also the base class for
@ -62,9 +64,10 @@ private:
* character select screen. */
std::string m_shadow_file; /**< Filename of the image file that
* contains the shadow for this kart.*/
Vec3 m_color; /**< Color the represents the kart in the
video::SColor m_color; /**< Color the represents the kart in the
* status bar and on the track-view. */
int m_shape; /**< Number of vertices in polygon when
* drawing the dot on the mini map. */
// Physic properties
// -----------------
float m_mass; /**< Weight of kart. */
@ -88,14 +91,9 @@ private:
kart length. */
m_max_radius; /**< Largest turn radius. */
//ssgEntity *m_wheel_model[4]; /**< The four wheel models. */
std::string m_wheel_filename[4]; /**< Filename of the wheel models. */
/** Radius of the graphical wheels. */
float m_wheel_graphics_radius[4];
//ssgTransform
// *m_wheel_transform[4]; /**< The transform for the wheels, used
// * to rotate the wheels and display
// * the suspension in the race. */
float m_rubber_band_max_length;/**< Max. length of plunger rubber band.*/
float m_rubber_band_force; /**< Force of an attached rubber band.*/
float m_rubber_band_duration;/**< Duration a rubber band works. */
@ -173,7 +171,11 @@ public:
const std::string& getIconFile () const {return m_icon_file; }
/** Returns the version of the .kart file. */
int getVersion () const {return m_version; }
const Vec3 &getColor () const {return m_color; }
/** Returns the dot color to use for this kart in the race gui. */
const video::SColor &getColor () const {return m_color; }
/** Returns the number of edges for the polygon used to draw the dot of
* this kart on the mini map of the race gui. */
int getShape () const {return m_shape; }
const std::vector<std::string>&
getGroups () const {return m_groups; }
float getMass () const {return m_mass; }

View File

@ -17,8 +17,8 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_KARTPROPERTIESMANAGER_HPP
#define HEADER_KARTPROPERTIESMANAGER_HPP
#ifndef HEADER_KART_PROPERTIES_MANAGER_HPP
#define HEADER_KART_PROPERTIES_MANAGER_HPP
#include <vector>
#include <map>

View File

@ -253,6 +253,7 @@ int handleCmdLine(int argc, char **argv)
std::string filename=file_manager->getKartFile(std::string(argv[i+1])+".tkkf");
if(filename!="")
{
race_manager->setNumLocalPlayers(1);
race_manager->setLocalKartInfo(0, argv[i+1]);
fprintf ( stdout, "You choose to use kart '%s'.\n", argv[i+1] ) ;
}

View File

@ -73,7 +73,11 @@ void World::init()
TimedRace::setClockMode( CHRONO );
m_use_highscores = true;
// Create the race gui before anything else is attached to the scene node.
// This allows the race gui to do any rendering on texture.
m_race_gui = new RaceGUI();
// Grab the track file
try
{
@ -158,8 +162,6 @@ void World::init()
// of karts.
m_track->reset();
m_race_gui = new RaceGUI();
m_track->startMusic();
if(!history->replayHistory()) history->initRecording();

View File

@ -20,23 +20,26 @@
#include "states_screens/race_gui.hpp"
#include "irrlicht.h"
using namespace irr;
#include "audio/sound_manager.hpp"
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material_manager.hpp"
#include "input/input.hpp"
#include "input/input_manager.hpp"
#include "karts/kart_properties_manager.hpp"
#include "race/race_manager.hpp"
#include "tracks/track.hpp"
#include "utils/constants.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include "irrlicht.h"
using namespace irr;
const video::SColor white(255,255,255,255);
/** The constructor is called before anything is attached to the scene node.
* So rendering to a texture can be done here. But world is not yet fully
* created, so only the race manager can be accessed safely.
*/
RaceGUI::RaceGUI()
{
// FIXME: translation problem
@ -52,8 +55,6 @@ RaceGUI::RaceGUI()
m_pos_string[9] = "9th";
m_pos_string[10] = "10th";
gui::IGUIEnvironment *gui_env = irr_driver->getGUI();
int icon_width=40;
int icon_player_width=50;
if(UserConfigParams::m_height<600)
@ -62,18 +63,76 @@ RaceGUI::RaceGUI()
icon_player_width = 35;
}
m_speed_back_icon = material_manager->getMaterial("speedback.png");
m_speed_fore_icon = material_manager->getMaterial("speedfore.png");
m_plunger_face = material_manager->getMaterial("plungerface.png");
m_speed_meter_icon = material_manager->getMaterial("speedback.png");
m_speed_bar_icon = material_manager->getMaterial("speedfore.png");
m_plunger_face = material_manager->getMaterial("plungerface.png");
createMarkerTexture();
} // RaceGUI
//-----------------------------------------------------------------------------
RaceGUI::~RaceGUI()
{
//FIXME: does all that material stuff need freeing somehow?
irr_driver->removeTexture(m_marker);
} // ~Racegui
//-----------------------------------------------------------------------------
/** Creates a texture with the markers for all karts in the current race
* on it. This assumes that nothing is attached to the scene node at
* this stage.
*/
void RaceGUI::createMarkerTexture()
{
unsigned int n=race_manager->getNumKarts();
unsigned int npower2 = 1;
// Textures must be power of 2, so
while(npower2<n) npower2*=2;
int marker_size = 64; // must be a power of 2
int radius = (marker_size>>1)-1;
irr_driver->beginRenderToTexture(core::dimension2di(marker_size * npower2, marker_size),
"RaceGUI::markers");
for(unsigned int i=0; i<race_manager->getNumKarts(); i++)
{
const std::string& kart_name = race_manager->getKartName(i);
const KartProperties *kp = kart_properties_manager->getKart(kart_name);
core::vector2df center((float)((marker_size>>1)+i*marker_size),
(float)(marker_size>>1));
int count = kp->getShape();
core::array<core::vector2df> vertices;
createRegularPolygon(count, (float)radius, center,&vertices);
video::SColor color = kp->getColor();
core::array<video::SColor> colors;
colors.push_back(color);
#ifdef IRRLICHT_HAS_SUPERTUXKART_POLYGON
irr_driver->getVideoDriver()->draw2DPolygon(vertices, &colors);
#endif
}
m_marker = irr_driver->endRenderToTexture();
core::dimension2di X = m_marker->getOriginalSize();
} // createMarkerTexture
//-----------------------------------------------------------------------------
/** Creates the 2D vertices for a regular polygon. Adopted from Irrlicht.
* \param n Number of vertices to use.
* \param radius Radius of the polygon.
* \param center The center point of the polygon.
* \param v Pointer to the array of vertices.
*/
void RaceGUI::createRegularPolygon(unsigned int n, float radius,
const core::vector2df &center,
core::array<core::vector2df> *v)
{
float f = 2*M_PI/(float)n;
for (unsigned int i=0; i<n; i++)
{
float p = i*f;
core::vector2df X = center + core::vector2df(sin(p)*radius, -cos(p)*radius);
v->push_back(X);
}
} // createRegularPolygon
//-----------------------------------------------------------------------------
/** Called before rendering, so no direct output to the screen can be done
* here.
@ -114,16 +173,21 @@ void RaceGUI::drawTimer ()
//-----------------------------------------------------------------------------
#define TRACKVIEW_SIZE 100
void RaceGUI::drawMap ()
void RaceGUI::drawMap()
{
// arenas currently don't have a map.
if(RaceManager::getTrack()->isArena()) return;
const video::ITexture *t=RaceManager::getTrack()->getMiniMap();
const video::ITexture *mini_map=RaceManager::getTrack()->getMiniMap();
core::rect<s32> dest(10, UserConfigParams::m_height-60,
60, UserConfigParams::m_height-10);
core::rect<s32> source(core::position2di(0, 0), t->getOriginalSize());
irr_driver->getVideoDriver()->draw2DImage(t, dest, source, 0, 0, true);
core::rect<s32> source(core::position2di(0, 0), mini_map->getOriginalSize());
//FIXME irr_driver->getVideoDriver()->draw2DImage(mini_map, dest, source, 0, 0, true);
core::rect<s32> dest1( 10, UserConfigParams::m_height-10,
100, UserConfigParams::m_height-110);
core::rect<s32> source1(core::position2di(0, 0), m_marker->getOriginalSize());
irr_driver->getVideoDriver()->draw2DImage(m_marker, dest, source1, 0, 0, true);
return;
@ -140,7 +204,7 @@ void RaceGUI::drawMap ()
{
Kart* kart = RaceManager::getKart(i);
if(kart->isEliminated()) continue; // don't draw eliminated kart
glColor3fv ( kart->getColor().toFloat());
//glColor3fv ( kart->getColor().toFloat());
const Vec3& xyz = kart->getXYZ();
/* If it's a player, draw a bigger sign */
@ -216,6 +280,7 @@ void RaceGUI::drawPlayerIcons (const KartIconDisplayInfo* info)
int w = kart->isPlayerKart() ? ICON_PLAYER_WIDTH : ICON_WIDTH;
const core::rect<s32> pos(x, y, x+w, y+w);
const core::rect<s32> rect(core::position2d<s32>(0,0), icon->getOriginalSize());
static const video::SColor white(255, 255, 255, 255);
irr_driver->getVideoDriver()->draw2DImage(icon, pos, rect, 0,
&white, true);
@ -244,6 +309,7 @@ void RaceGUI::drawPowerupIcons(Kart* player_kart, int offset_x,
video::ITexture *t=powerup->getIcon()->getTexture();
core::rect<s32> rect(core::position2di(0, 0), t->getOriginalSize());
static const video::SColor white(255, 255, 255, 255);
for ( int i = 0 ; i < n ; i++ )
{
core::rect<s32> pos(x1+i*30, y1, x1+i*30+nSize, y1+nSize);
@ -272,30 +338,21 @@ void RaceGUI::drawEnergyMeter ( Kart *player_kart, int offset_x, int offset_y,
#define LINE(x0,y0,x1,y1, color) video->draw2DLine(core::position2di(x0,y0), \
core::position2di(x1,y1), color)
// FIXME: the original code drew a rectangle, i.e. two lines. This seems to be
// unnecesssary, so it's commented out here
// Left side:
LINE(x-1, y+1, x-1, y-h-1, black_border);
//LINE(x, y-1, x, y+h+1, black_border);
LINE(x, y, x, y-h-2, white_border);
//LINE(x+1, y, x+1, y+h+2, white_border);
// Right side:
LINE(x+w, y+1, x+w, y-h-1, black_border);
//LINE(x+w+1, y-1, x+w+1, y+h+1, black_border);
LINE(x+w+1, y, x+w+1, y-h-2, white_border);
//LINE(x+w+2, y, x+w+2, y+h+2, white_border);
// Bottom
LINE(x, y+1, x+w, y+1, black_border);
//LINE(x, y, x+w, y, black_border);
LINE(x+1, y, x+w+1, y, white_border);
//LINE(x+1, y+1, x+w+1, y+1, white_border);
// Top
LINE(x, y-h, x+w, y-h, black_border);
//LINE(x, y+h+1, x+w, y+h+1, black_border);
LINE(x, y-h-1, x+w, y-h-1, white_border);
//LINE(x, y+h+2, x+w, y+h+2, white_border);
const int GRADS = (int)(MAX_ITEMS_COLLECTED/5); // each graduation equals 5 items
int gh = (int)(h/GRADS); //graduation height
@ -327,21 +384,25 @@ void RaceGUI::drawSpeed(Kart* kart, int offset_x, int offset_y,
float ratio_x, float ratio_y )
{
float minRatio = std::min(ratio_x, ratio_y);
const int SPEEDWIDTH=128;
int width = (int)(SPEEDWIDTH*minRatio);
int height = (int)(SPEEDWIDTH*minRatio);
offset_x += (int)((UserConfigParams::m_width-10)*ratio_x) - width;
offset_y += (int)(10*ratio_y);
float minRatio = std::min(ratio_x, ratio_y);
const int SPEEDWIDTH = 128;
int meter_width = (int)(SPEEDWIDTH*minRatio);
int meter_height = (int)(SPEEDWIDTH*minRatio);
offset_x += (int)((UserConfigParams::m_width-10)*ratio_x) - meter_width;
offset_y += (int)(10*ratio_y);
// First draw the meter (i.e. the background which contains the numbers etc.
// -------------------------------------------------------------------------
video::IVideoDriver *video = irr_driver->getVideoDriver();
video::SColor color(255, 255, 255, 255);
const core::rect<s32> pos(offset_x, UserConfigParams::m_height-offset_y-height,
offset_x+width, UserConfigParams::m_height-offset_y);
video::ITexture *t = m_speed_back_icon->getTexture();
const core::rect<s32> rect(core::position2d<s32>(0,0), t->getOriginalSize());
video->draw2DImage(t, pos, rect, 0, &color, true);
const core::rect<s32> meter_pos(offset_x, UserConfigParams::m_height-offset_y-meter_height,
offset_x+meter_width, UserConfigParams::m_height-offset_y);
video::ITexture *meter_texture = m_speed_meter_icon->getTexture();
const core::rect<s32> meter_texture_coords(core::position2d<s32>(0,0),
meter_texture->getOriginalSize());
video->draw2DImage(meter_texture, meter_pos, meter_texture_coords, NULL, NULL, true);
// Indicate when the kart is off ground
// ------------------------------------
if ( !kart->isOnGround() )
{
static video::SColor color = video::SColor(255, 255, 255, 255);
@ -351,50 +412,48 @@ void RaceGUI::drawSpeed(Kart* kart, int offset_x, int offset_y,
UserConfigParams::m_height-(offset_y-(int)(10*minRatio)) );
irr_driver->getRaceFont()->draw(core::stringw("!").c_str(), pos, color);
}
const float speed = kart->getSpeed();
if(speed>0)
if(speed <=0) return; // Nothing to do if speed is negative.
// Draw the actual speed bar (if the speed is >0)
// ----------------------------------------------
float speed_ratio = speed/KILOMETERS_PER_HOUR/110.0f;
if(speed_ratio>1) speed_ratio = 1;
video::ITexture *bar_texture = m_speed_bar_icon->getTexture();
core::dimension2di bar_size = bar_texture->getOriginalSize();
core::array<core::vector2di> tex_coords; // texture coordinates
core::array<core::vector2df> bar_vertices; // screen coordinates
tex_coords.push_back(core::vector2di(bar_size.Width, bar_size.Height));
bar_vertices.push_back(core::vector2df((float)meter_pos.LowerRightCorner.X,
(float)meter_pos.LowerRightCorner.Y));
tex_coords.push_back(core::vector2di(0,bar_size.Height));
bar_vertices.push_back(core::vector2df((float)meter_pos.UpperLeftCorner.X,
(float)meter_pos.LowerRightCorner.Y));
if(speed_ratio<=0.5f)
{
float speed_ratio = speed/KILOMETERS_PER_HOUR/110.0f;
if(speed_ratio>1) speed_ratio = 1;
core::vector2di v0(0, bar_size.Height-(int)(2*(speed_ratio)*bar_size.Height));
tex_coords.push_back(v0);
bar_vertices.push_back(core::vector2df((float)meter_pos.UpperLeftCorner.X,
(float)meter_pos.LowerRightCorner.Y-speed_ratio*2*meter_height));
}
else
{
tex_coords.push_back(core::vector2di(0, 0));
bar_vertices.push_back(core::vector2df((float)offset_x,
(float)(UserConfigParams::m_height-offset_y-meter_height)));
core::rect<s32> pos;
video::ITexture *t = m_speed_fore_icon->getTexture();
core::dimension2di tex_coords=t->getOriginalSize();
if(speed_ratio<0.5f)
{
pos = core::rect<s32>(offset_x,
UserConfigParams::m_height-offset_y-height,
offset_x+width,
UserConfigParams::m_height-offset_y-(int)(height*(1-speed_ratio)));
tex_coords.set(tex_coords.Width, (int)(tex_coords.Height*speed_ratio));
}
else
{
pos = core::rect<s32>(offset_x,
UserConfigParams::m_height-offset_y-height,
(int)(offset_x+width*speed_ratio),
UserConfigParams::m_height-offset_y);
tex_coords.set((int)(tex_coords.Width*speed_ratio), tex_coords.Height);
}
const core::rect<s32> rect(core::position2d<s32>(0,0), tex_coords);
video->draw2DImage(t, pos, rect, 0, &color, true);
#ifdef XX
glTexCoord2f(1, 0);glVertex2i(offset_x+width, offset_y);
glTexCoord2f(0, 0);glVertex2i(offset_x, offset_y);
if (speedRatio < 0.5)
{
glTexCoord2f(0, speedRatio*2);glVertex2i(offset_x, (int)(offset_y+width*speedRatio*2));
}
else
{
glTexCoord2f(0, 1);glVertex2i(offset_x, offset_y+width);
glTexCoord2f((speedRatio-0.5f)*2, 1);glVertex2i((int)(offset_x+height*(speedRatio-0.5f)*2), offset_y+height);
}
glEnd () ;
core::vector2di v0((int)(2*(speed_ratio-0.5f)*bar_size.Width), 0);
tex_coords.push_back(v0);
bar_vertices.push_back(core::vector2df(offset_x+2*(speed_ratio-0.5f)*meter_width,
(float)(UserConfigParams::m_height-offset_y-meter_height)));
}
#ifdef IRRLICHT_HAS_SUPERTUXKART_POLYGON
irr_driver->getVideoDriver()->draw2DPolygon(bar_vertices, NULL, bar_texture, true, &tex_coords);
#endif
} // speed<0
} // drawSpeed
//-----------------------------------------------------------------------------
@ -503,7 +562,7 @@ void RaceGUI::drawMusicDescription()
const MusicInformation* mi=sound_manager->getCurrentMusic();
if(!mi) return;
int y=UserConfigParams::m_height-40;
static video::SColor white = video::SColor(255, 255, 255, 255);
static const video::SColor white = video::SColor(255, 255, 255, 255);
gui::IGUIFont* font = irr_driver->getRaceFont();
if(mi->getComposer()!="")
{
@ -645,8 +704,8 @@ void RaceGUI::drawStatusText()
split_screen_ratio_x, split_screen_ratio_y );
drawEnergyMeter (player_kart, offset_x, offset_y,
split_screen_ratio_x, split_screen_ratio_y );
//drawSpeed (player_kart, offset_x, offset_y,
// split_screen_ratio_x, split_screen_ratio_y );
drawSpeed (player_kart, offset_x, offset_y,
split_screen_ratio_x, split_screen_ratio_y );
drawLap (info, player_kart, offset_x, offset_y,
split_screen_ratio_x, split_screen_ratio_y );
drawAllMessages (player_kart, offset_x, offset_y,
@ -678,7 +737,7 @@ void RaceGUI::drawStatusText()
drawMusicDescription();
}
drawMap();
//drawMap();
drawPlayerIcons(info);
} // drawStatusText

View File

@ -84,13 +84,18 @@ private:
}
};
private:
const char *m_pos_string [11];
Material *m_speed_back_icon;
Material *m_speed_fore_icon;
Material *m_plunger_face;
typedef std::vector<TimedMessage> AllMessageType;
AllMessageType m_messages;
const char *m_pos_string [11];
Material *m_speed_meter_icon;
Material *m_speed_bar_icon;
Material *m_plunger_face;
typedef std::vector<TimedMessage> AllMessageType;
AllMessageType m_messages;
video::ITexture *m_marker;
void createMarkerTexture();
void createRegularPolygon(unsigned int n, float radius,
const core::vector2df &center,
core::array<core::vector2df> *v);
/* Display informat on screen */
void drawStatusText ();

View File

@ -406,6 +406,11 @@ video::ITexture *QuadGraph::makeMiniMap(const core::dimension2di &dimension,
const video::SColor &fill_color)
{
irr_driver->beginRenderToTexture(dimension, name);
for(unsigned int i=0; i<m_all_quads->getNumberOfQuads(); i++)
{
// core::array<core::vector2df> vertices;
// vertices.push_back(core::vertices
}
createMesh();
video::S3DVertex *v = (video::S3DVertex*)m_mesh_buffer->getVertices();
for(unsigned int i=0; i<m_mesh_buffer->getVertexCount(); i++)