Merge branch 'master' of github.com:supertuxkart/stk-code
This commit is contained in:
commit
2c80feb3b5
@ -44,7 +44,7 @@
|
||||
title="Unstoppable" description="Win 5 single races in a row.">
|
||||
<wins goal="5"/>
|
||||
</achievement>
|
||||
<achievement id="9" check-type="all-at-least" reset-after-race="yes"
|
||||
<achievement id="9" check-type="all-at-least" reset-type="race"
|
||||
title="Banana Lover" description="Collect at least 5 bananas in one race.">
|
||||
<banana goal="5"/>
|
||||
</achievement>
|
||||
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 161 KiB |
@ -15,7 +15,10 @@
|
||||
child_height="120" keep_selection="true" />
|
||||
</box>
|
||||
|
||||
<spacer height="10" />
|
||||
<!-- Populated dynamically at runtime -->
|
||||
<tabs width="100%" height="30" id="gpgroups"> </tabs>
|
||||
|
||||
<spacer height="20" />
|
||||
|
||||
<box proportion="2" width="100%" layout="vertical-row">
|
||||
<label id="gpname" text_align="center" width="100%"
|
||||
|
@ -5,7 +5,7 @@ uniform sampler2D Detail;
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
flat in sampler2D secondhandle;
|
||||
flat in sampler2D thirdhandle;
|
||||
#endif
|
||||
in vec2 uv;
|
||||
in vec2 uv_bis;
|
||||
@ -20,7 +20,7 @@ void main(void)
|
||||
#ifdef SRGBBindlessFix
|
||||
color.xyz = pow(color.xyz, vec3(2.2));
|
||||
#endif
|
||||
vec4 detail = texture(secondhandle, uv_bis);
|
||||
vec4 detail = texture(thirdhandle, uv_bis);
|
||||
#else
|
||||
vec4 color = texture(Albedo, uv);
|
||||
vec4 detail = texture(Detail, uv_bis);
|
||||
|
@ -1,11 +1,11 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D normalMap;
|
||||
uniform sampler2D DiffuseForAlpha;
|
||||
uniform sampler2D glossMap;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
flat in sampler2D secondhandle;
|
||||
flat in sampler2D thirdhandle;
|
||||
#endif
|
||||
in vec3 tangent;
|
||||
in vec3 bitangent;
|
||||
@ -18,11 +18,11 @@ void main()
|
||||
{
|
||||
// normal in Tangent Space
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec3 TS_normal = 2.0 * texture(secondhandle, uv).rgb - 1.0;
|
||||
float alpha = texture(handle, uv).a;
|
||||
vec3 TS_normal = 2.0 * texture(thirdhandle, uv).rgb - 1.0;
|
||||
float gloss = texture(secondhandle, uv).x;
|
||||
#else
|
||||
vec3 TS_normal = 2.0 * texture(normalMap, uv).rgb - 1.0;
|
||||
float alpha = texture(DiffuseForAlpha, uv).a;
|
||||
float gloss = texture(glossMap, uv).x;
|
||||
#endif
|
||||
// Because of interpolation, we need to renormalize
|
||||
vec3 Frag_tangent = normalize(tangent);
|
||||
@ -31,5 +31,5 @@ void main()
|
||||
|
||||
vec3 FragmentNormal = TS_normal.x * Frag_tangent + TS_normal.y * Frag_bitangent - TS_normal.z * Frag_normal;
|
||||
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(FragmentNormal)) + 0.5;
|
||||
EncodedNormal.z = exp2(10. * (1. - alpha) + 1.);
|
||||
EncodedNormal.z = exp2(10. * gloss + 1.);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ layout(location = 9) in vec3 Scale;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(location = 10) in sampler2D Handle;
|
||||
layout(location = 11) in sampler2D SecondHandle;
|
||||
layout(location = 13) in sampler2D ThirdHandle;
|
||||
#endif
|
||||
|
||||
#else
|
||||
@ -37,6 +38,7 @@ out vec4 color;
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat out sampler2D handle;
|
||||
flat out sampler2D secondhandle;
|
||||
flat out sampler2D thirdhandle;
|
||||
#endif
|
||||
|
||||
mat4 getWorldMatrix(vec3 translation, vec3 rotation, vec3 scale);
|
||||
@ -56,5 +58,6 @@ void main(void)
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
handle = Handle;
|
||||
secondhandle = SecondHandle;
|
||||
thirdhandle = ThirdHandle;
|
||||
#endif
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D glosstex;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
flat in sampler2D secondhandle;
|
||||
#endif
|
||||
in vec3 nor;
|
||||
in vec2 uv;
|
||||
@ -14,10 +14,10 @@ vec2 EncodeNormal(vec3 n);
|
||||
void main(void)
|
||||
{
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 col = texture(handle, uv);
|
||||
float glossmap = texture(secondhandle, uv).x;
|
||||
#else
|
||||
vec4 col = texture(tex, uv);
|
||||
float glossmap = texture(glosstex, uv).x;
|
||||
#endif
|
||||
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
|
||||
EncodedNormal.z = exp2(10. * (1. - col.a) + 1.);
|
||||
EncodedNormal.z = exp2(10. * glossmap + 1.);
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
#ifndef GL_ARB_bindless_texture
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D glosstex;
|
||||
#endif
|
||||
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
flat in sampler2D handle;
|
||||
flat in sampler2D secondhandle;
|
||||
#endif
|
||||
in vec3 nor;
|
||||
in vec2 uv;
|
||||
@ -14,12 +16,14 @@ vec2 EncodeNormal(vec3 n);
|
||||
void main() {
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
vec4 col = texture(handle, uv);
|
||||
float glossmap = texture(secondhandle, uv).x;
|
||||
#else
|
||||
vec4 col = texture(tex, uv);
|
||||
float glossmap = texture(glosstex, uv).x;
|
||||
#endif
|
||||
if (col.a < 0.5)
|
||||
discard;
|
||||
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
|
||||
EncodedNormal.z = 1.;
|
||||
EncodedNormal.z = exp2(10. * glossmap + 1.);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ vec2 EncodeNormal(vec3 n);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 col = texture(tex, uv);
|
||||
float glossmap = texture(tex, uv).x;
|
||||
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
|
||||
EncodedNormal.z = exp2(10. * (1. - col.a) + 1.);
|
||||
EncodedNormal.z = exp2(10. * glossmap + 1.);
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
#ifdef GL_ARB_bindless_texture
|
||||
layout(bindless_sampler) uniform sampler2D tex;
|
||||
layout(bindless_sampler) uniform sampler2D glosstex;
|
||||
#else
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D glosstex;
|
||||
#endif
|
||||
|
||||
#if __VERSION__ >= 130
|
||||
@ -20,7 +22,8 @@ void main() {
|
||||
vec4 col = texture(tex, uv);
|
||||
if (col.a < 0.5)
|
||||
discard;
|
||||
float glossmap = texture(glosstex, uv).x;
|
||||
EncodedNormal.xy = 0.5 * EncodeNormal(normalize(nor)) + 0.5;
|
||||
EncodedNormal.z = 1.;
|
||||
EncodedNormal.z = exp2(10. * glossmap + 1.);
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ void AddonsManager::initAddons(const XMLNode *xml)
|
||||
else
|
||||
{
|
||||
m_addons_list.getData().push_back(addon);
|
||||
index = m_addons_list.getData().size()-1;
|
||||
index = (int) m_addons_list.getData().size()-1;
|
||||
}
|
||||
// Mark that this addon still exists on the server
|
||||
m_addons_list.getData()[index].setStillExists();
|
||||
@ -240,7 +240,7 @@ void AddonsManager::initAddons(const XMLNode *xml)
|
||||
// an addon that's still on the server and an invalid entry in the
|
||||
// addons installed file), it will be re-downloaded later.
|
||||
m_addons_list.lock();
|
||||
unsigned int count = m_addons_list.getData().size();
|
||||
unsigned int count = (unsigned int) m_addons_list.getData().size();
|
||||
|
||||
for(unsigned int i=0; i<count;)
|
||||
{
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
void setErrorState() { m_state.setAtomic(STATE_ERROR); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the list of addons (installed and uninstalled). */
|
||||
unsigned int getNumAddons() const { return m_addons_list.getData().size();}
|
||||
unsigned int getNumAddons() const { return (unsigned int) m_addons_list.getData().size();}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the i-th addons. */
|
||||
const Addon& getAddon(unsigned int i) { return m_addons_list.getData()[i];}
|
||||
|
@ -224,6 +224,14 @@ void NewsManager::checkRedirect(const XMLNode *xml)
|
||||
}
|
||||
UserConfigParams::m_server_addons = new_server;
|
||||
}
|
||||
|
||||
std::string hw_report_server;
|
||||
if(xml->get("hw-report-server", &hw_report_server)==1 && hw_report_server.size()>0)
|
||||
{
|
||||
Log::info("hw report", "New server at '%s'.", hw_report_server.c_str());
|
||||
UserConfigParams::m_server_hw_report = hw_report_server;
|
||||
}
|
||||
|
||||
} // checkRedirect
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "io/file_manager.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
@ -68,6 +69,7 @@ void SFXManager::destroy()
|
||||
*/
|
||||
SFXManager::SFXManager()
|
||||
{
|
||||
|
||||
// The sound manager initialises OpenAL
|
||||
m_initialized = music_manager->initialized();
|
||||
m_master_gain = UserConfigParams::m_sfx_volume;
|
||||
@ -75,11 +77,39 @@ SFXManager::SFXManager()
|
||||
m_position = Vec3(0,0,0);
|
||||
|
||||
loadSfx();
|
||||
|
||||
pthread_cond_init(&m_cond_request, NULL);
|
||||
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
// Should be the default, but just in case:
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
|
||||
m_thread_id.setAtomic(new pthread_t());
|
||||
// The thread is created even if there atm sfx are disabled
|
||||
// (since the user might enable it later).
|
||||
int error = pthread_create(m_thread_id.getData(), &attr,
|
||||
&SFXManager::mainLoop, this);
|
||||
if (error)
|
||||
{
|
||||
m_thread_id.lock();
|
||||
delete m_thread_id.getData();
|
||||
m_thread_id.unlock();
|
||||
m_thread_id.setAtomic(0);
|
||||
Log::error("HTTP Manager", "Could not create thread, error=%d.",
|
||||
errno);
|
||||
}
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
if (!sfxAllowed()) return;
|
||||
|
||||
setMasterSFXVolume( UserConfigParams::m_sfx_volume );
|
||||
m_sfx_to_play.lock();
|
||||
m_sfx_to_play.getData().clear();
|
||||
m_sfx_to_play.unlock();
|
||||
|
||||
} // SoundManager
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -87,8 +117,14 @@ SFXManager::SFXManager()
|
||||
*/
|
||||
SFXManager::~SFXManager()
|
||||
{
|
||||
m_thread_id.lock();
|
||||
pthread_join(*m_thread_id.getData(), NULL);
|
||||
delete m_thread_id.getData();
|
||||
m_thread_id.unlock();
|
||||
pthread_cond_destroy(&m_cond_request);
|
||||
|
||||
// ---- clear m_all_sfx
|
||||
const int sfx_amount = m_all_sfx.size();
|
||||
const int sfx_amount = (int) m_all_sfx.size();
|
||||
for (int n=0; n<sfx_amount; n++)
|
||||
{
|
||||
delete m_all_sfx[n];
|
||||
@ -131,29 +167,68 @@ void SFXManager::queue(SFXBase *sfx)
|
||||
{
|
||||
// Don't add sfx that are either not working correctly (e.g. because sfx
|
||||
// are disabled);
|
||||
if(sfx->getStatus()==SFX_UNKNOWN ) return;
|
||||
if(sfx && sfx->getStatus()==SFX_UNKNOWN ) return;
|
||||
|
||||
m_sfx_to_play.lock();
|
||||
m_sfx_to_play.getData().push_back(sfx);
|
||||
m_sfx_to_play.unlock();
|
||||
} // playSFX
|
||||
// Wake up the sfx thread
|
||||
pthread_cond_signal(&m_cond_request);
|
||||
|
||||
} // queue
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** Starts all sfx that are queues to be started. Called once per frame.
|
||||
/** Puts a NULL request into the queue, which will trigger the thread to
|
||||
* exit.
|
||||
*/
|
||||
void SFXManager::update()
|
||||
void SFXManager::stopThread()
|
||||
{
|
||||
m_sfx_to_play.lock();
|
||||
while(!m_sfx_to_play.getData().empty())
|
||||
queue(NULL);
|
||||
} // stopThread
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** This loops runs in a different threads, and starts sfx to be played.
|
||||
* This can sometimes take up to 5 ms, so it needs to be handled in a thread
|
||||
* in order to avoid rendering delays.
|
||||
* \param obj A pointer to the SFX singleton.
|
||||
*/
|
||||
void* SFXManager::mainLoop(void *obj)
|
||||
{
|
||||
SFXManager *me = (SFXManager*)obj;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
|
||||
me->m_sfx_to_play.lock();
|
||||
|
||||
// Wait till we have an empty sfx in the queue
|
||||
while (me->m_sfx_to_play.getData().empty() ||
|
||||
me->m_sfx_to_play.getData().front()!=NULL )
|
||||
{
|
||||
SFXBase *sfx = m_sfx_to_play.getData().front();
|
||||
m_sfx_to_play.getData().erase(m_sfx_to_play.getData().begin());
|
||||
m_sfx_to_play.unlock();
|
||||
sfx->reallyPlayNow();
|
||||
m_sfx_to_play.lock();
|
||||
} // while !empty
|
||||
m_sfx_to_play.unlock();
|
||||
} // update
|
||||
bool empty = me->m_sfx_to_play.getData().empty();
|
||||
|
||||
// Wait in cond_wait for a request to arrive. The 'while' is necessary
|
||||
// since "spurious wakeups from the pthread_cond_wait ... may occur"
|
||||
// (pthread_cond_wait man page)!
|
||||
while (empty)
|
||||
{
|
||||
pthread_cond_wait(&me->m_cond_request, me->m_sfx_to_play.getMutex());
|
||||
empty = me->m_sfx_to_play.getData().empty();
|
||||
}
|
||||
|
||||
SFXBase *current = me->m_sfx_to_play.getData().front();
|
||||
me->m_sfx_to_play.getData().erase(me->m_sfx_to_play.getData().begin());
|
||||
|
||||
if (!current) // empty sfx indicates to abort the sfx manager
|
||||
break;
|
||||
|
||||
me->m_sfx_to_play.unlock();
|
||||
current->reallyPlayNow();
|
||||
me->m_sfx_to_play.lock();
|
||||
|
||||
} // while
|
||||
|
||||
return NULL;
|
||||
} // mainLoop
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/** Called then sound is globally switched on or off. It either pauses or
|
||||
@ -174,7 +249,7 @@ void SFXManager::soundToggled(const bool on)
|
||||
|
||||
resumeAll();
|
||||
|
||||
const int sfx_amount = m_all_sfx.size();
|
||||
const int sfx_amount = (int)m_all_sfx.size();
|
||||
for (int n=0; n<sfx_amount; n++)
|
||||
{
|
||||
m_all_sfx[n]->onSoundEnabledBack();
|
||||
|
@ -110,15 +110,21 @@ private:
|
||||
/** Master gain value, taken from the user config value. */
|
||||
float m_master_gain;
|
||||
|
||||
/** Thread id of the thread running in this object. */
|
||||
Synchronised<pthread_t *> m_thread_id;
|
||||
|
||||
/** A conditional variable to wake up the main loop. */
|
||||
pthread_cond_t m_cond_request;
|
||||
|
||||
void loadSfx();
|
||||
SFXManager();
|
||||
virtual ~SFXManager();
|
||||
|
||||
static void* mainLoop(void *obj);
|
||||
public:
|
||||
static void create();
|
||||
static void destroy();
|
||||
void queue(SFXBase *sfx);
|
||||
void update();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Static function to get the singleton sfx manager. */
|
||||
static SFXManager *get()
|
||||
@ -128,6 +134,7 @@ public:
|
||||
} // get
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void stopThread();
|
||||
bool sfxAllowed();
|
||||
SFXBuffer* loadSingleSfx(const XMLNode* node,
|
||||
const std::string &path=std::string(""),
|
||||
|
@ -22,32 +22,106 @@
|
||||
#include "graphics/glwrap.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "online/http_request.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
namespace HardwareStats
|
||||
{
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns the amount of RAM in MB.
|
||||
* (C) 2014 by Wildfire Games (0 A.D.), ported by Joerg Henrichs
|
||||
*/
|
||||
int getRAM()
|
||||
{
|
||||
#ifdef __linux__
|
||||
const uint64_t memorySize = (uint64_t)sysconf(_SC_PHYS_PAGES)
|
||||
const uint64_t memory_size = (uint64_t)sysconf(_SC_PHYS_PAGES)
|
||||
* sysconf(_SC_PAGESIZE);
|
||||
return long(memorySize / (1024*1024));
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
return int(memory_size / (1024*1024));
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
MEMORYSTATUSEX mse;
|
||||
mse.dwLength = sizeof(mse);
|
||||
const bool ok = GlobalMemoryStatusEx(&mse)==TRUE;
|
||||
|
||||
DWORDLONG memory_size = mse.ullTotalPhys;
|
||||
// Richter, "Programming Applications for Windows": the reported
|
||||
// value doesn't include non-paged pool reserved during boot;
|
||||
// it's not considered available to the kernel. (the amount is
|
||||
// 528 KiB on a 512 MiB WinXP/Win2k machine). we'll round up
|
||||
// to the nearest megabyte to fix this.
|
||||
const DWORDLONG mbyte = 1024*1024;
|
||||
return (int)ceil(memory_size/mbyte);
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
size_t memory_size = 0;
|
||||
size_t len = sizeof(memory_size);
|
||||
// Argh, the API doesn't seem to be const-correct
|
||||
/*const*/ int mib[2] = { CTL_HW, HW_PHYSMEM };
|
||||
sysctl(mib, 2, &memory_size, &len, 0, 0);
|
||||
memory_size /= (1024*1024);
|
||||
return int(memory_size);
|
||||
#endif
|
||||
Log::error("HW report",
|
||||
"No RAM information available for hardware report.");
|
||||
return 0;
|
||||
} // getRAM
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns the number of processors on the system.
|
||||
* (C) 2014 by Wildfire Games (0 A.D.), ported by Joerg Henrichs
|
||||
*/
|
||||
int getNumProcessors()
|
||||
{
|
||||
#ifdef __linux__
|
||||
return sysconf(_SC_NPROCESSORS_CONF);
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si); // guaranteed to succeed
|
||||
return si.dwNumberOfProcessors;
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
// Mac OS X doesn't have sysconf(_SC_NPROCESSORS_CONF)
|
||||
int mib[] = { CTL_HW, HW_NCPU };
|
||||
int ncpus;
|
||||
size_t len = sizeof(ncpus);
|
||||
int ret = sysctl(mib, 2, &ncpus, &len, NULL, 0);
|
||||
assert(ret != -1);
|
||||
return ncpus;
|
||||
#endif
|
||||
Log::error("HW report",
|
||||
"Number of processors not available for hardware report.");
|
||||
return 0;
|
||||
} // getNumProcessors
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** If the configuration of this installation has not been reported for the
|
||||
* current version, collect the hardware statistics and send it to STK's
|
||||
* server.
|
||||
*/
|
||||
void reportHardwareStats()
|
||||
{
|
||||
// Version of the hw report, which is stored in the DB. If new fields
|
||||
// are added, increase this version. Each STK installation will report
|
||||
// its configuration only once (per version number). So if the version
|
||||
// number is increased, a new report will be sent.
|
||||
const int report_version = 1;
|
||||
if(UserConfigParams::m_last_hw_report_version>=report_version) return;
|
||||
while(UserConfigParams::m_random_identifier==0)
|
||||
{
|
||||
RandomGenerator rg;
|
||||
UserConfigParams::m_random_identifier = rg.get(1<<30);
|
||||
user_config->saveConfig();
|
||||
}
|
||||
|
||||
Json json;
|
||||
#ifdef WIN32
|
||||
json.add("os_win", 1);
|
||||
@ -100,22 +174,70 @@ void reportHardwareStats()
|
||||
if(mem>0)
|
||||
json.add("ram_total", mem);
|
||||
|
||||
int nr_procs = getNumProcessors();
|
||||
if(nr_procs>0)
|
||||
json.add("cpu_numprocs", nr_procs);
|
||||
|
||||
// Too long for debugging atm
|
||||
//json.add("GL_EXTENSIONS", getGLExtensions());
|
||||
getGLLimits(&json);
|
||||
json.finish();
|
||||
Log::verbose("json", "'%s'", json.toString().c_str());
|
||||
|
||||
Online::HTTPRequest *request = new Online::HTTPRequest(/*manage memory*/true, 1);
|
||||
request->addParameter("user_id", 3);
|
||||
// ------------------------------------------------------------------------
|
||||
/** A small class which sends the HW report to the STK server. On
|
||||
* completion, it will either update the last-submitted-hw-report version,
|
||||
* or log an error message (in which case next time STK is started it
|
||||
* wil try again to log the report).
|
||||
*/
|
||||
class HWReportRequest : public Online::HTTPRequest
|
||||
{
|
||||
private:
|
||||
/** Version number of the hw report. */
|
||||
int m_version;
|
||||
public:
|
||||
HWReportRequest(int version) : Online::HTTPRequest(/*manage memory*/true, 1)
|
||||
,m_version(version)
|
||||
{}
|
||||
// --------------------------------------------------------------------
|
||||
/** Callback after the request has been executed.
|
||||
*/
|
||||
virtual void callback()
|
||||
{
|
||||
// If the request contains incorrect data, it will not have a
|
||||
// download error, but return an error string as return value:
|
||||
if(hadDownloadError() || getData()=="<h1>Bad Request (400)</h1>")
|
||||
{
|
||||
Log::error("HW report", "Error uploading the HW report.");
|
||||
if(hadDownloadError())
|
||||
Log::error("HW report", "%s", getDownloadErrorMessage());
|
||||
else
|
||||
Log::error("HW report", "%s", getData().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::info("HW report", "Upload successful.");
|
||||
UserConfigParams::m_last_hw_report_version = m_version;
|
||||
// The callback is executed by the main thread, so no need
|
||||
// to worry about locks when writing the file.
|
||||
user_config->saveConfig();
|
||||
}
|
||||
} // callback
|
||||
|
||||
}; // HWReportRequest
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
Online::HTTPRequest *request = new HWReportRequest(report_version);
|
||||
request->addParameter("user_id", UserConfigParams::m_random_identifier);
|
||||
request->addParameter("time", StkTime::getTimeSinceEpoch());
|
||||
request->addParameter("type", "hwdetect");
|
||||
request->addParameter("version", 1);
|
||||
request->addParameter("version", report_version);
|
||||
request->addParameter("data", json.toString());
|
||||
request->setURL("http://stats.supertuxkart.net/upload/v1/");
|
||||
request->setURL((std::string)UserConfigParams::m_server_hw_report+"/upload/v1/");
|
||||
//request->setURL("http://127.0.0.1:8000/upload/v1/");
|
||||
// FIXME: For now: don't submit
|
||||
//request->queue();
|
||||
|
||||
} // reportHardwareStats
|
||||
|
||||
} // namespace HardwareStats
|
||||
|
@ -31,7 +31,6 @@ static PtrVector<UserConfigParam, REF> all_params;
|
||||
#define PARAM_DEFAULT(X) = X
|
||||
#include "config/user_config.hpp"
|
||||
|
||||
#include "config/player_profile.hpp"
|
||||
#include "config/saved_grand_prix.hpp"
|
||||
#include "config/stk_config.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
@ -91,7 +90,7 @@ GroupUserConfigParam::GroupUserConfigParam(const char* group_name,
|
||||
// ----------------------------------------------------------------------------
|
||||
void GroupUserConfigParam::write(std::ofstream& stream) const
|
||||
{
|
||||
const int attr_amount = m_attributes.size();
|
||||
const int attr_amount = (int)m_attributes.size();
|
||||
|
||||
// comments
|
||||
if(m_comment.size() > 0) stream << " <!-- " << m_comment.c_str();
|
||||
@ -110,7 +109,7 @@ void GroupUserConfigParam::write(std::ofstream& stream) const
|
||||
m_attributes[n]->writeInner(stream, 1);
|
||||
}
|
||||
stream << " >\n";
|
||||
const int children_amount = m_children.size();
|
||||
const int children_amount = (int)m_children.size();
|
||||
for (int n=0; n<children_amount; n++)
|
||||
{
|
||||
m_children[n]->writeInner(stream, 1);
|
||||
|
@ -680,7 +680,25 @@ namespace UserConfigParams
|
||||
"wasn't asked, 1: allowed, 2: "
|
||||
"not allowed") );
|
||||
|
||||
// ---- User managerment
|
||||
PARAM_PREFIX GroupUserConfigParam m_hw_report_group
|
||||
PARAM_DEFAULT( GroupUserConfigParam("HWReport",
|
||||
"Everything related to hardware configuration.") );
|
||||
|
||||
PARAM_PREFIX IntUserConfigParam m_last_hw_report_version
|
||||
PARAM_DEFAULT( IntUserConfigParam(0, "report-version", &m_hw_report_group,
|
||||
"Version of hardware report "
|
||||
"that was reported last") );
|
||||
PARAM_PREFIX IntUserConfigParam m_random_identifier
|
||||
PARAM_DEFAULT( IntUserConfigParam(0, "random-identifier", &m_hw_report_group,
|
||||
"A random number to avoid duplicated reports.") );
|
||||
|
||||
PARAM_PREFIX StringUserConfigParam m_server_hw_report
|
||||
PARAM_DEFAULT( StringUserConfigParam( "http://stats.supertuxkart.net",
|
||||
"hw-report-server",
|
||||
&m_hw_report_group,
|
||||
"The server used for reporting statistics to."));
|
||||
|
||||
// ---- User management
|
||||
|
||||
PARAM_PREFIX BoolUserConfigParam m_always_show_login_screen
|
||||
PARAM_DEFAULT( BoolUserConfigParam(false, "always_show_login_screen",
|
||||
|
@ -367,7 +367,6 @@ void FrameBuffer::Bind()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
glViewport(0, 0, width, height);
|
||||
irr::video::COpenGLDriver *gl_driver = (irr::video::COpenGLDriver*)irr_driver->getDevice()->getVideoDriver();
|
||||
GLenum bufs[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
|
||||
glDrawBuffers(RenderTargets.size(), bufs);
|
||||
}
|
||||
@ -770,360 +769,360 @@ const std::string getGLExtensions()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Adds GL limits to the json data structure.
|
||||
* Thanks to Wildfire Games / 0.A.D. for allowing us to port their sources.
|
||||
* (C) 2014 by Wildfire Games (0 A.D.), ported by Joerg Henrichs
|
||||
*/
|
||||
void getGLLimits(HardwareStats::Json *json)
|
||||
{
|
||||
// Various macros to make the data assembly shorter.
|
||||
#define INTEGER(id) \
|
||||
do { \
|
||||
GLint i = -1; \
|
||||
glGetIntegerv(GL_##id, &i); \
|
||||
if (glGetError()==GL_NO_ERROR) \
|
||||
json->add("GL_"#id, i); \
|
||||
} while (false)
|
||||
#define INTEGER2(id) \
|
||||
do { \
|
||||
GLint i[2] = { -1, -1 }; \
|
||||
glGetIntegerv(GL_##id, i); \
|
||||
if (glGetError()==GL_NO_ERROR) { \
|
||||
json->add("GL_"#id"[0]", i[0]); \
|
||||
json->add("GL_"#id"[1]", i[1]); \
|
||||
} \
|
||||
} while (false)
|
||||
#define FLOAT(id) \
|
||||
do { \
|
||||
GLfloat f = -1.0f; \
|
||||
glGetFloatv(GL_##id, &f); \
|
||||
if (glGetError()==GL_NO_ERROR) \
|
||||
json->add("GL_"#id, f); \
|
||||
} while (false)
|
||||
#define FLOAT2(id) \
|
||||
do { \
|
||||
GLfloat f[2] = {-1.0f, -1.0f}; \
|
||||
glGetFloatv(GL_##id, f); \
|
||||
if (glGetError()==GL_NO_ERROR) { \
|
||||
json->add("GL_"#id"[0]", f[0]); \
|
||||
json->add("GL_"#id"[1]", f[1]); \
|
||||
} \
|
||||
} while (false)
|
||||
#define STRING(id) \
|
||||
do { \
|
||||
const char* c = (const char*)glGetString(GL_##id); \
|
||||
if(!c) c=""; \
|
||||
json->add("GL_"#id, c); \
|
||||
} while (false)
|
||||
|
||||
|
||||
STRING(VERSION);
|
||||
STRING(VENDOR);
|
||||
STRING(RENDERER);
|
||||
STRING(EXTENSIONS);
|
||||
INTEGER(SUBPIXEL_BITS);
|
||||
INTEGER(MAX_TEXTURE_SIZE);
|
||||
INTEGER(MAX_CUBE_MAP_TEXTURE_SIZE);
|
||||
INTEGER2(MAX_VIEWPORT_DIMS);
|
||||
FLOAT2(ALIASED_POINT_SIZE_RANGE);
|
||||
FLOAT2(ALIASED_LINE_WIDTH_RANGE);
|
||||
INTEGER(SAMPLE_BUFFERS);
|
||||
INTEGER(SAMPLES);
|
||||
// TODO: compressed texture formats
|
||||
INTEGER(RED_BITS);
|
||||
INTEGER(GREEN_BITS);
|
||||
INTEGER(BLUE_BITS);
|
||||
INTEGER(ALPHA_BITS);
|
||||
INTEGER(DEPTH_BITS);
|
||||
INTEGER(STENCIL_BITS);
|
||||
|
||||
return;
|
||||
|
||||
#ifdef NOT_DONE_YET
|
||||
#define QUERY(target, pname) do { \
|
||||
GLint i = -1; \
|
||||
pglGetQueryivARB(GL_##target, GL_##pname, &i); \
|
||||
if (ogl_SquelchError(GL_INVALID_ENUM)) \
|
||||
scriptInterface.SetProperty(settings, "GL_" #target ".GL_" #pname, errstr); \
|
||||
else \
|
||||
scriptInterface.SetProperty(settings, "GL_" #target ".GL_" #pname, i); \
|
||||
} while (false)
|
||||
#define VERTEXPROGRAM(id) do { \
|
||||
GLint i = -1; \
|
||||
pglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_##id, &i); \
|
||||
if (ogl_SquelchError(GL_INVALID_ENUM)) \
|
||||
scriptInterface.SetProperty(settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, errstr); \
|
||||
else \
|
||||
scriptInterface.SetProperty(settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, i); \
|
||||
} while (false)
|
||||
#define FRAGMENTPROGRAM(id) do { \
|
||||
GLint i = -1; \
|
||||
pglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_##id, &i); \
|
||||
if (ogl_SquelchError(GL_INVALID_ENUM)) \
|
||||
scriptInterface.SetProperty(settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, errstr); \
|
||||
else \
|
||||
scriptInterface.SetProperty(settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, i); \
|
||||
} while (false)
|
||||
#define BOOL(id) INTEGER(id)
|
||||
|
||||
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(MAX_LIGHTS);
|
||||
INTEGER(MAX_CLIP_PLANES);
|
||||
// Skip MAX_COLOR_MATRIX_STACK_DEPTH (only in imaging subset)
|
||||
INTEGER(MAX_MODELVIEW_STACK_DEPTH);
|
||||
INTEGER(MAX_PROJECTION_STACK_DEPTH);
|
||||
INTEGER(MAX_TEXTURE_STACK_DEPTH);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(MAX_3D_TEXTURE_SIZE);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(MAX_PIXEL_MAP_TABLE);
|
||||
INTEGER(MAX_NAME_STACK_DEPTH);
|
||||
INTEGER(MAX_LIST_NESTING);
|
||||
INTEGER(MAX_EVAL_ORDER);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(MAX_ATTRIB_STACK_DEPTH);
|
||||
INTEGER(MAX_CLIENT_ATTRIB_STACK_DEPTH);
|
||||
INTEGER(AUX_BUFFERS);
|
||||
BOOL(RGBA_MODE);
|
||||
BOOL(INDEX_MODE);
|
||||
BOOL(DOUBLEBUFFER);
|
||||
BOOL(STEREO);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
FLOAT2(SMOOTH_POINT_SIZE_RANGE);
|
||||
FLOAT(SMOOTH_POINT_SIZE_GRANULARITY);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
FLOAT2(SMOOTH_LINE_WIDTH_RANGE);
|
||||
FLOAT(SMOOTH_LINE_WIDTH_GRANULARITY);
|
||||
// Skip MAX_CONVOLUTION_WIDTH, MAX_CONVOLUTION_HEIGHT (only in imaging subset)
|
||||
INTEGER(MAX_ELEMENTS_INDICES);
|
||||
INTEGER(MAX_ELEMENTS_VERTICES);
|
||||
INTEGER(MAX_TEXTURE_UNITS);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(INDEX_BITS);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(ACCUM_RED_BITS);
|
||||
INTEGER(ACCUM_GREEN_BITS);
|
||||
INTEGER(ACCUM_BLUE_BITS);
|
||||
INTEGER(ACCUM_ALPHA_BITS);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
// Core OpenGL 2.0 (treated as extensions):
|
||||
if (ogl_HaveExtension("GL_EXT_texture_lod_bias"))
|
||||
{
|
||||
FLOAT(MAX_TEXTURE_LOD_BIAS_EXT);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_occlusion_query"))
|
||||
{
|
||||
QUERY(SAMPLES_PASSED, QUERY_COUNTER_BITS);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_shading_language_100"))
|
||||
{
|
||||
STRING(SHADING_LANGUAGE_VERSION_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_shader"))
|
||||
{
|
||||
INTEGER(MAX_VERTEX_ATTRIBS_ARB);
|
||||
INTEGER(MAX_VERTEX_UNIFORM_COMPONENTS_ARB);
|
||||
INTEGER(MAX_VARYING_FLOATS_ARB);
|
||||
INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB);
|
||||
INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_fragment_shader"))
|
||||
{
|
||||
INTEGER(MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_shader") || ogl_HaveExtension("GL_ARB_fragment_shader") ||
|
||||
ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
|
||||
{
|
||||
INTEGER(MAX_TEXTURE_IMAGE_UNITS_ARB);
|
||||
INTEGER(MAX_TEXTURE_COORDS_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_draw_buffers"))
|
||||
{
|
||||
INTEGER(MAX_DRAW_BUFFERS_ARB);
|
||||
}
|
||||
// Core OpenGL 3.0:
|
||||
if (ogl_HaveExtension("GL_EXT_gpu_shader4"))
|
||||
{
|
||||
INTEGER(MIN_PROGRAM_TEXEL_OFFSET); // no _EXT version of these in glext.h
|
||||
INTEGER(MAX_PROGRAM_TEXEL_OFFSET);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_EXT_framebuffer_object"))
|
||||
{
|
||||
INTEGER(MAX_COLOR_ATTACHMENTS_EXT);
|
||||
INTEGER(MAX_RENDERBUFFER_SIZE_EXT);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_EXT_framebuffer_multisample"))
|
||||
{
|
||||
INTEGER(MAX_SAMPLES_EXT);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_EXT_texture_array"))
|
||||
{
|
||||
INTEGER(MAX_ARRAY_TEXTURE_LAYERS_EXT);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_EXT_transform_feedback"))
|
||||
{
|
||||
INTEGER(MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT);
|
||||
INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT);
|
||||
INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT);
|
||||
}
|
||||
// Other interesting extensions:
|
||||
if (ogl_HaveExtension("GL_EXT_timer_query") || ogl_HaveExtension("GL_ARB_timer_query"))
|
||||
{
|
||||
QUERY(TIME_ELAPSED, QUERY_COUNTER_BITS);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_timer_query"))
|
||||
{
|
||||
QUERY(TIMESTAMP, QUERY_COUNTER_BITS);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_EXT_texture_filter_anisotropic"))
|
||||
{
|
||||
FLOAT(MAX_TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_texture_rectangle"))
|
||||
{
|
||||
INTEGER(MAX_RECTANGLE_TEXTURE_SIZE_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
|
||||
{
|
||||
INTEGER(MAX_PROGRAM_MATRICES_ARB);
|
||||
INTEGER(MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_program"))
|
||||
{
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
|
||||
if (ogl_HaveExtension("GL_ARB_fragment_program"))
|
||||
{
|
||||
// The spec seems to say these should be supported, but
|
||||
// Mesa complains about them so let's not bother
|
||||
/*
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
|
||||
*/
|
||||
}
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_fragment_program"))
|
||||
{
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_program"))
|
||||
{
|
||||
// The spec seems to say these should be supported, but
|
||||
// Intel drivers on Windows complain about them so let's not bother
|
||||
/*
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
|
||||
*/
|
||||
}
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_geometry_shader4"))
|
||||
{
|
||||
INTEGER(MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB);
|
||||
INTEGER(MAX_GEOMETRY_OUTPUT_VERTICES_ARB);
|
||||
INTEGER(MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB);
|
||||
INTEGER(MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB);
|
||||
INTEGER(MAX_GEOMETRY_VARYING_COMPONENTS_ARB);
|
||||
INTEGER(MAX_VERTEX_VARYING_COMPONENTS_ARB);
|
||||
}
|
||||
#else // CONFIG2_GLES
|
||||
// Core OpenGL ES 2.0:
|
||||
STRING(SHADING_LANGUAGE_VERSION);
|
||||
INTEGER(MAX_VERTEX_ATTRIBS);
|
||||
INTEGER(MAX_VERTEX_UNIFORM_VECTORS);
|
||||
INTEGER(MAX_VARYING_VECTORS);
|
||||
INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
|
||||
INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS);
|
||||
INTEGER(MAX_FRAGMENT_UNIFORM_VECTORS);
|
||||
INTEGER(MAX_TEXTURE_IMAGE_UNITS);
|
||||
INTEGER(MAX_RENDERBUFFER_SIZE);
|
||||
#endif // CONFIG2_GLES
|
||||
#ifdef SDL_VIDEO_DRIVER_X11
|
||||
#define GLXQCR_INTEGER(id) do { \
|
||||
unsigned int i = UINT_MAX; \
|
||||
if (pglXQueryCurrentRendererIntegerMESA(id, &i)) \
|
||||
scriptInterface.SetProperty(settings, #id, i); \
|
||||
} while (false)
|
||||
#define GLXQCR_INTEGER2(id) do { \
|
||||
unsigned int i[2] = { UINT_MAX, UINT_MAX }; \
|
||||
if (pglXQueryCurrentRendererIntegerMESA(id, i)) { \
|
||||
scriptInterface.SetProperty(settings, #id "[0]", i[0]); \
|
||||
scriptInterface.SetProperty(settings, #id "[1]", i[1]); \
|
||||
} \
|
||||
} while (false)
|
||||
#define GLXQCR_INTEGER3(id) do { \
|
||||
unsigned int i[3] = { UINT_MAX, UINT_MAX, UINT_MAX }; \
|
||||
if (pglXQueryCurrentRendererIntegerMESA(id, i)) { \
|
||||
scriptInterface.SetProperty(settings, #id "[0]", i[0]); \
|
||||
scriptInterface.SetProperty(settings, #id "[1]", i[1]); \
|
||||
scriptInterface.SetProperty(settings, #id "[2]", i[2]); \
|
||||
} \
|
||||
} while (false)
|
||||
#define GLXQCR_STRING(id) do { \
|
||||
const char* str = pglXQueryCurrentRendererStringMESA(id); \
|
||||
if (str) \
|
||||
scriptInterface.SetProperty(settings, #id ".string", str); \
|
||||
} while (false)
|
||||
SDL_SysWMinfo wminfo;
|
||||
SDL_VERSION(&wminfo.version);
|
||||
if (SDL_GetWMInfo(&wminfo) && wminfo.subsystem == SDL_SYSWM_X11)
|
||||
{
|
||||
Display* dpy = wminfo.info.x11.gfxdisplay;
|
||||
int scrnum = DefaultScreen(dpy);
|
||||
const char* glxexts = glXQueryExtensionsString(dpy, scrnum);
|
||||
scriptInterface.SetProperty(settings, "glx_extensions", glxexts);
|
||||
if (strstr(glxexts, "GLX_MESA_query_renderer") && pglXQueryCurrentRendererIntegerMESA && pglXQueryCurrentRendererStringMESA)
|
||||
{
|
||||
GLXQCR_INTEGER(GLX_RENDERER_VENDOR_ID_MESA);
|
||||
GLXQCR_INTEGER(GLX_RENDERER_DEVICE_ID_MESA);
|
||||
GLXQCR_INTEGER3(GLX_RENDERER_VERSION_MESA);
|
||||
GLXQCR_INTEGER(GLX_RENDERER_ACCELERATED_MESA);
|
||||
GLXQCR_INTEGER(GLX_RENDERER_VIDEO_MEMORY_MESA);
|
||||
GLXQCR_INTEGER(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA);
|
||||
GLXQCR_INTEGER(GLX_RENDERER_PREFERRED_PROFILE_MESA);
|
||||
GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA);
|
||||
GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA);
|
||||
GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA);
|
||||
GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA);
|
||||
GLXQCR_STRING(GLX_RENDERER_VENDOR_ID_MESA);
|
||||
GLXQCR_STRING(GLX_RENDERER_DEVICE_ID_MESA);
|
||||
}
|
||||
}
|
||||
#define INTEGER(id) \
|
||||
do { \
|
||||
GLint i = -1; \
|
||||
glGetIntegerv(GL_##id, &i); \
|
||||
if (glGetError()==GL_NO_ERROR) \
|
||||
json->add("GL_"#id, i); \
|
||||
} while (false)
|
||||
#define INTEGER2(id) \
|
||||
do { \
|
||||
GLint i[2] = { -1, -1 }; \
|
||||
glGetIntegerv(GL_##id, i); \
|
||||
if (glGetError()==GL_NO_ERROR) { \
|
||||
json->add("GL_"#id"[0]", i[0]); \
|
||||
json->add("GL_"#id"[1]", i[1]); \
|
||||
} \
|
||||
} while (false)
|
||||
#define FLOAT(id) \
|
||||
do { \
|
||||
GLfloat f = -1.0f; \
|
||||
glGetFloatv(GL_##id, &f); \
|
||||
if (glGetError()==GL_NO_ERROR) \
|
||||
json->add("GL_"#id, f); \
|
||||
} while (false)
|
||||
#define FLOAT2(id) \
|
||||
do { \
|
||||
GLfloat f[2] = {-1.0f, -1.0f}; \
|
||||
glGetFloatv(GL_##id, f); \
|
||||
if (glGetError()==GL_NO_ERROR) { \
|
||||
json->add("GL_"#id"[0]", f[0]); \
|
||||
json->add("GL_"#id"[1]", f[1]); \
|
||||
} \
|
||||
} while (false)
|
||||
#define STRING(id) \
|
||||
do { \
|
||||
const char* c = (const char*)glGetString(GL_##id); \
|
||||
if(!c) c=""; \
|
||||
json->add("GL_"#id, c); \
|
||||
} while (false)
|
||||
|
||||
|
||||
STRING(VERSION);
|
||||
STRING(VENDOR);
|
||||
STRING(RENDERER);
|
||||
STRING(EXTENSIONS);
|
||||
INTEGER(SUBPIXEL_BITS);
|
||||
INTEGER(MAX_TEXTURE_SIZE);
|
||||
INTEGER(MAX_CUBE_MAP_TEXTURE_SIZE);
|
||||
INTEGER2(MAX_VIEWPORT_DIMS);
|
||||
FLOAT2(ALIASED_POINT_SIZE_RANGE);
|
||||
FLOAT2(ALIASED_LINE_WIDTH_RANGE);
|
||||
INTEGER(SAMPLE_BUFFERS);
|
||||
INTEGER(SAMPLES);
|
||||
// TODO: compressed texture formats
|
||||
INTEGER(RED_BITS);
|
||||
INTEGER(GREEN_BITS);
|
||||
INTEGER(BLUE_BITS);
|
||||
INTEGER(ALPHA_BITS);
|
||||
INTEGER(DEPTH_BITS);
|
||||
INTEGER(STENCIL_BITS);
|
||||
|
||||
return;
|
||||
|
||||
#ifdef NOT_DONE_YET
|
||||
#define QUERY(target, pname) do { \
|
||||
GLint i = -1; \
|
||||
pglGetQueryivARB(GL_##target, GL_##pname, &i); \
|
||||
if (ogl_SquelchError(GL_INVALID_ENUM)) \
|
||||
scriptInterface.SetProperty(settings, "GL_" #target ".GL_" #pname, errstr); \
|
||||
else \
|
||||
scriptInterface.SetProperty(settings, "GL_" #target ".GL_" #pname, i); \
|
||||
} while (false)
|
||||
#define VERTEXPROGRAM(id) do { \
|
||||
GLint i = -1; \
|
||||
pglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_##id, &i); \
|
||||
if (ogl_SquelchError(GL_INVALID_ENUM)) \
|
||||
scriptInterface.SetProperty(settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, errstr); \
|
||||
else \
|
||||
scriptInterface.SetProperty(settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, i); \
|
||||
} while (false)
|
||||
#define FRAGMENTPROGRAM(id) do { \
|
||||
GLint i = -1; \
|
||||
pglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_##id, &i); \
|
||||
if (ogl_SquelchError(GL_INVALID_ENUM)) \
|
||||
scriptInterface.SetProperty(settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, errstr); \
|
||||
else \
|
||||
scriptInterface.SetProperty(settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, i); \
|
||||
} while (false)
|
||||
#define BOOL(id) INTEGER(id)
|
||||
|
||||
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(MAX_LIGHTS);
|
||||
INTEGER(MAX_CLIP_PLANES);
|
||||
// Skip MAX_COLOR_MATRIX_STACK_DEPTH (only in imaging subset)
|
||||
INTEGER(MAX_MODELVIEW_STACK_DEPTH);
|
||||
INTEGER(MAX_PROJECTION_STACK_DEPTH);
|
||||
INTEGER(MAX_TEXTURE_STACK_DEPTH);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(MAX_3D_TEXTURE_SIZE);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(MAX_PIXEL_MAP_TABLE);
|
||||
INTEGER(MAX_NAME_STACK_DEPTH);
|
||||
INTEGER(MAX_LIST_NESTING);
|
||||
INTEGER(MAX_EVAL_ORDER);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(MAX_ATTRIB_STACK_DEPTH);
|
||||
INTEGER(MAX_CLIENT_ATTRIB_STACK_DEPTH);
|
||||
INTEGER(AUX_BUFFERS);
|
||||
BOOL(RGBA_MODE);
|
||||
BOOL(INDEX_MODE);
|
||||
BOOL(DOUBLEBUFFER);
|
||||
BOOL(STEREO);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
FLOAT2(SMOOTH_POINT_SIZE_RANGE);
|
||||
FLOAT(SMOOTH_POINT_SIZE_GRANULARITY);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
FLOAT2(SMOOTH_LINE_WIDTH_RANGE);
|
||||
FLOAT(SMOOTH_LINE_WIDTH_GRANULARITY);
|
||||
// Skip MAX_CONVOLUTION_WIDTH, MAX_CONVOLUTION_HEIGHT (only in imaging subset)
|
||||
INTEGER(MAX_ELEMENTS_INDICES);
|
||||
INTEGER(MAX_ELEMENTS_VERTICES);
|
||||
INTEGER(MAX_TEXTURE_UNITS);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(INDEX_BITS);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
INTEGER(ACCUM_RED_BITS);
|
||||
INTEGER(ACCUM_GREEN_BITS);
|
||||
INTEGER(ACCUM_BLUE_BITS);
|
||||
INTEGER(ACCUM_ALPHA_BITS);
|
||||
#endif
|
||||
#if !CONFIG2_GLES
|
||||
// Core OpenGL 2.0 (treated as extensions):
|
||||
if (ogl_HaveExtension("GL_EXT_texture_lod_bias"))
|
||||
{
|
||||
FLOAT(MAX_TEXTURE_LOD_BIAS_EXT);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_occlusion_query"))
|
||||
{
|
||||
QUERY(SAMPLES_PASSED, QUERY_COUNTER_BITS);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_shading_language_100"))
|
||||
{
|
||||
STRING(SHADING_LANGUAGE_VERSION_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_shader"))
|
||||
{
|
||||
INTEGER(MAX_VERTEX_ATTRIBS_ARB);
|
||||
INTEGER(MAX_VERTEX_UNIFORM_COMPONENTS_ARB);
|
||||
INTEGER(MAX_VARYING_FLOATS_ARB);
|
||||
INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB);
|
||||
INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_fragment_shader"))
|
||||
{
|
||||
INTEGER(MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_shader") || ogl_HaveExtension("GL_ARB_fragment_shader") ||
|
||||
ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
|
||||
{
|
||||
INTEGER(MAX_TEXTURE_IMAGE_UNITS_ARB);
|
||||
INTEGER(MAX_TEXTURE_COORDS_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_draw_buffers"))
|
||||
{
|
||||
INTEGER(MAX_DRAW_BUFFERS_ARB);
|
||||
}
|
||||
// Core OpenGL 3.0:
|
||||
if (ogl_HaveExtension("GL_EXT_gpu_shader4"))
|
||||
{
|
||||
INTEGER(MIN_PROGRAM_TEXEL_OFFSET); // no _EXT version of these in glext.h
|
||||
INTEGER(MAX_PROGRAM_TEXEL_OFFSET);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_EXT_framebuffer_object"))
|
||||
{
|
||||
INTEGER(MAX_COLOR_ATTACHMENTS_EXT);
|
||||
INTEGER(MAX_RENDERBUFFER_SIZE_EXT);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_EXT_framebuffer_multisample"))
|
||||
{
|
||||
INTEGER(MAX_SAMPLES_EXT);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_EXT_texture_array"))
|
||||
{
|
||||
INTEGER(MAX_ARRAY_TEXTURE_LAYERS_EXT);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_EXT_transform_feedback"))
|
||||
{
|
||||
INTEGER(MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT);
|
||||
INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT);
|
||||
INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT);
|
||||
}
|
||||
// Other interesting extensions:
|
||||
if (ogl_HaveExtension("GL_EXT_timer_query") || ogl_HaveExtension("GL_ARB_timer_query"))
|
||||
{
|
||||
QUERY(TIME_ELAPSED, QUERY_COUNTER_BITS);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_timer_query"))
|
||||
{
|
||||
QUERY(TIMESTAMP, QUERY_COUNTER_BITS);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_EXT_texture_filter_anisotropic"))
|
||||
{
|
||||
FLOAT(MAX_TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_texture_rectangle"))
|
||||
{
|
||||
INTEGER(MAX_RECTANGLE_TEXTURE_SIZE_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
|
||||
{
|
||||
INTEGER(MAX_PROGRAM_MATRICES_ARB);
|
||||
INTEGER(MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB);
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_program"))
|
||||
{
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
|
||||
if (ogl_HaveExtension("GL_ARB_fragment_program"))
|
||||
{
|
||||
// The spec seems to say these should be supported, but
|
||||
// Mesa complains about them so let's not bother
|
||||
/*
|
||||
VERTEXPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
|
||||
VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
|
||||
*/
|
||||
}
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_fragment_program"))
|
||||
{
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
|
||||
if (ogl_HaveExtension("GL_ARB_vertex_program"))
|
||||
{
|
||||
// The spec seems to say these should be supported, but
|
||||
// Intel drivers on Windows complain about them so let's not bother
|
||||
/*
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
|
||||
FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
|
||||
*/
|
||||
}
|
||||
}
|
||||
if (ogl_HaveExtension("GL_ARB_geometry_shader4"))
|
||||
{
|
||||
INTEGER(MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB);
|
||||
INTEGER(MAX_GEOMETRY_OUTPUT_VERTICES_ARB);
|
||||
INTEGER(MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB);
|
||||
INTEGER(MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB);
|
||||
INTEGER(MAX_GEOMETRY_VARYING_COMPONENTS_ARB);
|
||||
INTEGER(MAX_VERTEX_VARYING_COMPONENTS_ARB);
|
||||
}
|
||||
#else // CONFIG2_GLES
|
||||
// Core OpenGL ES 2.0:
|
||||
STRING(SHADING_LANGUAGE_VERSION);
|
||||
INTEGER(MAX_VERTEX_ATTRIBS);
|
||||
INTEGER(MAX_VERTEX_UNIFORM_VECTORS);
|
||||
INTEGER(MAX_VARYING_VECTORS);
|
||||
INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
|
||||
INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS);
|
||||
INTEGER(MAX_FRAGMENT_UNIFORM_VECTORS);
|
||||
INTEGER(MAX_TEXTURE_IMAGE_UNITS);
|
||||
INTEGER(MAX_RENDERBUFFER_SIZE);
|
||||
#endif // CONFIG2_GLES
|
||||
#ifdef SDL_VIDEO_DRIVER_X11
|
||||
#define GLXQCR_INTEGER(id) do { \
|
||||
unsigned int i = UINT_MAX; \
|
||||
if (pglXQueryCurrentRendererIntegerMESA(id, &i)) \
|
||||
scriptInterface.SetProperty(settings, #id, i); \
|
||||
} while (false)
|
||||
#define GLXQCR_INTEGER2(id) do { \
|
||||
unsigned int i[2] = { UINT_MAX, UINT_MAX }; \
|
||||
if (pglXQueryCurrentRendererIntegerMESA(id, i)) { \
|
||||
scriptInterface.SetProperty(settings, #id "[0]", i[0]); \
|
||||
scriptInterface.SetProperty(settings, #id "[1]", i[1]); \
|
||||
} \
|
||||
} while (false)
|
||||
#define GLXQCR_INTEGER3(id) do { \
|
||||
unsigned int i[3] = { UINT_MAX, UINT_MAX, UINT_MAX }; \
|
||||
if (pglXQueryCurrentRendererIntegerMESA(id, i)) { \
|
||||
scriptInterface.SetProperty(settings, #id "[0]", i[0]); \
|
||||
scriptInterface.SetProperty(settings, #id "[1]", i[1]); \
|
||||
scriptInterface.SetProperty(settings, #id "[2]", i[2]); \
|
||||
} \
|
||||
} while (false)
|
||||
#define GLXQCR_STRING(id) do { \
|
||||
const char* str = pglXQueryCurrentRendererStringMESA(id); \
|
||||
if (str) \
|
||||
scriptInterface.SetProperty(settings, #id ".string", str); \
|
||||
} while (false)
|
||||
SDL_SysWMinfo wminfo;
|
||||
SDL_VERSION(&wminfo.version);
|
||||
if (SDL_GetWMInfo(&wminfo) && wminfo.subsystem == SDL_SYSWM_X11)
|
||||
{
|
||||
Display* dpy = wminfo.info.x11.gfxdisplay;
|
||||
int scrnum = DefaultScreen(dpy);
|
||||
const char* glxexts = glXQueryExtensionsString(dpy, scrnum);
|
||||
scriptInterface.SetProperty(settings, "glx_extensions", glxexts);
|
||||
if (strstr(glxexts, "GLX_MESA_query_renderer") && pglXQueryCurrentRendererIntegerMESA && pglXQueryCurrentRendererStringMESA)
|
||||
{
|
||||
GLXQCR_INTEGER(GLX_RENDERER_VENDOR_ID_MESA);
|
||||
GLXQCR_INTEGER(GLX_RENDERER_DEVICE_ID_MESA);
|
||||
GLXQCR_INTEGER3(GLX_RENDERER_VERSION_MESA);
|
||||
GLXQCR_INTEGER(GLX_RENDERER_ACCELERATED_MESA);
|
||||
GLXQCR_INTEGER(GLX_RENDERER_VIDEO_MEMORY_MESA);
|
||||
GLXQCR_INTEGER(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA);
|
||||
GLXQCR_INTEGER(GLX_RENDERER_PREFERRED_PROFILE_MESA);
|
||||
GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA);
|
||||
GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA);
|
||||
GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA);
|
||||
GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA);
|
||||
GLXQCR_STRING(GLX_RENDERER_VENDOR_ID_MESA);
|
||||
GLXQCR_STRING(GLX_RENDERER_DEVICE_ID_MESA);
|
||||
}
|
||||
}
|
||||
#endif // SDL_VIDEO_DRIVER_X11
|
||||
|
||||
#endif // ifdef XX
|
||||
} // getGLLimits
|
||||
} // getGLLimits
|
||||
|
@ -16,7 +16,7 @@ namespace HardwareStats
|
||||
|
||||
void initGL();
|
||||
GLuint LoadTFBProgram(const char * vertex_file_path, const char **varyings, unsigned varyingscount);
|
||||
video::ITexture* getUnicolorTexture(video::SColor c);
|
||||
video::ITexture* getUnicolorTexture(const video::SColor &c);
|
||||
void setTexture(unsigned TextureUnit, GLuint TextureId, GLenum MagFilter, GLenum MinFilter, bool allowAF = false);
|
||||
GLuint LoadShader(const char * file, unsigned type);
|
||||
|
||||
|
@ -499,6 +499,7 @@ void IrrDriver::initDevice()
|
||||
m_glsl = (m_gl_major_version > 3 || (m_gl_major_version == 3 && m_gl_minor_version >= 1));
|
||||
#endif
|
||||
initGL();
|
||||
m_sync = 0;
|
||||
|
||||
// Parse extensions
|
||||
hasVSLayer = false;
|
||||
@ -949,22 +950,36 @@ void IrrDriver::setAllMaterialFlags(scene::IMesh *mesh) const
|
||||
for(unsigned int i=0; i<n; i++)
|
||||
{
|
||||
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
|
||||
video::SMaterial &irr_material=mb->getMaterial();
|
||||
video::ITexture* t=irr_material.getTexture(0);
|
||||
if(t) material_manager->setAllMaterialFlags(t, mb);
|
||||
video::SMaterial &irr_material = mb->getMaterial();
|
||||
|
||||
// special case : for splatting, the main material is on layer 1.
|
||||
// it was done this way to provide a fallback for computers
|
||||
// where shaders are not supported
|
||||
t = irr_material.getTexture(1);
|
||||
if (t)
|
||||
video::ITexture* t2 = irr_material.getTexture(1);
|
||||
bool is_splatting = false;
|
||||
if (t2)
|
||||
{
|
||||
Material* mat = material_manager->getMaterialFor(t, mb);
|
||||
Material* mat = material_manager->getMaterialFor(t2, mb);
|
||||
if (mat != NULL && mat->getShaderType() == Material::SHADERTYPE_SPLATTING)
|
||||
material_manager->setAllMaterialFlags(t, mb);
|
||||
{
|
||||
material_manager->setAllMaterialFlags(t2, mb);
|
||||
is_splatting = true;
|
||||
}
|
||||
}
|
||||
|
||||
material_manager->setAllUntexturedMaterialFlags(mb);
|
||||
if (!is_splatting)
|
||||
{
|
||||
video::ITexture* t = irr_material.getTexture(0);
|
||||
if (t)
|
||||
{
|
||||
material_manager->setAllMaterialFlags(t, mb);
|
||||
}
|
||||
else
|
||||
{
|
||||
material_manager->setAllUntexturedMaterialFlags(mb);
|
||||
}
|
||||
}
|
||||
|
||||
} // for i<getMeshBufferCount()
|
||||
} // setAllMaterialFlags
|
||||
|
||||
|
@ -91,10 +91,6 @@ int LODNode::getLevel()
|
||||
return n;
|
||||
}
|
||||
|
||||
// If it's the shadow pass, and we would have otherwise hidden the item, show the min one
|
||||
if (curr_cam->isOrthogonal())
|
||||
return m_detail.size() - 1;
|
||||
|
||||
return -1;
|
||||
} // getLevel
|
||||
|
||||
@ -104,7 +100,7 @@ int LODNode::getLevel()
|
||||
* camera is activated, since it zooms in to the kart. */
|
||||
void LODNode::forceLevelOfDetail(int n)
|
||||
{
|
||||
m_forced_lod = (n >=(int)m_detail.size()) ? m_detail.size()-1 : n;
|
||||
m_forced_lod = (n >=(int)m_detail.size()) ? (int)m_detail.size()-1 : n;
|
||||
} // forceLevelOfDetail
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -144,7 +140,7 @@ void LODNode::updateVisibility(bool* shown)
|
||||
if (!isVisible()) return;
|
||||
if (m_nodes.size() == 0) return;
|
||||
|
||||
int level = getLevel();
|
||||
unsigned int level = getLevel();
|
||||
for (size_t i = 0; i < m_nodes.size(); i++)
|
||||
{
|
||||
m_nodes[i]->setVisible(i == level);
|
||||
@ -165,7 +161,6 @@ void LODNode::OnRegisterSceneNode()
|
||||
m_nodes[0]->getType() == scene::ESNT_ANIMATED_MESH) &&
|
||||
now > m_last_tick)
|
||||
{
|
||||
int level = getLevel();
|
||||
if (m_previous_visibility == WAS_HIDDEN && shown)
|
||||
{
|
||||
scene::IMesh* mesh;
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "modes/world.hpp"
|
||||
#include "tracks/track.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
|
||||
#include <IMaterialRendererServices.h>
|
||||
#include <ISceneNode.h>
|
||||
@ -50,9 +51,8 @@ const unsigned int VCLAMP = 2;
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Create a new material using the parameters specified in the xml file.
|
||||
* \param node Node containing the parameters for this material.
|
||||
* \param index Index in material_manager.
|
||||
*/
|
||||
Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
Material::Material(const XMLNode *node, bool deprecated)
|
||||
{
|
||||
m_shader_type = SHADERTYPE_SOLID;
|
||||
m_deprecated = deprecated;
|
||||
@ -64,7 +64,7 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
throw std::runtime_error("[Material] No texture name specified "
|
||||
"in file\n");
|
||||
}
|
||||
init(index);
|
||||
init();
|
||||
|
||||
bool b = false;
|
||||
|
||||
@ -396,26 +396,25 @@ Material::Material(const XMLNode *node, int index, bool deprecated)
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Create a standard material using the default settings for materials.
|
||||
* \param fname Name of the texture file.
|
||||
* \param index Unique index in material_manager.
|
||||
* \param is_full_path If the fname contains the full path.
|
||||
*/
|
||||
Material::Material(const std::string& fname, int index, bool is_full_path,
|
||||
bool complain_if_not_found)
|
||||
Material::Material(const std::string& fname, bool is_full_path,
|
||||
bool complain_if_not_found, bool load_texture)
|
||||
{
|
||||
m_deprecated = false;
|
||||
|
||||
m_texname = fname;
|
||||
init(index);
|
||||
install(is_full_path, complain_if_not_found);
|
||||
init();
|
||||
|
||||
if (load_texture)
|
||||
install(is_full_path, complain_if_not_found);
|
||||
} // Material
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Inits all material data with the default settings.
|
||||
* \param Index of this material in the material_manager index array.
|
||||
*/
|
||||
void Material::init(unsigned int index)
|
||||
void Material::init()
|
||||
{
|
||||
m_index = index;
|
||||
m_clamp_tex = 0;
|
||||
m_shader_type = SHADERTYPE_SOLID;
|
||||
//m_lightmap = false;
|
||||
@ -606,7 +605,7 @@ void Material::initParticlesEffect(const XMLNode *node)
|
||||
std::vector<std::string> conditions;
|
||||
node->get("condition", &conditions);
|
||||
|
||||
const int count = conditions.size();
|
||||
const int count = (int)conditions.size();
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
@ -679,10 +678,6 @@ void Material::setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) con
|
||||
*/
|
||||
void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* mb)
|
||||
{
|
||||
// !!======== This method is only called for materials that can be found in
|
||||
// materials.xml, if you want to set flags for all surfaces, see
|
||||
// 'MaterialManager::setAllMaterialFlags'
|
||||
|
||||
if (m_deprecated ||
|
||||
(m->getTexture(0) != NULL &&
|
||||
((core::stringc)m->getTexture(0)->getName()).find("deprecated") != -1))
|
||||
@ -691,20 +686,140 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
m_texname.c_str());
|
||||
}
|
||||
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SOLID_UNLIT)
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
ITexture *tex;
|
||||
ITexture *glossytex;
|
||||
if (m_gloss_map.size() > 0)
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_OBJECT_UNLIT);
|
||||
glossytex = irr_driver->getTexture(m_gloss_map);
|
||||
}
|
||||
else
|
||||
{
|
||||
m->AmbientColor = video::SColor(255, 255, 255, 255);
|
||||
m->DiffuseColor = video::SColor(255, 255, 255, 255);
|
||||
m->EmissiveColor = video::SColor(255, 255, 255, 255);
|
||||
m->SpecularColor = video::SColor(255, 255, 255, 255);
|
||||
glossytex = getUnicolorTexture(SColor(0, 0, 0, 0));
|
||||
}
|
||||
switch (m_shader_type)
|
||||
{
|
||||
case SHADERTYPE_SOLID_UNLIT:
|
||||
m->MaterialType = irr_driver->getShader(ES_OBJECT_UNLIT);
|
||||
m->setTexture(1, glossytex);
|
||||
return;
|
||||
case SHADERTYPE_ALPHA_TEST:
|
||||
m->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
m->setTexture(1, glossytex);
|
||||
return;
|
||||
case SHADERTYPE_ALPHA_BLEND:
|
||||
m->MaterialType = video::EMT_ONETEXTURE_BLEND;
|
||||
m->MaterialTypeParam =
|
||||
pack_textureBlendFunc(video::EBF_SRC_ALPHA,
|
||||
video::EBF_ONE_MINUS_SRC_ALPHA,
|
||||
video::EMFN_MODULATE_1X,
|
||||
video::EAS_TEXTURE | video::EAS_VERTEX_COLOR);
|
||||
return;
|
||||
case SHADERTYPE_ADDITIVE:
|
||||
m->MaterialType = video::EMT_ONETEXTURE_BLEND;
|
||||
m->MaterialTypeParam = pack_textureBlendFunc(video::EBF_SRC_ALPHA,
|
||||
video::EBF_ONE,
|
||||
video::EMFN_MODULATE_1X,
|
||||
video::EAS_TEXTURE |
|
||||
video::EAS_VERTEX_COLOR);
|
||||
return;
|
||||
case SHADERTYPE_SPHERE_MAP:
|
||||
m->MaterialType = irr_driver->getShader(ES_SPHERE_MAP);
|
||||
m->setTexture(1, glossytex);
|
||||
return;
|
||||
case SHADERTYPE_SPLATTING:
|
||||
tex = irr_driver->getTexture(m_splatting_texture_1);
|
||||
m->setTexture(2, tex);
|
||||
|
||||
if (m_splatting_texture_2.size() > 0)
|
||||
{
|
||||
tex = irr_driver->getTexture(m_splatting_texture_2);
|
||||
}
|
||||
m->setTexture(3, tex);
|
||||
|
||||
if (m_splatting_texture_3.size() > 0)
|
||||
{
|
||||
tex = irr_driver->getTexture(m_splatting_texture_3);
|
||||
}
|
||||
m->setTexture(4, tex);
|
||||
|
||||
if (m_splatting_texture_4.size() > 0)
|
||||
{
|
||||
tex = irr_driver->getTexture(m_splatting_texture_4);
|
||||
}
|
||||
m->setTexture(5, tex);
|
||||
m->setTexture(6, glossytex);
|
||||
|
||||
// Material and shaders
|
||||
m->MaterialType = irr_driver->getShader(ES_SPLATTING);
|
||||
return;
|
||||
case SHADERTYPE_WATER:
|
||||
m->setTexture(1, irr_driver->getTexture(FileManager::TEXTURE,
|
||||
"waternormals.jpg"));
|
||||
m->setTexture(2, irr_driver->getTexture(FileManager::TEXTURE,
|
||||
"waternormals2.jpg"));
|
||||
|
||||
((WaterShaderProvider *)irr_driver->getCallback(ES_WATER))->
|
||||
setSpeed(m_water_shader_speed_1 / 100.0f, m_water_shader_speed_2 / 100.0f);
|
||||
|
||||
m->MaterialType = irr_driver->getShader(ES_WATER);
|
||||
return;
|
||||
case SHADERTYPE_VEGETATION:
|
||||
// Only one grass speed & amplitude per map for now
|
||||
((GrassShaderProvider *)irr_driver->getCallback(ES_GRASS))->
|
||||
setSpeed(m_grass_speed);
|
||||
((GrassShaderProvider *)irr_driver->getCallback(ES_GRASS))->
|
||||
setAmplitude(m_grass_amplitude);
|
||||
m->MaterialType = irr_driver->getShader(ES_GRASS_REF);
|
||||
m->setTexture(1, glossytex);
|
||||
return;
|
||||
case SHADERTYPE_BUBBLE:
|
||||
if (mb)
|
||||
{
|
||||
BubbleEffectProvider * bubble = (BubbleEffectProvider *)
|
||||
irr_driver->getCallback(ES_BUBBLES);
|
||||
bubble->addBubble(mb);
|
||||
|
||||
m->MaterialType = irr_driver->getShader(ES_BUBBLES);
|
||||
m->BlendOperation = video::EBO_ADD;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m->getTexture(0))
|
||||
m->setTexture(0, getUnicolorTexture(SColor(255, 255, 255, 255)));
|
||||
|
||||
if (m_normal_map_tex.size() > 0)
|
||||
{
|
||||
tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
m->setTexture(2, tex);
|
||||
|
||||
// Material and shaders
|
||||
m->MaterialType = irr_driver->getShader(ES_NORMAL_MAP);
|
||||
m->setTexture(1, glossytex);
|
||||
return;
|
||||
}
|
||||
|
||||
// Detail map : move it to slot 3 and add glossy to slot 2
|
||||
// Sometimes the material will be parsed twice, in this case we dont want to swap 1 and 2 again.
|
||||
if (mb && mb->getVertexType() == video::EVT_2TCOORDS)
|
||||
{
|
||||
if (m->getTexture(1) != glossytex)
|
||||
m->setTexture(2, m->getTexture(1));
|
||||
if (!m->getTexture(2))
|
||||
m->setTexture(2, getUnicolorTexture(SColor(255, 255, 255, 255)));
|
||||
}
|
||||
m->setTexture(1, glossytex);
|
||||
}
|
||||
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SOLID_UNLIT)
|
||||
{
|
||||
m->AmbientColor = video::SColor(255, 255, 255, 255);
|
||||
m->DiffuseColor = video::SColor(255, 255, 255, 255);
|
||||
m->EmissiveColor = video::SColor(255, 255, 255, 255);
|
||||
m->SpecularColor = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_ALPHA_TEST)
|
||||
@ -725,127 +840,33 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
video::EAS_TEXTURE | video::EAS_VERTEX_COLOR);
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SPHERE_MAP)
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
m->MaterialType = irr_driver->getShader(ES_SPHERE_MAP);
|
||||
}
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_SPHERE_MAP;
|
||||
}
|
||||
}
|
||||
|
||||
//if (m_lightmap)
|
||||
//{
|
||||
// m->MaterialType = video::EMT_LIGHTMAP;
|
||||
//}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_ADDITIVE)
|
||||
{
|
||||
// EMT_TRANSPARENT_ADD_COLOR doesn't include vertex color alpha into
|
||||
// account, which messes up fading in/out effects. So we use the
|
||||
// more customizable EMT_ONETEXTURE_BLEND instead
|
||||
m->MaterialType = video::EMT_ONETEXTURE_BLEND ;
|
||||
m->MaterialType = video::EMT_ONETEXTURE_BLEND;
|
||||
m->MaterialTypeParam = pack_textureBlendFunc(video::EBF_SRC_ALPHA,
|
||||
video::EBF_ONE,
|
||||
video::EMFN_MODULATE_1X,
|
||||
video::EAS_TEXTURE |
|
||||
video::EAS_VERTEX_COLOR);
|
||||
video::EBF_ONE,
|
||||
video::EMFN_MODULATE_1X,
|
||||
video::EAS_TEXTURE |
|
||||
video::EAS_VERTEX_COLOR);
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SPHERE_MAP)
|
||||
{
|
||||
m->MaterialType = video::EMT_SPHERE_MAP;
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SOLID && m_normal_map_tex.size() > 0)
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
// FIXME; cannot perform this check atm, because setMaterialProperties
|
||||
// is sometimes called before calculating tangents
|
||||
//if (mb->getVertexType() != video::EVT_TANGENTS)
|
||||
//{
|
||||
// Log::warn("material", "Requiring normal map without tangent enabled mesh for <%s>",
|
||||
// m_texname.c_str());
|
||||
//}
|
||||
|
||||
ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
m->setTexture(1, tex);
|
||||
|
||||
bool with_lightmap = false;
|
||||
|
||||
//if (m_normal_map_shader_lightmap.size() > 0)
|
||||
//{
|
||||
// ITexture* lm_tex = irr_driver->getTexture(m_normal_map_shader_lightmap);
|
||||
// m->setTexture(2, lm_tex);
|
||||
// with_lightmap = true;
|
||||
//}
|
||||
|
||||
// Material and shaders
|
||||
m->MaterialType = irr_driver->getShader(
|
||||
with_lightmap ? ES_NORMAL_MAP_LIGHTMAP : ES_NORMAL_MAP);
|
||||
m->Lighting = false;
|
||||
m->ZWriteEnable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove normal map texture so that it's not blended with the rest
|
||||
m->setTexture(1, NULL);
|
||||
}
|
||||
// remove normal map texture so that it's not blended with the rest
|
||||
m->setTexture(1, NULL);
|
||||
}
|
||||
//if (m_parallax_map)
|
||||
//{
|
||||
// video::ITexture* tex = irr_driver->getTexture(m_normal_map_tex);
|
||||
// if (m_is_heightmap)
|
||||
// {
|
||||
// irr_driver->getVideoDriver()->makeNormalMapTexture( tex );
|
||||
// }
|
||||
// m->setTexture(1, tex);
|
||||
// m->MaterialType = video::EMT_PARALLAX_MAP_SOLID;
|
||||
// m->MaterialTypeParam = m_parallax_height;
|
||||
// m->SpecularColor.set(0,0,0,0);
|
||||
// modes++;
|
||||
//}
|
||||
|
||||
//if(m_graphical_effect == GE_SKYBOX && irr_driver->isGLSL())
|
||||
//{
|
||||
// ITexture* tex = irr_driver->getTexture("cloud_mask.png");
|
||||
// m->setTexture(1, tex);
|
||||
//
|
||||
//
|
||||
// m->MaterialType = irr_driver->getShader(ES_SKYBOX);
|
||||
//}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_SPLATTING)
|
||||
{
|
||||
if (irr_driver->supportsSplatting())
|
||||
{
|
||||
ITexture* tex = irr_driver->getTexture(m_splatting_texture_1);
|
||||
m->setTexture(2, tex);
|
||||
|
||||
if (m_splatting_texture_2.size() > 0)
|
||||
{
|
||||
tex = irr_driver->getTexture(m_splatting_texture_2);
|
||||
}
|
||||
m->setTexture(3, tex);
|
||||
|
||||
if (m_splatting_texture_3.size() > 0)
|
||||
{
|
||||
tex = irr_driver->getTexture(m_splatting_texture_3);
|
||||
}
|
||||
m->setTexture(4, tex);
|
||||
|
||||
if (m_splatting_texture_4.size() > 0)
|
||||
{
|
||||
tex = irr_driver->getTexture(m_splatting_texture_4);
|
||||
}
|
||||
m->setTexture(5, tex);
|
||||
|
||||
// Material and shaders
|
||||
m->MaterialType = irr_driver->getShader(ES_SPLATTING);
|
||||
}
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_SOLID;
|
||||
}
|
||||
m->MaterialType = video::EMT_SOLID;
|
||||
}
|
||||
|
||||
|
||||
@ -861,62 +882,9 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
m->SpecularColor = video::SColor(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_BUBBLE && mb != NULL)
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
BubbleEffectProvider * bubble = (BubbleEffectProvider *)
|
||||
irr_driver->getCallback(ES_BUBBLES);
|
||||
bubble->addBubble(mb);
|
||||
|
||||
m->MaterialType = irr_driver->getShader(ES_BUBBLES);
|
||||
m->BlendOperation = video::EBO_ADD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (m_shader_type == SHADERTYPE_WATER)
|
||||
{
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
m->setTexture(1, irr_driver->getTexture(FileManager::TEXTURE,
|
||||
"waternormals.jpg"));
|
||||
m->setTexture(2, irr_driver->getTexture(FileManager::TEXTURE,
|
||||
"waternormals2.jpg"));
|
||||
|
||||
((WaterShaderProvider *) irr_driver->getCallback(ES_WATER))->
|
||||
setSpeed(m_water_shader_speed_1/100.0f, m_water_shader_speed_2/100.0f);
|
||||
|
||||
m->MaterialType = irr_driver->getShader(ES_WATER);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_shader_type == SHADERTYPE_VEGETATION)
|
||||
{
|
||||
if (UserConfigParams::m_weather_effects &&
|
||||
irr_driver->isGLSL())
|
||||
{
|
||||
// Only one grass speed & amplitude per map for now
|
||||
((GrassShaderProvider *) irr_driver->getCallback(ES_GRASS))->
|
||||
setSpeed(m_grass_speed);
|
||||
((GrassShaderProvider *) irr_driver->getCallback(ES_GRASS))->
|
||||
setAmplitude(m_grass_amplitude);
|
||||
|
||||
// Material and shaders
|
||||
//if (m_alpha_testing)
|
||||
//{
|
||||
m->MaterialType = irr_driver->getShader(ES_GRASS_REF);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// m->MaterialType = irr_driver->getShader(ES_GRASS);
|
||||
// m->BlendOperation = video::EBO_ADD;
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
m->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
}
|
||||
m->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
}
|
||||
|
||||
if (m_disable_z_write)
|
||||
@ -985,9 +953,6 @@ void Material::setMaterialProperties(video::SMaterial *m, scene::IMeshBuffer* m
|
||||
}
|
||||
#endif
|
||||
|
||||
//if (UserConfigParams::m_fullscreen_antialiasing)
|
||||
// m->AntiAliasing = video::EAAM_LINE_SMOOTH;
|
||||
|
||||
} // setMaterialProperties
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
private:
|
||||
|
||||
video::ITexture *m_texture;
|
||||
unsigned int m_index;
|
||||
//unsigned int m_index;
|
||||
std::string m_texname;
|
||||
/** Name of a special sfx to play when a kart is on this terrain, or
|
||||
* "" if no special sfx exists. */
|
||||
@ -228,16 +228,17 @@ private:
|
||||
|
||||
bool m_deprecated;
|
||||
|
||||
void init (unsigned int index);
|
||||
void init ();
|
||||
void install (bool is_full_path=false, bool complain_if_not_found=true);
|
||||
void initCustomSFX(const XMLNode *sfx);
|
||||
void initParticlesEffect(const XMLNode *node);
|
||||
|
||||
public:
|
||||
Material(const XMLNode *node, int index, bool deprecated);
|
||||
Material(const std::string& fname, int index,
|
||||
Material(const XMLNode *node, bool deprecated);
|
||||
Material(const std::string& fname,
|
||||
bool is_full_path=false,
|
||||
bool complain_if_not_found=true);
|
||||
bool complain_if_not_found=true,
|
||||
bool load_texture = true);
|
||||
~Material ();
|
||||
|
||||
void setSFXSpeed(SFXBase *sfx, float speed, bool should_be_paused) const;
|
||||
@ -261,7 +262,7 @@ public:
|
||||
bool highTireAdhesion () const { return m_high_tire_adhesion; }
|
||||
const std::string&
|
||||
getTexFname () const { return m_texname; }
|
||||
int getIndex () const { return m_index; }
|
||||
//int getIndex () const { return m_index; }
|
||||
|
||||
bool isTransparent () const
|
||||
{
|
||||
|
@ -40,6 +40,7 @@ MaterialManager::MaterialManager()
|
||||
{
|
||||
/* Create list - and default material zero */
|
||||
|
||||
m_default_material = NULL;
|
||||
m_materials.reserve(256);
|
||||
// We can't call init/loadMaterial here, since the global variable
|
||||
// material_manager has not yet been initialised, and
|
||||
@ -95,6 +96,11 @@ void MaterialManager::setAllMaterialFlags(video::ITexture* t,
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_default_material == NULL)
|
||||
m_default_material = new Material("", false, false, false);
|
||||
m_default_material->setMaterialProperties(&(mb->getMaterial()), mb);
|
||||
|
||||
/*
|
||||
// This material does not appear in materials.xml. Set some common flags...
|
||||
if (UserConfigParams::m_anisotropic > 0)
|
||||
{
|
||||
@ -132,7 +138,7 @@ void MaterialManager::setAllMaterialFlags(video::ITexture* t,
|
||||
|
||||
//if (UserConfigParams::m_fullscreen_antialiasing)
|
||||
// mb->getMaterial().AntiAliasing = video::EAAM_LINE_SMOOTH;
|
||||
|
||||
*/
|
||||
} // setAllMaterialFlags
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -156,7 +162,7 @@ void MaterialManager::adjustForFog(video::ITexture* t,
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MaterialManager::setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb) const
|
||||
void MaterialManager::setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb)
|
||||
{
|
||||
irr::video::SMaterial& material = mb->getMaterial();
|
||||
if (material.getTexture(0) == NULL)
|
||||
@ -169,6 +175,10 @@ void MaterialManager::setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb) cons
|
||||
material.ColorMaterial = irr::video::ECM_DIFFUSE_AND_AMBIENT;
|
||||
material.MaterialType = irr::video::EMT_SOLID;
|
||||
}
|
||||
|
||||
if (m_default_material == NULL)
|
||||
m_default_material = new Material("", false, false, false);
|
||||
m_default_material->setMaterialProperties(&(mb->getMaterial()), mb);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
int MaterialManager::addEntity(Material *m)
|
||||
@ -244,7 +254,7 @@ bool MaterialManager::pushTempMaterial(const XMLNode *root,
|
||||
}
|
||||
try
|
||||
{
|
||||
m_materials.push_back(new Material(node, m_materials.size(), deprecated));
|
||||
m_materials.push_back(new Material(node, deprecated));
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
@ -311,7 +321,7 @@ Material *MaterialManager::getMaterial(const std::string& fname,
|
||||
}
|
||||
|
||||
// Add the new material
|
||||
Material* m=new Material(fname, m_materials.size(), is_full_path, complain_if_not_found);
|
||||
Material* m = new Material(fname, is_full_path, complain_if_not_found);
|
||||
m_materials.push_back(m);
|
||||
if(make_permanent)
|
||||
{
|
||||
@ -327,7 +337,7 @@ Material *MaterialManager::getMaterial(const std::string& fname,
|
||||
*/
|
||||
void MaterialManager::makeMaterialsPermanent()
|
||||
{
|
||||
m_shared_material_index = m_materials.size();
|
||||
m_shared_material_index = (int) m_materials.size();
|
||||
} // makeMaterialsPermanent
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -47,6 +47,9 @@ private:
|
||||
int m_shared_material_index;
|
||||
|
||||
std::vector<Material*> m_materials;
|
||||
|
||||
Material* m_default_material;
|
||||
|
||||
public:
|
||||
MaterialManager();
|
||||
~MaterialManager();
|
||||
@ -60,7 +63,7 @@ public:
|
||||
scene::ISceneNode* parent,
|
||||
bool use_fog) const;
|
||||
|
||||
void setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb) const;
|
||||
void setAllUntexturedMaterialFlags(scene::IMeshBuffer *mb);
|
||||
|
||||
int addEntity (Material *m);
|
||||
Material *getMaterial (const std::string& t,
|
||||
|
@ -174,7 +174,8 @@ void IrrDriver::renderGLSL(float dt)
|
||||
oss << "drawAll() for kart " << cam;
|
||||
PROFILER_PUSH_CPU_MARKER(oss.str().c_str(), (cam+1)*60,
|
||||
0x00, 0x00);
|
||||
// camera->activate();
|
||||
if (!UserConfigParams::m_dynamic_lights)
|
||||
camera->activate();
|
||||
rg->preRenderCallback(camera); // adjusts start referee
|
||||
m_scene_manager->setActiveCamera(camnode);
|
||||
|
||||
@ -261,7 +262,8 @@ void IrrDriver::renderGLSL(float dt)
|
||||
{
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
camera->activate();
|
||||
if (UserConfigParams::m_dynamic_lights)
|
||||
camera->activate();
|
||||
m_post_processing->renderPassThrough(fbo->getRTT()[0]);
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
@ -907,4 +909,4 @@ void IrrDriver::renderGlow(std::vector<GlowData>& glows)
|
||||
m_rtts->getFBO(FBO_COLORS).Bind();
|
||||
m_post_processing->renderGlow(m_rtts->getRenderTarget(RTT_QUARTER1));
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,6 @@
|
||||
/**
|
||||
\page render_geometry Geometry Rendering Overview
|
||||
|
||||
/**
|
||||
\section adding_material Adding a solid material
|
||||
|
||||
You need to consider twice before adding a new material : in the worst case a material requires 8 shaders :
|
||||
@ -77,6 +76,145 @@ layout(location = 6) in vec3 Bitangent;
|
||||
|
||||
*/
|
||||
|
||||
struct DefaultMaterial
|
||||
{
|
||||
typedef MeshShader::InstancedObjectPass1Shader InstancedFirstPassShader;
|
||||
typedef MeshShader::InstancedObjectPass2Shader InstancedSecondPassShader;
|
||||
typedef ListInstancedMatDefault InstancedList;
|
||||
typedef MeshShader::ObjectPass1Shader FirstPassShader;
|
||||
typedef MeshShader::ObjectPass2Shader SecondPassShader;
|
||||
typedef ListMatDefault List;
|
||||
static const enum E_VERTEX_TYPE VertexType = video::EVT_STANDARD;
|
||||
static const enum MeshMaterial MaterialType = MAT_DEFAULT;
|
||||
static const enum InstanceType Instance = InstanceTypeDualTex;
|
||||
static const std::vector<size_t> FirstPassTextures;
|
||||
static const std::vector<size_t> SecondPassTextures;
|
||||
};
|
||||
|
||||
const std::vector<size_t> DefaultMaterial::FirstPassTextures = { 1 };
|
||||
const std::vector<size_t> DefaultMaterial::SecondPassTextures = { 0 };
|
||||
|
||||
struct AlphaRef
|
||||
{
|
||||
typedef MeshShader::InstancedObjectRefPass1Shader InstancedFirstPassShader;
|
||||
typedef MeshShader::InstancedObjectRefPass2Shader InstancedSecondPassShader;
|
||||
typedef ListInstancedMatAlphaRef InstancedList;
|
||||
typedef MeshShader::ObjectRefPass1Shader FirstPassShader;
|
||||
typedef MeshShader::ObjectRefPass2Shader SecondPassShader;
|
||||
typedef ListMatAlphaRef List;
|
||||
static const enum E_VERTEX_TYPE VertexType = video::EVT_STANDARD;
|
||||
static const enum MeshMaterial MaterialType = MAT_ALPHA_REF;
|
||||
static const enum InstanceType Instance = InstanceTypeDualTex;
|
||||
static const std::vector<size_t> FirstPassTextures;
|
||||
static const std::vector<size_t> SecondPassTextures;
|
||||
};
|
||||
|
||||
const std::vector<size_t> AlphaRef::FirstPassTextures = { 0, 1 };
|
||||
const std::vector<size_t> AlphaRef::SecondPassTextures = { 0 };
|
||||
|
||||
struct SphereMap
|
||||
{
|
||||
typedef MeshShader::InstancedObjectPass1Shader InstancedFirstPassShader;
|
||||
typedef MeshShader::InstancedSphereMapShader InstancedSecondPassShader;
|
||||
typedef ListInstancedMatSphereMap InstancedList;
|
||||
typedef MeshShader::ObjectPass1Shader FirstPassShader;
|
||||
typedef MeshShader::SphereMapShader SecondPassShader;
|
||||
typedef ListMatSphereMap List;
|
||||
static const enum E_VERTEX_TYPE VertexType = video::EVT_STANDARD;
|
||||
static const enum MeshMaterial MaterialType = MAT_SPHEREMAP;
|
||||
static const enum InstanceType Instance = InstanceTypeDualTex;
|
||||
static const std::vector<size_t> FirstPassTextures;
|
||||
static const std::vector<size_t> SecondPassTextures;
|
||||
};
|
||||
|
||||
const std::vector<size_t> SphereMap::FirstPassTextures = { 1 };
|
||||
const std::vector<size_t> SphereMap::SecondPassTextures = { 0 };
|
||||
|
||||
struct UnlitMat
|
||||
{
|
||||
typedef MeshShader::InstancedObjectRefPass1Shader InstancedFirstPassShader;
|
||||
typedef MeshShader::InstancedObjectUnlitShader InstancedSecondPassShader;
|
||||
typedef ListInstancedMatUnlit InstancedList;
|
||||
typedef MeshShader::ObjectRefPass1Shader FirstPassShader;
|
||||
typedef MeshShader::ObjectUnlitShader SecondPassShader;
|
||||
typedef ListMatUnlit List;
|
||||
static const enum E_VERTEX_TYPE VertexType = video::EVT_STANDARD;
|
||||
static const enum MeshMaterial MaterialType = MAT_UNLIT;
|
||||
static const enum InstanceType Instance = InstanceTypeDualTex;
|
||||
static const std::vector<size_t> FirstPassTextures;
|
||||
static const std::vector<size_t> SecondPassTextures;
|
||||
};
|
||||
|
||||
const std::vector<size_t> UnlitMat::FirstPassTextures = { 0, 1 };
|
||||
const std::vector<size_t> UnlitMat::SecondPassTextures = { 0 };
|
||||
|
||||
struct GrassMat
|
||||
{
|
||||
typedef MeshShader::InstancedGrassPass1Shader InstancedFirstPassShader;
|
||||
typedef MeshShader::InstancedGrassPass2Shader InstancedSecondPassShader;
|
||||
typedef ListInstancedMatGrass InstancedList;
|
||||
typedef MeshShader::GrassPass1Shader FirstPassShader;
|
||||
typedef MeshShader::GrassPass2Shader SecondPassShader;
|
||||
typedef ListMatGrass List;
|
||||
static const enum E_VERTEX_TYPE VertexType = video::EVT_STANDARD;
|
||||
static const enum MeshMaterial MaterialType = MAT_GRASS;
|
||||
static const enum InstanceType Instance = InstanceTypeDualTex;
|
||||
static const std::vector<size_t> FirstPassTextures;
|
||||
static const std::vector<size_t> SecondPassTextures;
|
||||
};
|
||||
|
||||
const std::vector<size_t> GrassMat::FirstPassTextures = { 0 };
|
||||
const std::vector<size_t> GrassMat::SecondPassTextures = { 0 };
|
||||
|
||||
struct NormalMat
|
||||
{
|
||||
typedef MeshShader::InstancedNormalMapShader InstancedFirstPassShader;
|
||||
typedef MeshShader::InstancedObjectPass2Shader InstancedSecondPassShader;
|
||||
typedef ListInstancedMatNormalMap InstancedList;
|
||||
typedef MeshShader::NormalMapShader FirstPassShader;
|
||||
typedef MeshShader::ObjectPass2Shader SecondPassShader;
|
||||
typedef ListMatNormalMap List;
|
||||
static const enum E_VERTEX_TYPE VertexType = video::EVT_TANGENTS;
|
||||
static const enum MeshMaterial MaterialType = MAT_NORMAL_MAP;
|
||||
static const enum InstanceType Instance = InstanceTypeThreeTex;
|
||||
static const std::vector<size_t> FirstPassTextures;
|
||||
static const std::vector<size_t> SecondPassTextures;
|
||||
};
|
||||
|
||||
const std::vector<size_t> NormalMat::FirstPassTextures = { 2, 1 };
|
||||
const std::vector<size_t> NormalMat::SecondPassTextures = { 0 };
|
||||
|
||||
struct DetailMat
|
||||
{
|
||||
typedef MeshShader::InstancedObjectPass1Shader InstancedFirstPassShader;
|
||||
typedef MeshShader::InstancedDetailledObjectPass2Shader InstancedSecondPassShader;
|
||||
typedef ListInstancedMatDetails InstancedList;
|
||||
typedef MeshShader::ObjectPass1Shader FirstPassShader;
|
||||
typedef MeshShader::DetailledObjectPass2Shader SecondPassShader;
|
||||
typedef ListMatDetails List;
|
||||
static const enum E_VERTEX_TYPE VertexType = video::EVT_2TCOORDS;
|
||||
static const enum MeshMaterial MaterialType = MAT_DETAIL;
|
||||
static const enum InstanceType Instance = InstanceTypeThreeTex;
|
||||
static const std::vector<size_t> FirstPassTextures;
|
||||
static const std::vector<size_t> SecondPassTextures;
|
||||
};
|
||||
|
||||
const std::vector<size_t> DetailMat::FirstPassTextures = { 1 };
|
||||
const std::vector<size_t> DetailMat::SecondPassTextures = { 0, 2 };
|
||||
|
||||
struct SplattingMat
|
||||
{
|
||||
typedef MeshShader::ObjectPass1Shader FirstPassShader;
|
||||
typedef MeshShader::SplattingShader SecondPassShader;
|
||||
typedef ListMatSplatting List;
|
||||
static const enum E_VERTEX_TYPE VertexType = video::EVT_2TCOORDS;
|
||||
static const std::vector<size_t> FirstPassTextures;
|
||||
static const std::vector<size_t> SecondPassTextures;
|
||||
};
|
||||
|
||||
const std::vector<size_t> SplattingMat::FirstPassTextures = { 6 };
|
||||
const std::vector<size_t> SplattingMat::SecondPassTextures = { 1, 2, 3, 4, 5 };
|
||||
|
||||
namespace RenderGeometry
|
||||
{
|
||||
struct TexUnit
|
||||
@ -160,12 +298,14 @@ struct custom_unroll_args<N, List...>
|
||||
};
|
||||
|
||||
|
||||
template<typename Shader, enum E_VERTEX_TYPE VertexType, int ...List, typename... TupleType>
|
||||
void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > &meshes)
|
||||
template<typename T, int ...List>
|
||||
void renderMeshes1stPass()
|
||||
{
|
||||
glUseProgram(Shader::getInstance()->Program);
|
||||
const std::vector<size_t> &TexUnits = T::FirstPassTextures;
|
||||
auto &meshes = T::List::getInstance()->SolidPass;
|
||||
glUseProgram(T::FirstPassShader::getInstance()->Program);
|
||||
if (irr_driver->hasARB_base_instance())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||
for (unsigned i = 0; i < meshes.size(); i++)
|
||||
{
|
||||
std::vector<GLuint> Textures;
|
||||
@ -176,11 +316,11 @@ void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
|
||||
for (unsigned j = 0; j < TexUnits.size(); j++)
|
||||
{
|
||||
if (UserConfigParams::m_azdo)
|
||||
Handles.push_back(mesh.TextureHandles[TexUnits[j].m_id]);
|
||||
Handles.push_back(mesh.TextureHandles[TexUnits[j]]);
|
||||
else
|
||||
Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j].m_id]));
|
||||
Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j]]));
|
||||
}
|
||||
if (mesh.VAOType != VertexType)
|
||||
if (mesh.VAOType != T::VertexType)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::error("Materials", "Wrong vertex Type associed to pass 1 (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str());
|
||||
@ -189,46 +329,49 @@ void renderMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
|
||||
}
|
||||
|
||||
if (UserConfigParams::m_azdo)
|
||||
Shader::getInstance()->SetTextureHandles(Handles);
|
||||
T::FirstPassShader::getInstance()->SetTextureHandles(Handles);
|
||||
else
|
||||
Shader::getInstance()->SetTextureUnits(Textures);
|
||||
custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes.at(i));
|
||||
T::FirstPassShader::getInstance()->SetTextureUnits(Textures);
|
||||
custom_unroll_args<List...>::template exec(T::FirstPassShader::getInstance(), meshes.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
||||
void renderInstancedMeshes1stPass(const std::vector<TexUnit> &TexUnits, std::vector<GLMesh *> &meshes, Args...args)
|
||||
template<typename T, typename...Args>
|
||||
void renderInstancedMeshes1stPass(Args...args)
|
||||
{
|
||||
glUseProgram(Shader::getInstance()->Program);
|
||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeDefault));
|
||||
const std::vector<size_t> &TexUnits = T::FirstPassTextures;
|
||||
std::vector<GLMesh *> &meshes = T::InstancedList::getInstance()->SolidPass;
|
||||
glUseProgram(T::InstancedFirstPassShader::getInstance()->Program);
|
||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance));
|
||||
for (unsigned i = 0; i < meshes.size(); i++)
|
||||
{
|
||||
std::vector<GLuint> Textures;
|
||||
GLMesh *mesh = meshes[i];
|
||||
#ifdef DEBUG
|
||||
if (mesh->VAOType != VT)
|
||||
Log::error("RenderGeometry", "Wrong instanced vertex format");
|
||||
if (mesh->VAOType != T::VertexType)
|
||||
Log::error("RenderGeometry", "Wrong instanced vertex format (hint : %s)",
|
||||
mesh->textures[0]->getName().getPath().c_str());
|
||||
#endif
|
||||
for (unsigned j = 0; j < TexUnits.size(); j++)
|
||||
Textures.push_back(getTextureGLuint(mesh->textures[TexUnits[j].m_id]));
|
||||
Shader::getInstance()->SetTextureUnits(Textures);
|
||||
Textures.push_back(getTextureGLuint(mesh->textures[TexUnits[j]]));
|
||||
T::InstancedFirstPassShader::getInstance()->SetTextureUnits(Textures);
|
||||
|
||||
Shader::getInstance()->setUniforms(args...);
|
||||
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[Mat] + i) * sizeof(DrawElementsIndirectCommand)));
|
||||
T::InstancedFirstPassShader::getInstance()->setUniforms(args...);
|
||||
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand)));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
||||
template<typename T, typename...Args>
|
||||
void multidraw1stPass(Args...args)
|
||||
{
|
||||
glUseProgram(Shader::getInstance()->Program);
|
||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeDefault));
|
||||
if (SolidPassCmd::getInstance()->Size[Mat])
|
||||
glUseProgram(T::InstancedFirstPassShader::getInstance()->Program);
|
||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance));
|
||||
if (SolidPassCmd::getInstance()->Size[T::MaterialType])
|
||||
{
|
||||
Shader::getInstance()->setUniforms(args...);
|
||||
T::InstancedFirstPassShader::getInstance()->setUniforms(args...);
|
||||
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT,
|
||||
(const void*)(SolidPassCmd::getInstance()->Offset[Mat] * sizeof(DrawElementsIndirectCommand)),
|
||||
SolidPassCmd::getInstance()->Size[Mat],
|
||||
(const void*)(SolidPassCmd::getInstance()->Offset[T::MaterialType] * sizeof(DrawElementsIndirectCommand)),
|
||||
SolidPassCmd::getInstance()->Size[T::MaterialType],
|
||||
sizeof(DrawElementsIndirectCommand));
|
||||
}
|
||||
}
|
||||
@ -249,65 +392,48 @@ void IrrDriver::renderSolidFirstPass()
|
||||
for (unsigned i = 0; i < ImmediateDrawList::getInstance()->size(); i++)
|
||||
ImmediateDrawList::getInstance()->at(i)->render();
|
||||
|
||||
std::vector<TexUnit> object_pass1_texunits = TexUnits(TexUnit(0, true) );
|
||||
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatDefault::getInstance()->SolidPass);
|
||||
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(object_pass1_texunits, ListMatSplatting::getInstance()->SolidPass);
|
||||
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD, 3, 2, 1>(object_pass1_texunits, ListMatUnlit::getInstance()->SolidPass);
|
||||
renderMeshes1stPass<MeshShader::ObjectRefPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(0, true)), ListMatAlphaRef::getInstance()->SolidPass);
|
||||
renderMeshes1stPass<MeshShader::GrassPass1Shader, video::EVT_STANDARD, 3, 2, 1>(TexUnits(TexUnit(0, true)), ListMatGrass::getInstance()->SolidPass);
|
||||
renderMeshes1stPass<MeshShader::NormalMapShader, video::EVT_TANGENTS, 2, 1>(TexUnits(
|
||||
TexUnit(1, false),
|
||||
TexUnit(0, true)
|
||||
), ListMatNormalMap::getInstance()->SolidPass);
|
||||
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_STANDARD, 2, 1>(object_pass1_texunits, ListMatSphereMap::getInstance()->SolidPass);
|
||||
renderMeshes1stPass<MeshShader::ObjectPass1Shader, video::EVT_2TCOORDS, 2, 1>(object_pass1_texunits, ListMatDetails::getInstance()->SolidPass);
|
||||
renderMeshes1stPass<DefaultMaterial, 2, 1>();
|
||||
renderMeshes1stPass<SplattingMat, 2, 1>();
|
||||
renderMeshes1stPass<UnlitMat, 3, 2, 1>();
|
||||
renderMeshes1stPass<AlphaRef, 3, 2, 1>();
|
||||
renderMeshes1stPass<GrassMat, 3, 2, 1>();
|
||||
renderMeshes1stPass<NormalMat, 2, 1>();
|
||||
renderMeshes1stPass<SphereMap, 2, 1>();
|
||||
renderMeshes1stPass<DetailMat, 2, 1>();
|
||||
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
multidraw1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DEFAULT, video::EVT_STANDARD>();
|
||||
multidraw1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_ALPHA_REF, video::EVT_STANDARD>();
|
||||
multidraw1stPass<MeshShader::InstancedNormalMapShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>();
|
||||
multidraw1stPass<MeshShader::InstancedObjectPass1Shader, MAT_SPHEREMAP, video::EVT_STANDARD>();
|
||||
multidraw1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DETAIL, video::EVT_2TCOORDS>();
|
||||
multidraw1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_UNLIT, video::EVT_STANDARD>();
|
||||
multidraw1stPass<MeshShader::InstancedGrassPass1Shader, MAT_GRASS, video::EVT_STANDARD>(windDir);
|
||||
multidraw1stPass<DefaultMaterial>();
|
||||
multidraw1stPass<AlphaRef>();
|
||||
multidraw1stPass<SphereMap>();
|
||||
multidraw1stPass<UnlitMat>();
|
||||
multidraw1stPass<GrassMat>(windDir);
|
||||
|
||||
multidraw1stPass<NormalMat>();
|
||||
multidraw1stPass<DetailMat>();
|
||||
}
|
||||
else if (irr_driver->hasARB_draw_indirect())
|
||||
{
|
||||
// Default
|
||||
renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DEFAULT, video::EVT_STANDARD>(
|
||||
TexUnits(TexUnit(0, true)), ListInstancedMatDefault::getInstance()->SolidPass);
|
||||
// Alpha ref
|
||||
renderInstancedMeshes1stPass<MeshShader::InstancedObjectRefPass1Shader, MAT_ALPHA_REF, video::EVT_STANDARD>(
|
||||
TexUnits(TexUnit(0, true)), ListInstancedMatAlphaRef::getInstance()->SolidPass);
|
||||
// Unlit
|
||||
renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader, MAT_UNLIT, video::EVT_STANDARD>(
|
||||
TexUnits(TexUnit(0, true)), ListInstancedMatUnlit::getInstance()->SolidPass);
|
||||
// Spheremap
|
||||
renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader, MAT_SPHEREMAP, video::EVT_STANDARD>(
|
||||
TexUnits(TexUnit(0, true)), ListInstancedMatSphereMap::getInstance()->SolidPass);
|
||||
// Grass
|
||||
renderInstancedMeshes1stPass<MeshShader::InstancedGrassPass1Shader, MAT_GRASS, video::EVT_STANDARD>(
|
||||
TexUnits(TexUnit(0, true)), ListInstancedMatGrass::getInstance()->SolidPass, windDir);
|
||||
|
||||
// Detail
|
||||
renderInstancedMeshes1stPass<MeshShader::InstancedObjectPass1Shader, MAT_DETAIL, video::EVT_2TCOORDS>(
|
||||
TexUnits(TexUnit(0, true)), ListInstancedMatDetails::getInstance()->SolidPass);
|
||||
|
||||
// Normal Map
|
||||
renderInstancedMeshes1stPass<MeshShader::InstancedNormalMapShader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(
|
||||
TexUnits(TexUnit(1, false), TexUnit(0, true)), ListInstancedMatNormalMap::getInstance()->SolidPass);
|
||||
renderInstancedMeshes1stPass<DefaultMaterial>();
|
||||
renderInstancedMeshes1stPass<AlphaRef>();
|
||||
renderInstancedMeshes1stPass<UnlitMat>();
|
||||
renderInstancedMeshes1stPass<SphereMap>();
|
||||
renderInstancedMeshes1stPass<GrassMat>(windDir);
|
||||
renderInstancedMeshes1stPass<DetailMat>();
|
||||
renderInstancedMeshes1stPass<NormalMat>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Shader, enum E_VERTEX_TYPE VertexType, int...List, typename... TupleType>
|
||||
void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::Tuple<TupleType...> > &meshes, const std::vector<uint64_t> &Prefilled_Handle,
|
||||
template<typename T, int...List>
|
||||
void renderMeshes2ndPass( const std::vector<uint64_t> &Prefilled_Handle,
|
||||
const std::vector<GLuint> &Prefilled_Tex)
|
||||
{
|
||||
glUseProgram(Shader::getInstance()->Program);
|
||||
const std::vector<size_t> &TexUnits = T::SecondPassTextures;
|
||||
auto &meshes = T::List::getInstance()->SolidPass;
|
||||
glUseProgram(T::SecondPassShader::getInstance()->Program);
|
||||
if (irr_driver->hasARB_base_instance())
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(VertexType));
|
||||
glBindVertexArray(VAOManager::getInstance()->getVAO(T::VertexType));
|
||||
for (unsigned i = 0; i < meshes.size(); i++)
|
||||
{
|
||||
std::vector<uint64_t> Handles(Prefilled_Handle);
|
||||
@ -318,12 +444,12 @@ void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
|
||||
for (unsigned j = 0; j < TexUnits.size(); j++)
|
||||
{
|
||||
if (UserConfigParams::m_azdo)
|
||||
Handles.push_back(mesh.TextureHandles[TexUnits[j].m_id]);
|
||||
Handles.push_back(mesh.TextureHandles[TexUnits[j]]);
|
||||
else
|
||||
Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j].m_id]));
|
||||
Textures.push_back(getTextureGLuint(mesh.textures[TexUnits[j]]));
|
||||
}
|
||||
|
||||
if (mesh.VAOType != VertexType)
|
||||
if (mesh.VAOType != T::VertexType)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log::error("Materials", "Wrong vertex Type associed to pass 2 (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str());
|
||||
@ -332,42 +458,44 @@ void renderMeshes2ndPass(const std::vector<TexUnit> &TexUnits, std::vector<STK::
|
||||
}
|
||||
|
||||
if (UserConfigParams::m_azdo)
|
||||
Shader::getInstance()->SetTextureHandles(Handles);
|
||||
T::SecondPassShader::getInstance()->SetTextureHandles(Handles);
|
||||
else
|
||||
Shader::getInstance()->SetTextureUnits(Textures);
|
||||
custom_unroll_args<List...>::template exec(Shader::getInstance(), meshes.at(i));
|
||||
T::SecondPassShader::getInstance()->SetTextureUnits(Textures);
|
||||
custom_unroll_args<List...>::template exec(T::SecondPassShader::getInstance(), meshes.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
||||
void renderInstancedMeshes2ndPass(const std::vector<TexUnit> &TexUnits, const std::vector<GLuint> &Prefilled_tex, std::vector<GLMesh *> &meshes, Args...args)
|
||||
template<typename T, typename...Args>
|
||||
void renderInstancedMeshes2ndPass(const std::vector<GLuint> &Prefilled_tex, Args...args)
|
||||
{
|
||||
glUseProgram(Shader::getInstance()->Program);
|
||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeDefault));
|
||||
std::vector<GLMesh *> &meshes = T::InstancedList::getInstance()->SolidPass;
|
||||
const std::vector<size_t> &TexUnits = T::SecondPassTextures;
|
||||
glUseProgram(T::InstancedSecondPassShader::getInstance()->Program);
|
||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance));
|
||||
for (unsigned i = 0; i < meshes.size(); i++)
|
||||
{
|
||||
GLMesh *mesh = meshes[i];
|
||||
std::vector<GLuint> Textures(Prefilled_tex);
|
||||
for (unsigned j = 0; j < TexUnits.size(); j++)
|
||||
Textures.push_back(getTextureGLuint(mesh->textures[TexUnits[j].m_id]));
|
||||
Shader::getInstance()->SetTextureUnits(Textures);
|
||||
Shader::getInstance()->setUniforms(args...);
|
||||
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[Mat] + i) * sizeof(DrawElementsIndirectCommand)));
|
||||
Textures.push_back(getTextureGLuint(mesh->textures[TexUnits[j]]));
|
||||
T::InstancedSecondPassShader::getInstance()->SetTextureUnits(Textures);
|
||||
T::InstancedSecondPassShader::getInstance()->setUniforms(args...);
|
||||
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, (const void*)((SolidPassCmd::getInstance()->Offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand)));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Shader, MeshMaterial Mat, video::E_VERTEX_TYPE VT, typename...Args>
|
||||
template<typename T, typename...Args>
|
||||
void multidraw2ndPass(const std::vector<uint64_t> &Handles, Args... args)
|
||||
{
|
||||
glUseProgram(Shader::getInstance()->Program);
|
||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(VT, InstanceTypeDefault));
|
||||
if (SolidPassCmd::getInstance()->Size[Mat])
|
||||
glUseProgram(T::InstancedSecondPassShader::getInstance()->Program);
|
||||
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance));
|
||||
if (SolidPassCmd::getInstance()->Size[T::MaterialType])
|
||||
{
|
||||
Shader::getInstance()->SetTextureHandles(Handles);
|
||||
Shader::getInstance()->setUniforms(args...);
|
||||
T::InstancedSecondPassShader::getInstance()->SetTextureHandles(Handles);
|
||||
T::InstancedSecondPassShader::getInstance()->setUniforms(args...);
|
||||
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT,
|
||||
(const void*)(SolidPassCmd::getInstance()->Offset[Mat] * sizeof(DrawElementsIndirectCommand)),
|
||||
SolidPassCmd::getInstance()->Size[Mat],
|
||||
(const void*)(SolidPassCmd::getInstance()->Offset[T::MaterialType] * sizeof(DrawElementsIndirectCommand)),
|
||||
SolidPassCmd::getInstance()->Size[T::MaterialType],
|
||||
sizeof(DrawElementsIndirectCommand));
|
||||
}
|
||||
}
|
||||
@ -409,75 +537,39 @@ void IrrDriver::renderSolidSecondPass()
|
||||
|
||||
std::vector<GLuint> DiffSpecSSAOTex = createVector<GLuint>(m_rtts->getRenderTarget(RTT_DIFFUSE), m_rtts->getRenderTarget(RTT_SPECULAR), m_rtts->getRenderTarget(RTT_HALF1_R));
|
||||
|
||||
renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_STANDARD, 3, 1>(TexUnits(
|
||||
TexUnit(0, true)
|
||||
), ListMatDefault::getInstance()->SolidPass,
|
||||
createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<MeshShader::ObjectRefPass2Shader, video::EVT_STANDARD, 3, 1 >(TexUnits(
|
||||
TexUnit(0, true)
|
||||
), ListMatAlphaRef::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<MeshShader::ObjectUnlitShader, video::EVT_STANDARD, 3, 1>(TexUnits(
|
||||
TexUnit(0, true)
|
||||
), ListMatUnlit::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<MeshShader::SplattingShader, video::EVT_2TCOORDS, 1>(TexUnits(
|
||||
TexUnit(1, false),
|
||||
TexUnit(2, true),
|
||||
TexUnit(3, true),
|
||||
TexUnit(4, true),
|
||||
TexUnit(0, true)
|
||||
), ListMatSplatting::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<MeshShader::SphereMapShader, video::EVT_STANDARD, 2, 1>(TexUnits(
|
||||
TexUnit(0, true)
|
||||
), ListMatSphereMap::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<MeshShader::DetailledObjectPass2Shader, video::EVT_2TCOORDS, 1>(TexUnits(
|
||||
TexUnit(0, true),
|
||||
TexUnit(1, true)
|
||||
), ListMatDetails::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<MeshShader::GrassPass2Shader, video::EVT_STANDARD, 3, 1>(TexUnits(
|
||||
TexUnit(0, true)
|
||||
), ListMatGrass::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<MeshShader::ObjectPass2Shader, video::EVT_TANGENTS, 3, 1>(TexUnits(
|
||||
TexUnit(0, true)
|
||||
), ListMatNormalMap::getInstance()->SolidPass, createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<DefaultMaterial, 3, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<AlphaRef, 3, 1 >(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<UnlitMat, 3, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<SplattingMat, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<SphereMap, 2, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<DetailMat, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<GrassMat, 3, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
renderMeshes2ndPass<NormalMat, 3, 1>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle), DiffSpecSSAOTex);
|
||||
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
multidraw2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_DEFAULT, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||
multidraw2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||
multidraw2ndPass<MeshShader::InstancedObjectRefPass2Shader, MAT_ALPHA_REF, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||
multidraw2ndPass<MeshShader::InstancedSphereMapShader, MAT_SPHEREMAP, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||
multidraw2ndPass<MeshShader::InstancedDetailledObjectPass2Shader, MAT_DETAIL, video::EVT_2TCOORDS>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0));
|
||||
multidraw2ndPass<MeshShader::InstancedObjectUnlitShader, MAT_UNLIT, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||
multidraw2ndPass<DefaultMaterial>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||
multidraw2ndPass<AlphaRef>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||
multidraw2ndPass<SphereMap>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||
multidraw2ndPass<UnlitMat>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
|
||||
multidraw2ndPass<MeshShader::InstancedGrassPass2Shader, MAT_GRASS, video::EVT_STANDARD>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, DepthHandle, 0), windDir, cb->getPosition());
|
||||
multidraw2ndPass<GrassMat>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, DepthHandle, 0), windDir, cb->getPosition());
|
||||
|
||||
multidraw2ndPass<NormalMat>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0));
|
||||
multidraw2ndPass<DetailMat>(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, 0, 0));
|
||||
}
|
||||
else if (irr_driver->hasARB_draw_indirect())
|
||||
{
|
||||
// Default
|
||||
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_DEFAULT, video::EVT_STANDARD>(
|
||||
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatDefault::getInstance()->SolidPass);
|
||||
// Alpha ref
|
||||
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectRefPass2Shader, MAT_ALPHA_REF, video::EVT_STANDARD>(
|
||||
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatAlphaRef::getInstance()->SolidPass);
|
||||
// Unlit
|
||||
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectUnlitShader, MAT_UNLIT, video::EVT_STANDARD>(
|
||||
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatUnlit::getInstance()->SolidPass);
|
||||
// Spheremap
|
||||
renderInstancedMeshes2ndPass<MeshShader::InstancedSphereMapShader, MAT_SPHEREMAP, video::EVT_STANDARD>(
|
||||
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatSphereMap::getInstance()->SolidPass);
|
||||
// Details
|
||||
renderInstancedMeshes2ndPass<MeshShader::InstancedDetailledObjectPass2Shader, MAT_DETAIL, video::EVT_2TCOORDS>(
|
||||
TexUnits(TexUnit(0, true), TexUnit(1, false)), DiffSpecSSAOTex, ListInstancedMatDetails::getInstance()->SolidPass);
|
||||
|
||||
// Normal map
|
||||
renderInstancedMeshes2ndPass<MeshShader::InstancedObjectPass2Shader, MAT_NORMAL_MAP, video::EVT_TANGENTS>(
|
||||
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatNormalMap::getInstance()->SolidPass);
|
||||
|
||||
// Grass
|
||||
renderInstancedMeshes2ndPass<DefaultMaterial>(DiffSpecSSAOTex);
|
||||
renderInstancedMeshes2ndPass<AlphaRef>(DiffSpecSSAOTex);
|
||||
renderInstancedMeshes2ndPass<UnlitMat>(DiffSpecSSAOTex);
|
||||
renderInstancedMeshes2ndPass<SphereMap>(DiffSpecSSAOTex);
|
||||
SunLightProvider * const cb = (SunLightProvider *)irr_driver->getCallback(ES_SUNLIGHT);
|
||||
DiffSpecSSAOTex.push_back(irr_driver->getDepthStencilTexture());
|
||||
renderInstancedMeshes2ndPass<MeshShader::InstancedGrassPass2Shader, MAT_GRASS, video::EVT_STANDARD>(
|
||||
TexUnits(TexUnit(0, true)), DiffSpecSSAOTex, ListInstancedMatGrass::getInstance()->SolidPass, windDir, cb->getPosition());
|
||||
renderInstancedMeshes2ndPass<GrassMat>(DiffSpecSSAOTex, windDir, cb->getPosition());
|
||||
DiffSpecSSAOTex.pop_back();
|
||||
renderInstancedMeshes2ndPass<DetailMat>(DiffSpecSSAOTex);
|
||||
renderInstancedMeshes2ndPass<NormalMat>(DiffSpecSSAOTex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +119,6 @@ static void getYml(GLenum face, size_t width, size_t height,
|
||||
static float getTexelValue(unsigned i, unsigned j, size_t width, size_t height, float *Coeff, float *Y00, float *Y1minus1, float *Y10, float *Y11,
|
||||
float *Y2minus2, float * Y2minus1, float * Y20, float *Y21, float *Y22)
|
||||
{
|
||||
float d = sqrt((float)(i * i + j * j + 1));
|
||||
float solidangle = 1.;
|
||||
size_t idx = i * height + j;
|
||||
float reconstructedVal = Y00[idx] * Coeff[0];
|
||||
|
@ -89,8 +89,6 @@ RTT::RTT(size_t width, size_t height)
|
||||
const dimension2du shadowsize1(shadowside / 2, shadowside / 2);
|
||||
const dimension2du shadowsize2(shadowside / 4, shadowside / 4);
|
||||
const dimension2du shadowsize3(shadowside / 8, shadowside / 8);
|
||||
const dimension2du warpvsize(1, 512);
|
||||
const dimension2du warphsize(512, 1);
|
||||
|
||||
unsigned linear_depth_mip_levels = int(ceilf(log2f( float(max_(res.Width, res.Height)) )));
|
||||
|
||||
|
@ -785,7 +785,7 @@ namespace MeshShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/objectref_pass1.frag").c_str());
|
||||
AssignUniforms("ModelMatrix", "InverseModelMatrix", "TextureMatrix");
|
||||
AssignSamplerNames(Program, 0, "tex");
|
||||
AssignSamplerNames(Program, 0, "tex", 1, "glosstex");
|
||||
}
|
||||
|
||||
GrassPass1Shader::GrassPass1Shader()
|
||||
@ -817,7 +817,7 @@ namespace MeshShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_object_pass1.frag").c_str());
|
||||
|
||||
AssignUniforms();
|
||||
AssignSamplerNames(Program, 0, "tex");
|
||||
AssignSamplerNames(Program, 0, "glosstex");
|
||||
}
|
||||
|
||||
InstancedObjectRefPass1Shader::InstancedObjectRefPass1Shader()
|
||||
@ -829,7 +829,7 @@ namespace MeshShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_objectref_pass1.frag").c_str());
|
||||
|
||||
AssignUniforms();
|
||||
AssignSamplerNames(Program, 0, "tex");
|
||||
AssignSamplerNames(Program, 0, "tex", 1, "glosstex");
|
||||
}
|
||||
|
||||
InstancedGrassPass1Shader::InstancedGrassPass1Shader()
|
||||
@ -851,7 +851,7 @@ namespace MeshShader
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/utils/encode_normal.frag").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_normalmap.frag").c_str());
|
||||
AssignUniforms();
|
||||
AssignSamplerNames(Program, 0, "normalMap", 1, "DiffuseForAlpha");
|
||||
AssignSamplerNames(Program, 0, "normalMap", 1, "glossMap");
|
||||
}
|
||||
|
||||
// Solid Lit pass shaders
|
||||
@ -1199,14 +1199,14 @@ namespace MeshShader
|
||||
{
|
||||
Program = LoadProgram(OBJECT,
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow_grass.vert").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_shadowref.frag").c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Program = LoadProgram(OBJECT,
|
||||
GL_VERTEX_SHADER, file_manager->getAsset("shaders/shadow_grass.vert").c_str(),
|
||||
GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(),
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str());
|
||||
GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/instanced_shadowref.frag").c_str());
|
||||
}
|
||||
AssignUniforms("layer", "ModelMatrix", "windDir");
|
||||
AssignSamplerNames(Program, 0, "tex");
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
ObjectPass1Shader();
|
||||
};
|
||||
|
||||
class ObjectRefPass1Shader : public ShaderHelperSingleton<ObjectRefPass1Shader, core::matrix4, core::matrix4, core::matrix4>, public TextureRead<Trilinear_Anisotropic_Filtered>
|
||||
class ObjectRefPass1Shader : public ShaderHelperSingleton<ObjectRefPass1Shader, core::matrix4, core::matrix4, core::matrix4>, public TextureRead<Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered>
|
||||
{
|
||||
public:
|
||||
ObjectRefPass1Shader();
|
||||
@ -83,7 +83,7 @@ public:
|
||||
InstancedObjectPass1Shader();
|
||||
};
|
||||
|
||||
class InstancedObjectRefPass1Shader : public ShaderHelperSingleton<InstancedObjectRefPass1Shader>, public TextureRead<Trilinear_Anisotropic_Filtered>
|
||||
class InstancedObjectRefPass1Shader : public ShaderHelperSingleton<InstancedObjectRefPass1Shader>, public TextureRead<Trilinear_Anisotropic_Filtered, Trilinear_Anisotropic_Filtered>
|
||||
{
|
||||
public:
|
||||
InstancedObjectRefPass1Shader();
|
||||
|
@ -440,7 +440,8 @@ public:
|
||||
std::vector<GLuint> SamplersId;
|
||||
void SetTextureUnits(const std::vector<GLuint> &args)
|
||||
{
|
||||
assert(args.size() == sizeof...(tp) && "Too much texture unit provided");
|
||||
if (args.size() != sizeof...(tp))
|
||||
abort();
|
||||
if (getGLSLVersion() >= 330)
|
||||
{
|
||||
for (unsigned i = 0; i < args.size(); i++)
|
||||
|
@ -64,7 +64,7 @@ Stars::Stars(scene::ISceneNode* parentKart, core::vector3df center)
|
||||
|
||||
Stars::~Stars()
|
||||
{
|
||||
const int nodeAmount = m_nodes.size();
|
||||
const int nodeAmount = (int) m_nodes.size();
|
||||
for (int n=0; n<nodeAmount; n++)
|
||||
{
|
||||
m_parent_kart_node->removeChild(m_nodes[n]);
|
||||
@ -79,8 +79,8 @@ void Stars::showFor(float time)
|
||||
m_remaining_time = time;
|
||||
m_fade_in_time = 1.0f;
|
||||
|
||||
const int nodeAmount = m_nodes.size();
|
||||
for (int n=0; n<nodeAmount; n++)
|
||||
const int node_amount = (int)m_nodes.size();
|
||||
for (int n=0; n<node_amount; n++)
|
||||
{
|
||||
m_nodes[n]->setVisible(true);
|
||||
((scene::IBillboardSceneNode*)m_nodes[n])
|
||||
@ -111,16 +111,16 @@ void Stars::update(float delta_t)
|
||||
{
|
||||
m_enabled = false;
|
||||
|
||||
const int nodeAmount = m_nodes.size();
|
||||
for (int n=0; n<nodeAmount; n++)
|
||||
const int node_amount = (int)m_nodes.size();
|
||||
for (int n=0; n<node_amount; n++)
|
||||
{
|
||||
m_nodes[n]->setVisible(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const int nodeAmount = m_nodes.size();
|
||||
for (int n=0; n<nodeAmount; n++)
|
||||
const int node_amount = (int)m_nodes.size();
|
||||
for (int n=0; n<node_amount; n++)
|
||||
{
|
||||
// do one full rotation every 4 seconds (this "ranges" ranges
|
||||
// from 0 to 1)
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "graphics/stkmeshscenenode.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "guiengine/scalable_font.hpp"
|
||||
|
||||
#include "glwrap.hpp"
|
||||
#include <SMesh.h>
|
||||
#include <SMeshBuffer.h>
|
||||
#include <ISceneManager.h>
|
||||
@ -92,6 +92,7 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFon
|
||||
{
|
||||
buffer = new scene::SMeshBuffer();
|
||||
buffer->getMaterial().setTexture(0, m_chars[i].m_texture);
|
||||
buffer->getMaterial().setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0)));
|
||||
buffer->getMaterial().MaterialType = irr_driver->getShader(ES_OBJECT_UNLIT);
|
||||
buffers[m_chars[i].m_texture] = buffer;
|
||||
}
|
||||
|
@ -43,15 +43,18 @@ void STKAnimatedMesh::cleanGLMeshes()
|
||||
if (mesh.index_buffer)
|
||||
glDeleteBuffers(1, &(mesh.index_buffer));
|
||||
}
|
||||
GLmeshes.clear();
|
||||
for (unsigned i = 0; i < MAT_COUNT; i++)
|
||||
MeshSolidMaterial[i].clearWithoutDeleting();
|
||||
for (unsigned i = 0; i < TM_COUNT; i++)
|
||||
TransparentMesh[i].clearWithoutDeleting();
|
||||
}
|
||||
|
||||
void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh)
|
||||
{
|
||||
isGLInitialized = false;
|
||||
isMaterialInitialized = false;
|
||||
GLmeshes.clear();
|
||||
for (unsigned i = 0; i < MAT_COUNT; i++)
|
||||
MeshSolidMaterial[i].clearWithoutDeleting();
|
||||
cleanGLMeshes();
|
||||
CAnimatedMeshSceneNode::setMesh(mesh);
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb)
|
||||
case scene::EPT_QUADS:
|
||||
assert(0 && "Unsupported primitive type");
|
||||
}
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
for (unsigned i = 0; i < 8; i++)
|
||||
result.textures[i] = mb->getMaterial().getTexture(i);
|
||||
result.TextureMatrix = 0;
|
||||
result.VAOType = mb->getVertexType();
|
||||
@ -301,7 +301,7 @@ static void
|
||||
SetTexture(GLMesh &mesh, unsigned i, bool isSrgb)
|
||||
{
|
||||
if (!mesh.textures[i])
|
||||
mesh.textures[i] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||
Log::fatal("STKMesh", "Missing texture");
|
||||
compressTexture(mesh.textures[i], isSrgb);
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
@ -323,18 +323,22 @@ void InitTextures(GLMesh &mesh, MeshMaterial Mat)
|
||||
case MAT_SPHEREMAP:
|
||||
case MAT_UNLIT:
|
||||
SetTexture(mesh, 0, true);
|
||||
SetTexture(mesh, 1, false);
|
||||
break;
|
||||
case MAT_DETAIL:
|
||||
case MAT_NORMAL_MAP:
|
||||
SetTexture(mesh, 0, true);
|
||||
SetTexture(mesh, 1, false);
|
||||
SetTexture(mesh, 2, false);
|
||||
break;
|
||||
case MAT_SPLATTING:
|
||||
SetTexture(mesh, 0, true);
|
||||
SetTexture(mesh, 1, true);
|
||||
SetTexture(mesh, 1, false);
|
||||
SetTexture(mesh, 2, true);
|
||||
SetTexture(mesh, 3, true);
|
||||
SetTexture(mesh, 4, true);
|
||||
SetTexture(mesh, 5, true);
|
||||
SetTexture(mesh, 6, false);
|
||||
break;
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ struct GLMesh {
|
||||
GLuint vao;
|
||||
GLuint vertex_buffer;
|
||||
GLuint index_buffer;
|
||||
video::ITexture *textures[6];
|
||||
video::ITexture *textures[8];
|
||||
GLenum PrimitiveType;
|
||||
GLenum IndexType;
|
||||
size_t IndexCount;
|
||||
|
@ -63,6 +63,8 @@ void STKMeshSceneNode::cleanGLMeshes()
|
||||
GLmeshes.clear();
|
||||
for (unsigned i = 0; i < MAT_COUNT; i++)
|
||||
MeshSolidMaterial[i].clearWithoutDeleting();
|
||||
for (unsigned i = 0; i < TM_COUNT; i++)
|
||||
TransparentMesh[i].clearWithoutDeleting();
|
||||
}
|
||||
|
||||
void STKMeshSceneNode::setMesh(irr::scene::IMesh* mesh)
|
||||
@ -169,7 +171,6 @@ void STKMeshSceneNode::updateGL()
|
||||
|
||||
irr::video::IVideoDriver* driver = irr_driver->getVideoDriver();
|
||||
video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType;
|
||||
f32 MaterialTypeParam = mb->getMaterial().MaterialTypeParam;
|
||||
video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type);
|
||||
|
||||
|
||||
@ -251,8 +252,6 @@ void STKMeshSceneNode::render()
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
|
||||
if (!mesh.textures[0])
|
||||
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||
compressTexture(mesh.textures[0], true);
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
@ -282,8 +281,6 @@ void STKMeshSceneNode::render()
|
||||
glDisable(GL_CULL_FACE);
|
||||
if (update_each_frame && !UserConfigParams::m_dynamic_lights)
|
||||
updatevbo();
|
||||
if (!spareWhiteTex)
|
||||
spareWhiteTex = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||
glUseProgram(MeshShader::ObjectPass2Shader::getInstance()->Program);
|
||||
// Only untextured
|
||||
for (unsigned i = 0; i < GLmeshes.size(); i++)
|
||||
@ -309,7 +306,7 @@ void STKMeshSceneNode::render()
|
||||
glMakeTextureHandleResidentARB(SSAOHandle);
|
||||
|
||||
if (!mesh.TextureHandles[0])
|
||||
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(spareWhiteTex), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
|
||||
mesh.TextureHandles[0] = glGetTextureSamplerHandleARB(getTextureGLuint(mesh.textures[0]), MeshShader::TransparentFogShader::getInstance()->SamplersId[0]);
|
||||
if (!glIsTextureHandleResidentARB(mesh.TextureHandles[0]))
|
||||
glMakeTextureHandleResidentARB(mesh.TextureHandles[0]);
|
||||
MeshShader::ObjectPass2Shader::getInstance()->SetTextureHandles(createVector<uint64_t>(DiffuseHandle, SpecularHandle, SSAOHandle, mesh.TextureHandles[0]));
|
||||
@ -319,7 +316,7 @@ void STKMeshSceneNode::render()
|
||||
irr_driver->getRenderTargetTexture(RTT_DIFFUSE),
|
||||
irr_driver->getRenderTargetTexture(RTT_SPECULAR),
|
||||
irr_driver->getRenderTargetTexture(RTT_HALF1_R),
|
||||
getTextureGLuint(spareWhiteTex)));
|
||||
getTextureGLuint(mesh.textures[0])));
|
||||
MeshShader::ObjectPass2Shader::getInstance()->setUniforms(AbsoluteTransformation, mesh.TextureMatrix);
|
||||
assert(mesh.vao);
|
||||
glBindVertexArray(mesh.vao);
|
||||
@ -381,8 +378,6 @@ void STKMeshSceneNode::render()
|
||||
tmpcol.getGreen() / 255.0f,
|
||||
tmpcol.getBlue() / 255.0f);
|
||||
|
||||
if (!mesh.textures[0])
|
||||
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||
compressTexture(mesh.textures[0], true);
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
@ -412,8 +407,7 @@ void STKMeshSceneNode::render()
|
||||
GLenum ptype = mesh.PrimitiveType;
|
||||
GLenum itype = mesh.IndexType;
|
||||
size_t count = mesh.IndexCount;
|
||||
if (!mesh.textures[0])
|
||||
mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255));
|
||||
|
||||
compressTexture(mesh.textures[0], true);
|
||||
if (UserConfigParams::m_azdo)
|
||||
{
|
||||
|
@ -21,8 +21,95 @@
|
||||
#include <SViewFrustum.h>
|
||||
#include <functional>
|
||||
|
||||
template<typename T>
|
||||
struct InstanceFiller
|
||||
{
|
||||
static void add(GLMesh *, scene::ISceneNode *, T &);
|
||||
};
|
||||
|
||||
template<>
|
||||
void InstanceFiller<InstanceDataSingleTex>::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataSingleTex &Instance)
|
||||
{
|
||||
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||
const core::vector3df &Origin = mat.getTranslation();
|
||||
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||
const core::vector3df &Scale = mat.getScale();
|
||||
Instance.Origin.X = Origin.X;
|
||||
Instance.Origin.Y = Origin.Y;
|
||||
Instance.Origin.Z = Origin.Z;
|
||||
Instance.Orientation.X = Orientation.X;
|
||||
Instance.Orientation.Y = Orientation.Y;
|
||||
Instance.Orientation.Z = Orientation.Z;
|
||||
Instance.Scale.X = Scale.X;
|
||||
Instance.Scale.Y = Scale.Y;
|
||||
Instance.Scale.Z = Scale.Z;
|
||||
Instance.Texture = mesh->TextureHandles[0];
|
||||
}
|
||||
|
||||
template<>
|
||||
void InstanceFiller<InstanceDataDualTex>::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataDualTex &Instance)
|
||||
{
|
||||
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||
const core::vector3df &Origin = mat.getTranslation();
|
||||
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||
const core::vector3df &Scale = mat.getScale();
|
||||
Instance.Origin.X = Origin.X;
|
||||
Instance.Origin.Y = Origin.Y;
|
||||
Instance.Origin.Z = Origin.Z;
|
||||
Instance.Orientation.X = Orientation.X;
|
||||
Instance.Orientation.Y = Orientation.Y;
|
||||
Instance.Orientation.Z = Orientation.Z;
|
||||
Instance.Scale.X = Scale.X;
|
||||
Instance.Scale.Y = Scale.Y;
|
||||
Instance.Scale.Z = Scale.Z;
|
||||
Instance.Texture = mesh->TextureHandles[0];
|
||||
Instance.SecondTexture = mesh->TextureHandles[1];
|
||||
}
|
||||
|
||||
template<>
|
||||
void InstanceFiller<InstanceDataThreeTex>::add(GLMesh *mesh, scene::ISceneNode *node, InstanceDataThreeTex &Instance)
|
||||
{
|
||||
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||
const core::vector3df &Origin = mat.getTranslation();
|
||||
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||
const core::vector3df &Scale = mat.getScale();
|
||||
Instance.Origin.X = Origin.X;
|
||||
Instance.Origin.Y = Origin.Y;
|
||||
Instance.Origin.Z = Origin.Z;
|
||||
Instance.Orientation.X = Orientation.X;
|
||||
Instance.Orientation.Y = Orientation.Y;
|
||||
Instance.Orientation.Z = Orientation.Z;
|
||||
Instance.Scale.X = Scale.X;
|
||||
Instance.Scale.Y = Scale.Y;
|
||||
Instance.Scale.Z = Scale.Z;
|
||||
Instance.Texture = mesh->TextureHandles[0];
|
||||
Instance.SecondTexture = mesh->TextureHandles[1];
|
||||
Instance.ThirdTexture = mesh->TextureHandles[2];
|
||||
}
|
||||
|
||||
template<>
|
||||
void InstanceFiller<GlowInstanceData>::add(GLMesh *mesh, scene::ISceneNode *node, GlowInstanceData &Instance)
|
||||
{
|
||||
STKMeshSceneNode *nd = dynamic_cast<STKMeshSceneNode*>(node);
|
||||
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||
const core::vector3df &Origin = mat.getTranslation();
|
||||
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||
const core::vector3df &Scale = mat.getScale();
|
||||
Instance.Color = nd->getGlowColor().color;
|
||||
Instance.Origin.X = Origin.X;
|
||||
Instance.Origin.Y = Origin.Y;
|
||||
Instance.Origin.Z = Origin.Z;
|
||||
Instance.Orientation.X = Orientation.X;
|
||||
Instance.Orientation.Y = Orientation.Y;
|
||||
Instance.Orientation.Z = Orientation.Z;
|
||||
Instance.Scale.X = Scale.X;
|
||||
Instance.Scale.Y = Scale.Y;
|
||||
Instance.Scale.Z = Scale.Z;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void
|
||||
FillInstances_impl(std::vector<std::pair<GLMesh *, scene::ISceneNode *> > InstanceList, InstanceData * InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer,
|
||||
FillInstances_impl(std::vector<std::pair<GLMesh *, scene::ISceneNode *> > InstanceList, T * InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer,
|
||||
size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &PolyCount, std::function<bool (const scene::ISceneNode *)> cull_func)
|
||||
{
|
||||
// Should never be empty
|
||||
@ -35,22 +122,7 @@ FillInstances_impl(std::vector<std::pair<GLMesh *, scene::ISceneNode *> > Instan
|
||||
scene::ISceneNode *node = Tp.second;
|
||||
if (cull_func(node))
|
||||
continue;
|
||||
InstanceData &Instance = InstanceBuffer[InstanceBufferOffset++];
|
||||
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||
const core::vector3df &Origin = mat.getTranslation();
|
||||
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||
const core::vector3df &Scale = mat.getScale();
|
||||
Instance.Origin.X = Origin.X;
|
||||
Instance.Origin.Y = Origin.Y;
|
||||
Instance.Origin.Z = Origin.Z;
|
||||
Instance.Orientation.X = Orientation.X;
|
||||
Instance.Orientation.Y = Orientation.Y;
|
||||
Instance.Orientation.Z = Orientation.Z;
|
||||
Instance.Scale.X = Scale.X;
|
||||
Instance.Scale.Y = Scale.Y;
|
||||
Instance.Scale.Z = Scale.Z;
|
||||
Instance.Texture = mesh->TextureHandles[0];
|
||||
Instance.SecondTexture = mesh->TextureHandles[1];
|
||||
InstanceFiller<T>::add(mesh, node, InstanceBuffer[InstanceBufferOffset++]);
|
||||
}
|
||||
|
||||
DrawElementsIndirectCommand &CurrentCommand = CommandBuffer[CommandBufferOffset++];
|
||||
@ -63,62 +135,23 @@ FillInstances_impl(std::vector<std::pair<GLMesh *, scene::ISceneNode *> > Instan
|
||||
PolyCount += (InstanceBufferOffset - InitialOffset) * mesh->IndexCount / 3;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
FillInstancesGlow_impl(std::vector<std::pair<GLMesh *, STKMeshCommon *> > InstanceList, GlowInstanceData * InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer,
|
||||
size_t &InstanceBufferOffset, size_t &CommandBufferOffset, std::function<bool (const scene::ISceneNode *)> cull_func)
|
||||
{
|
||||
// Should never be empty
|
||||
GLMesh *mesh = InstanceList.front().first;
|
||||
size_t InitialOffset = InstanceBufferOffset;
|
||||
|
||||
for (unsigned i = 0; i < InstanceList.size(); i++)
|
||||
{
|
||||
STKMeshSceneNode *node = dynamic_cast<STKMeshSceneNode*>(InstanceList[i].second);
|
||||
if (cull_func(node))
|
||||
continue;
|
||||
GlowInstanceData &Instance = InstanceBuffer[InstanceBufferOffset++];
|
||||
const core::matrix4 &mat = node->getAbsoluteTransformation();
|
||||
const core::vector3df &Origin = mat.getTranslation();
|
||||
const core::vector3df &Orientation = mat.getRotationDegrees();
|
||||
const core::vector3df &Scale = mat.getScale();
|
||||
Instance.Color = node->getGlowColor().color;
|
||||
Instance.Origin.X = Origin.X;
|
||||
Instance.Origin.Y = Origin.Y;
|
||||
Instance.Origin.Z = Origin.Z;
|
||||
Instance.Orientation.X = Orientation.X;
|
||||
Instance.Orientation.Y = Orientation.Y;
|
||||
Instance.Orientation.Z = Orientation.Z;
|
||||
Instance.Scale.X = Scale.X;
|
||||
Instance.Scale.Y = Scale.Y;
|
||||
Instance.Scale.Z = Scale.Z;
|
||||
}
|
||||
|
||||
DrawElementsIndirectCommand &CurrentCommand = CommandBuffer[CommandBufferOffset++];
|
||||
CurrentCommand.baseVertex = mesh->vaoBaseVertex;
|
||||
CurrentCommand.count = mesh->IndexCount;
|
||||
CurrentCommand.firstIndex = mesh->vaoOffset / 2;
|
||||
CurrentCommand.baseInstance = InitialOffset;
|
||||
CurrentCommand.instanceCount = InstanceBufferOffset - InitialOffset;
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
static
|
||||
void FillInstances(const std::unordered_map<scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > &GatheredGLMesh, std::vector<GLMesh *> &InstancedList,
|
||||
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &Polycount,
|
||||
T *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &Polycount,
|
||||
std::function<bool (const scene::ISceneNode *)> cull_func)
|
||||
{
|
||||
auto It = GatheredGLMesh.begin(), E = GatheredGLMesh.end();
|
||||
for (; It != E; ++It)
|
||||
{
|
||||
FillInstances_impl(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, Polycount, cull_func);
|
||||
FillInstances_impl<T>(It->second, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, Polycount, cull_func);
|
||||
if (!UserConfigParams::m_azdo)
|
||||
InstancedList.push_back(It->second.front().first);
|
||||
}
|
||||
}
|
||||
|
||||
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForSolidPass[MAT_COUNT];
|
||||
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, STKMeshCommon *> > > MeshForGlowPass;
|
||||
static std::unordered_map <scene::IMeshBuffer *, std::vector<std::pair<GLMesh *, scene::ISceneNode*> > > MeshForGlowPass;
|
||||
static std::vector <STKMeshCommon *> DeferredUpdate;
|
||||
|
||||
static core::vector3df windDir;
|
||||
@ -224,7 +257,7 @@ handleSTKCommon(scene::ISceneNode *Node, std::vector<scene::ISceneNode *> *Immed
|
||||
for_in(mesh, node->MeshSolidMaterial[Mat])
|
||||
{
|
||||
if (node->glow())
|
||||
MeshForGlowPass[mesh->mb].emplace_back(mesh, node);
|
||||
MeshForGlowPass[mesh->mb].emplace_back(mesh, Node);
|
||||
|
||||
if (Mat != MAT_SPLATTING && mesh->TextureMatrix.isIdentity())
|
||||
MeshForSolidPass[Mat][mesh->mb].emplace_back(mesh, Node);
|
||||
@ -422,14 +455,14 @@ parseSceneManager(core::list<scene::ISceneNode*> List, std::vector<scene::IScene
|
||||
}
|
||||
}
|
||||
|
||||
template<MeshMaterial Mat> static void
|
||||
template<MeshMaterial Mat, typename T> static void
|
||||
GenDrawCalls(unsigned cascade, std::vector<GLMesh *> &InstancedList,
|
||||
InstanceData *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &PolyCount)
|
||||
T *InstanceBuffer, DrawElementsIndirectCommand *CommandBuffer, size_t &InstanceBufferOffset, size_t &CommandBufferOffset, size_t &PolyCount)
|
||||
{
|
||||
std::function<bool(const scene::ISceneNode *)> shadowculling = [&](const scene::ISceneNode *nd) {return dynamic_cast<const STKMeshCommon*>(nd)->isCulledForShadowCam(cascade); };
|
||||
if (irr_driver->hasARB_draw_indirect())
|
||||
ShadowPassCmd::getInstance()->Offset[cascade][Mat] = CommandBufferOffset; // Store command buffer offset
|
||||
FillInstances(MeshForSolidPass[Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, PolyCount, shadowculling);
|
||||
FillInstances<T>(MeshForSolidPass[Mat], InstancedList, InstanceBuffer, CommandBuffer, InstanceBufferOffset, CommandBufferOffset, PolyCount, shadowculling);
|
||||
if (UserConfigParams::m_azdo)
|
||||
ShadowPassCmd::getInstance()->Size[cascade][Mat] = CommandBufferOffset - ShadowPassCmd::getInstance()->Offset[cascade][Mat];
|
||||
}
|
||||
@ -510,9 +543,10 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
|
||||
if (!irr_driver->hasARB_draw_indirect())
|
||||
return;
|
||||
|
||||
InstanceData *InstanceBuffer;
|
||||
InstanceData *ShadowInstanceBuffer;
|
||||
InstanceData *RSMInstanceBuffer;
|
||||
InstanceDataDualTex *InstanceBufferDualTex;
|
||||
InstanceDataThreeTex *InstanceBufferThreeTex;
|
||||
InstanceDataSingleTex *ShadowInstanceBuffer;
|
||||
InstanceDataSingleTex *RSMInstanceBuffer;
|
||||
GlowInstanceData *GlowInstanceBuffer;
|
||||
DrawElementsIndirectCommand *CmdBuffer;
|
||||
DrawElementsIndirectCommand *ShadowCmdBuffer;
|
||||
@ -521,9 +555,10 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
|
||||
|
||||
if (irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
InstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeDefault);
|
||||
ShadowInstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeShadow);
|
||||
RSMInstanceBuffer = (InstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeRSM);
|
||||
InstanceBufferDualTex = (InstanceDataDualTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeDualTex);
|
||||
InstanceBufferThreeTex = (InstanceDataThreeTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeThreeTex);
|
||||
ShadowInstanceBuffer = (InstanceDataSingleTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeShadow);
|
||||
RSMInstanceBuffer = (InstanceDataSingleTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeRSM);
|
||||
GlowInstanceBuffer = (GlowInstanceData*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeGlow);
|
||||
CmdBuffer = SolidPassCmd::getInstance()->Ptr;
|
||||
ShadowCmdBuffer = ShadowPassCmd::getInstance()->Ptr;
|
||||
@ -554,8 +589,8 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
|
||||
size_t offset = 0, current_cmd = 0;
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeDefault));
|
||||
InstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeDualTex));
|
||||
InstanceBufferDualTex = (InstanceDataDualTex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceDataDualTex), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, SolidPassCmd::getInstance()->drawindirectcmd);
|
||||
CmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
@ -563,33 +598,42 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
|
||||
|
||||
// Default Material
|
||||
SolidPassCmd::getInstance()->Offset[MAT_DEFAULT] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
FillInstances(MeshForSolidPass[MAT_DEFAULT], ListInstancedMatDefault::getInstance()->SolidPass, InstanceBufferDualTex, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_DEFAULT] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_DEFAULT];
|
||||
// Alpha Ref
|
||||
SolidPassCmd::getInstance()->Offset[MAT_ALPHA_REF] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
FillInstances(MeshForSolidPass[MAT_ALPHA_REF], ListInstancedMatAlphaRef::getInstance()->SolidPass, InstanceBufferDualTex, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_ALPHA_REF] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_ALPHA_REF];
|
||||
// Unlit
|
||||
SolidPassCmd::getInstance()->Offset[MAT_UNLIT] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
FillInstances(MeshForSolidPass[MAT_UNLIT], ListInstancedMatUnlit::getInstance()->SolidPass, InstanceBufferDualTex, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_UNLIT] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_UNLIT];
|
||||
// Spheremap
|
||||
SolidPassCmd::getInstance()->Offset[MAT_SPHEREMAP] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_SPHEREMAP], ListInstancedMatSphereMap::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
FillInstances(MeshForSolidPass[MAT_SPHEREMAP], ListInstancedMatSphereMap::getInstance()->SolidPass, InstanceBufferDualTex, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_SPHEREMAP] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_SPHEREMAP];
|
||||
// Grass
|
||||
SolidPassCmd::getInstance()->Offset[MAT_GRASS] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_GRASS], ListInstancedMatGrass::getInstance()->SolidPass, InstanceBufferDualTex, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_GRASS] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_GRASS];
|
||||
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeThreeTex));
|
||||
InstanceBufferThreeTex = (InstanceDataThreeTex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceDataSingleTex), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
|
||||
}
|
||||
|
||||
// Detail
|
||||
SolidPassCmd::getInstance()->Offset[MAT_DETAIL] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
FillInstances(MeshForSolidPass[MAT_DETAIL], ListInstancedMatDetails::getInstance()->SolidPass, InstanceBufferThreeTex, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_DETAIL] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_DETAIL];
|
||||
// Normal Map
|
||||
SolidPassCmd::getInstance()->Offset[MAT_NORMAL_MAP] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
FillInstances(MeshForSolidPass[MAT_NORMAL_MAP], ListInstancedMatNormalMap::getInstance()->SolidPass, InstanceBufferThreeTex, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_NORMAL_MAP] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_NORMAL_MAP];
|
||||
|
||||
// Grass
|
||||
SolidPassCmd::getInstance()->Offset[MAT_GRASS] = current_cmd;
|
||||
FillInstances(MeshForSolidPass[MAT_GRASS], ListInstancedMatGrass::getInstance()->SolidPass, InstanceBuffer, CmdBuffer, offset, current_cmd, SolidPoly, playercamculling);
|
||||
SolidPassCmd::getInstance()->Size[MAT_GRASS] = current_cmd - SolidPassCmd::getInstance()->Offset[MAT_GRASS];
|
||||
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
@ -604,7 +648,7 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeGlow));
|
||||
GlowInstanceBuffer = (GlowInstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
GlowInstanceBuffer = (GlowInstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceDataDualTex), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, GlowPassCmd::getInstance()->drawindirectcmd);
|
||||
GlowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
@ -616,7 +660,8 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
|
||||
auto It = MeshForGlowPass.begin(), E = MeshForGlowPass.end();
|
||||
for (; It != E; ++It)
|
||||
{
|
||||
FillInstancesGlow_impl(It->second, GlowInstanceBuffer, GlowCmdBuffer, offset, current_cmd, playercamculling);
|
||||
size_t Polycnt = 0;
|
||||
FillInstances_impl<GlowInstanceData>(It->second, GlowInstanceBuffer, GlowCmdBuffer, offset, current_cmd, Polycnt, playercamculling);
|
||||
if (!UserConfigParams::m_azdo)
|
||||
ListInstancedGlow::getInstance()->push_back(It->second.front().first);
|
||||
}
|
||||
@ -638,7 +683,7 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeShadow));
|
||||
ShadowInstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
ShadowInstanceBuffer = (InstanceDataSingleTex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceDataDualTex), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ShadowPassCmd::getInstance()->drawindirectcmd);
|
||||
ShadowCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
@ -673,7 +718,7 @@ void IrrDriver::PrepareDrawCalls(scene::ICameraSceneNode *camnode)
|
||||
if (!irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeRSM));
|
||||
RSMInstanceBuffer = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
RSMInstanceBuffer = (InstanceDataSingleTex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceDataDualTex), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, RSMPassCmd::getInstance()->drawindirectcmd);
|
||||
RSMCmdBuffer = (DrawElementsIndirectCommand*)glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, 10000 * sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "texturemanager.hpp"
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "../../lib/irrlicht/source/Irrlicht/COpenGLTexture.h"
|
||||
#include "irr_driver.hpp"
|
||||
|
||||
@ -169,14 +169,31 @@ void saveCompressedTexture(const std::string& compressed_tex)
|
||||
|
||||
static unsigned colorcount = 0;
|
||||
|
||||
video::ITexture* getUnicolorTexture(video::SColor c)
|
||||
std::map<int, video::ITexture*> unicolor_cache;
|
||||
|
||||
video::ITexture* getUnicolorTexture(const video::SColor &c)
|
||||
{
|
||||
video::SColor tmp[4] = {
|
||||
c, c, c, c
|
||||
};
|
||||
video::IImage *img = irr_driver->getVideoDriver()->createImageFromData(video::ECF_A8R8G8B8, core::dimension2d<u32>(2, 2), tmp);
|
||||
img->grab();
|
||||
std::string name("color");
|
||||
name += colorcount++;
|
||||
return irr_driver->getVideoDriver()->addTexture(name.c_str(), img);
|
||||
std::map<int, video::ITexture*>::iterator it = unicolor_cache.find(c.color);
|
||||
if (it != unicolor_cache.end())
|
||||
{
|
||||
it->second->grab();
|
||||
return it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned tmp[4] = {
|
||||
c.color,
|
||||
c.color,
|
||||
c.color,
|
||||
c.color
|
||||
};
|
||||
video::IImage *img = irr_driver->getVideoDriver()->createImageFromData(video::ECF_A8R8G8B8, core::dimension2d<u32>(2, 2), tmp);
|
||||
img->grab();
|
||||
std::stringstream name;
|
||||
name << "color" << c.color;
|
||||
video::ITexture* tex = irr_driver->getVideoDriver()->addTexture(name.str().c_str(), img);
|
||||
unicolor_cache[c.color] = tex;
|
||||
img->drop();
|
||||
return tex;
|
||||
}
|
||||
}
|
@ -17,12 +17,12 @@ VAOManager::VAOManager()
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[i]);
|
||||
if (irr_driver->hasBufferStorageExtension())
|
||||
{
|
||||
glBufferStorage(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
Ptr[i] = glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
glBufferStorage(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceDataDualTex), 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
Ptr[i] = glMapBufferRange(GL_ARRAY_BUFFER, 0, 10000 * sizeof(InstanceDataDualTex), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferData(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceData), 0, GL_STREAM_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, 10000 * sizeof(InstanceDataDualTex), 0, GL_STREAM_DRAW);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,6 +122,7 @@ void VAOManager::regenerateVAO(enum VTXTYPE tp)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo[tp]);
|
||||
switch (tp)
|
||||
{
|
||||
case VTXTYPE_COUNT: break; // avoid compiler warning
|
||||
case VTXTYPE_STANDARD:
|
||||
// Position
|
||||
glEnableVertexAttribArray(0);
|
||||
@ -179,6 +180,71 @@ void VAOManager::regenerateVAO(enum VTXTYPE tp)
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct VAOInstanceUtil
|
||||
{
|
||||
static void SetVertexAttrib_impl()
|
||||
{
|
||||
glEnableVertexAttribArray(7);
|
||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(T), 0);
|
||||
glVertexAttribDivisor(7, 1);
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(T), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(8, 1);
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(T), (GLvoid*)(6 * sizeof(float)));
|
||||
glVertexAttribDivisor(9, 1);
|
||||
}
|
||||
|
||||
static void SetVertexAttrib();
|
||||
};
|
||||
|
||||
template<>
|
||||
void VAOInstanceUtil<InstanceDataSingleTex>::SetVertexAttrib()
|
||||
{
|
||||
SetVertexAttrib_impl();
|
||||
glEnableVertexAttribArray(10);
|
||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceDataSingleTex), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(10, 1);
|
||||
}
|
||||
|
||||
template<>
|
||||
void VAOInstanceUtil<InstanceDataDualTex>::SetVertexAttrib()
|
||||
{
|
||||
SetVertexAttrib_impl();
|
||||
glEnableVertexAttribArray(10);
|
||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceDataDualTex), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(10, 1);
|
||||
glEnableVertexAttribArray(11);
|
||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceDataDualTex), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||
glVertexAttribDivisor(11, 1);
|
||||
}
|
||||
|
||||
template<>
|
||||
void VAOInstanceUtil<InstanceDataThreeTex>::SetVertexAttrib()
|
||||
{
|
||||
SetVertexAttrib_impl();
|
||||
glEnableVertexAttribArray(10);
|
||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceDataThreeTex), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(10, 1);
|
||||
glEnableVertexAttribArray(11);
|
||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceDataThreeTex), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||
glVertexAttribDivisor(11, 1);
|
||||
glEnableVertexAttribArray(13);
|
||||
glVertexAttribIPointer(13, 2, GL_UNSIGNED_INT, sizeof(InstanceDataThreeTex), (GLvoid*)(9 * sizeof(float) + 4 * sizeof(unsigned)));
|
||||
glVertexAttribDivisor(13, 1);
|
||||
}
|
||||
|
||||
template<>
|
||||
void VAOInstanceUtil<GlowInstanceData>::SetVertexAttrib()
|
||||
{
|
||||
SetVertexAttrib_impl();
|
||||
glEnableVertexAttribArray(12);
|
||||
glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GlowInstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(12, 1);
|
||||
}
|
||||
|
||||
|
||||
void VAOManager::regenerateInstancedVAO()
|
||||
{
|
||||
cleanInstanceVAOs();
|
||||
@ -190,81 +256,30 @@ void VAOManager::regenerateInstancedVAO()
|
||||
if (!vbo[tp] || !ibo[tp])
|
||||
continue;
|
||||
GLuint vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeDefault]);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeDualTex]);
|
||||
VAOInstanceUtil<InstanceDataDualTex>::SetVertexAttrib();
|
||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeDualTex)] = vao;
|
||||
|
||||
glEnableVertexAttribArray(7);
|
||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
||||
glVertexAttribDivisor(7, 1);
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(8, 1);
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||
glVertexAttribDivisor(9, 1);
|
||||
glEnableVertexAttribArray(10);
|
||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(10, 1);
|
||||
glEnableVertexAttribArray(11);
|
||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||
glVertexAttribDivisor(11, 1);
|
||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeDefault)] = vao;
|
||||
vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeThreeTex]);
|
||||
VAOInstanceUtil<InstanceDataThreeTex>::SetVertexAttrib();
|
||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeThreeTex)] = vao;
|
||||
|
||||
vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeShadow]);
|
||||
|
||||
glEnableVertexAttribArray(7);
|
||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
||||
glVertexAttribDivisor(7, 1);
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(8, 1);
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||
glVertexAttribDivisor(9, 1);
|
||||
glEnableVertexAttribArray(10);
|
||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(10, 1);
|
||||
glEnableVertexAttribArray(11);
|
||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||
glVertexAttribDivisor(11, 1);
|
||||
VAOInstanceUtil<InstanceDataSingleTex>::SetVertexAttrib();
|
||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeShadow)] = vao;
|
||||
|
||||
vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeRSM]);
|
||||
|
||||
glEnableVertexAttribArray(7);
|
||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
|
||||
glVertexAttribDivisor(7, 1);
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(8, 1);
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||
glVertexAttribDivisor(9, 1);
|
||||
glEnableVertexAttribArray(10);
|
||||
glVertexAttribIPointer(10, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(10, 1);
|
||||
glEnableVertexAttribArray(11);
|
||||
glVertexAttribIPointer(11, 2, GL_UNSIGNED_INT, sizeof(InstanceData), (GLvoid*)(9 * sizeof(float) + 2 * sizeof(unsigned)));
|
||||
glVertexAttribDivisor(11, 1);
|
||||
VAOInstanceUtil<InstanceDataSingleTex>::SetVertexAttrib();
|
||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeRSM)] = vao;
|
||||
|
||||
vao = createVAO(vbo[tp], ibo[tp], tp);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instance_vbo[InstanceTypeGlow]);
|
||||
|
||||
glEnableVertexAttribArray(7);
|
||||
glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), 0);
|
||||
glVertexAttribDivisor(7, 1);
|
||||
glEnableVertexAttribArray(8);
|
||||
glVertexAttribPointer(8, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(3 * sizeof(float)));
|
||||
glVertexAttribDivisor(8, 1);
|
||||
glEnableVertexAttribArray(9);
|
||||
glVertexAttribPointer(9, 3, GL_FLOAT, GL_FALSE, sizeof(GlowInstanceData), (GLvoid*)(6 * sizeof(float)));
|
||||
glVertexAttribDivisor(9, 1);
|
||||
glEnableVertexAttribArray(12);
|
||||
glVertexAttribPointer(12, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GlowInstanceData), (GLvoid*)(9 * sizeof(float)));
|
||||
glVertexAttribDivisor(12, 1);
|
||||
VAOInstanceUtil<GlowInstanceData>::SetVertexAttrib();
|
||||
InstanceVAO[std::pair<video::E_VERTEX_TYPE, InstanceType>(tp, InstanceTypeGlow)] = vao;
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,8 @@
|
||||
|
||||
enum InstanceType
|
||||
{
|
||||
InstanceTypeDefault,
|
||||
InstanceTypeDualTex,
|
||||
InstanceTypeThreeTex,
|
||||
InstanceTypeShadow,
|
||||
InstanceTypeRSM,
|
||||
InstanceTypeGlow,
|
||||
@ -20,7 +21,34 @@ enum InstanceType
|
||||
#ifdef WIN32
|
||||
#pragma pack(push, 1)
|
||||
#endif
|
||||
struct InstanceData
|
||||
struct InstanceDataSingleTex
|
||||
{
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Origin;
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Orientation;
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Scale;
|
||||
uint64_t Texture;
|
||||
#ifdef WIN32
|
||||
};
|
||||
#else
|
||||
} __attribute__((packed));
|
||||
#endif
|
||||
|
||||
struct InstanceDataDualTex
|
||||
{
|
||||
struct
|
||||
{
|
||||
@ -48,6 +76,35 @@ struct InstanceData
|
||||
} __attribute__((packed));
|
||||
#endif
|
||||
|
||||
struct InstanceDataThreeTex
|
||||
{
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Origin;
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Orientation;
|
||||
struct
|
||||
{
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
} Scale;
|
||||
uint64_t Texture;
|
||||
uint64_t SecondTexture;
|
||||
uint64_t ThirdTexture;
|
||||
#ifdef WIN32
|
||||
};
|
||||
#else
|
||||
} __attribute__((packed));
|
||||
#endif
|
||||
|
||||
struct GlowInstanceData
|
||||
{
|
||||
struct
|
||||
|
@ -737,7 +737,7 @@ namespace GUIEngine
|
||||
void showMessage(const wchar_t* message, const float time)
|
||||
{
|
||||
// check for duplicates
|
||||
const int count = gui_messages.size();
|
||||
const int count = (int) gui_messages.size();
|
||||
for (int n=0; n<count; n++)
|
||||
{
|
||||
if (gui_messages[n].m_message == message) return;
|
||||
@ -1330,7 +1330,7 @@ namespace GUIEngine
|
||||
SColor(255,255,255,255),
|
||||
true/* center h */, false /* center v */ );
|
||||
|
||||
const int icon_count = g_loading_icons.size();
|
||||
const int icon_count = (int)g_loading_icons.size();
|
||||
const int icon_size = (int)(screen_w / 16.0f);
|
||||
const int ICON_MARGIN = 6;
|
||||
int x = ICON_MARGIN;
|
||||
|
@ -575,7 +575,6 @@ void ScalableFont::doDraw(const core::stringw& text,
|
||||
fallback_positions = NULL;
|
||||
}
|
||||
|
||||
video::IVideoDriver* driver = GUIEngine::getDriver();
|
||||
const int spriteAmount = sprites.size();
|
||||
for (int n=0; n<indiceAmount; n++)
|
||||
{
|
||||
@ -707,6 +706,7 @@ void ScalableFont::doDraw(const core::stringw& text,
|
||||
color, true);
|
||||
}
|
||||
#ifdef FONT_DEBUG
|
||||
video::IVideoDriver* driver = GUIEngine::getDriver();
|
||||
driver->draw2DLine(core::position2d<s32>(dest.UpperLeftCorner.X, dest.UpperLeftCorner.Y),
|
||||
core::position2d<s32>(dest.UpperLeftCorner.X, dest.LowerRightCorner.Y),
|
||||
video::SColor(255, 255,0,0));
|
||||
|
@ -317,7 +317,9 @@ void Widget::setParent(IGUIElement* parent)
|
||||
bool Widget::isVisible() const
|
||||
{
|
||||
if (m_element != NULL)
|
||||
{
|
||||
assert(m_element->isVisible() == m_is_visible);
|
||||
}
|
||||
return m_is_visible;
|
||||
}
|
||||
|
||||
|
@ -221,7 +221,7 @@ void DynamicRibbonWidget::add()
|
||||
|
||||
if (item_count < 1)
|
||||
{
|
||||
item_count = m_items.size();
|
||||
item_count = (int) m_items.size();
|
||||
}
|
||||
|
||||
if (item_count < 1)
|
||||
@ -327,7 +327,7 @@ void DynamicRibbonWidget::buildInternalStructure()
|
||||
m_col_amount = (int)roundf( m_w / ( m_child_width*ratio_zoom ) );
|
||||
|
||||
// ajust column amount to not add more item slots than we actually need
|
||||
const int item_count = m_items.size();
|
||||
const int item_count = (int) m_items.size();
|
||||
//std::cout << "item_count=" << item_count << ", row_amount*m_col_amount=" << m_row_amount*m_col_amount << std::endl;
|
||||
if (m_row_amount*m_col_amount > item_count)
|
||||
{
|
||||
@ -647,7 +647,7 @@ EventPropagation DynamicRibbonWidget::transmitEvent(Widget* w,
|
||||
if (selected_ribbon != NULL)
|
||||
{
|
||||
m_selected_item[playerID] = selected_ribbon->m_selection[playerID] + m_scroll_offset;
|
||||
if (m_selected_item[playerID] >= (int)m_items.size()) m_selected_item[playerID] -= m_items.size();
|
||||
if (m_selected_item[playerID] >= (int)m_items.size()) m_selected_item[playerID] -= (int)m_items.size();
|
||||
}
|
||||
}
|
||||
|
||||
@ -755,7 +755,7 @@ void DynamicRibbonWidget::scroll(const int x_delta)
|
||||
{
|
||||
RibbonWidget* ribbon = m_rows.get(0); // there is a single row when we can select items
|
||||
int id = m_selected_item[n] - m_scroll_offset;
|
||||
if (id < 0) id += m_items.size();
|
||||
if (id < 0) id += (int) m_items.size();
|
||||
ribbon->setSelection(id, n);
|
||||
}
|
||||
}
|
||||
@ -791,7 +791,7 @@ void DynamicRibbonWidget::propagateSelection()
|
||||
if (m_combo)
|
||||
{
|
||||
m_selected_item[p] = relative_selection + m_scroll_offset;
|
||||
if (m_selected_item[p] >= (int)m_items.size()) m_selected_item[p] -= m_items.size();
|
||||
if (m_selected_item[p] >= (int)m_items.size()) m_selected_item[p] -= (int)m_items.size();
|
||||
}
|
||||
|
||||
// set same selection in all ribbons
|
||||
@ -819,7 +819,7 @@ void DynamicRibbonWidget::updateLabel(RibbonWidget* from_this_ribbon)
|
||||
|
||||
std::string selection_id = row->getSelectionIDString(playerID);
|
||||
|
||||
const int amount = m_items.size();
|
||||
const int amount = (int)m_items.size();
|
||||
for (int n=0; n<amount; n++)
|
||||
{
|
||||
if (m_items[n].m_code_name == selection_id)
|
||||
@ -844,14 +844,14 @@ void DynamicRibbonWidget::updateItemDisplay()
|
||||
if ((int)m_items.size() != m_previous_item_count)
|
||||
{
|
||||
buildInternalStructure();
|
||||
m_previous_item_count = m_items.size();
|
||||
m_previous_item_count = (int)m_items.size();
|
||||
}
|
||||
|
||||
// ---- some variables
|
||||
int icon_id = 0;
|
||||
|
||||
const int row_amount = m_rows.size();
|
||||
const int item_amount = m_items.size();
|
||||
const int row_amount = (int)m_rows.size();
|
||||
const int item_amount = (int)m_items.size();
|
||||
|
||||
//FIXME: isn't this set by 'buildInternalStructure' already?
|
||||
m_needed_cols = (int)ceil( (float)item_amount / (float)row_amount );
|
||||
@ -860,7 +860,8 @@ void DynamicRibbonWidget::updateItemDisplay()
|
||||
|
||||
// the number of items that fit perfectly the number of rows we have
|
||||
// (this value will be useful to compute scrolling)
|
||||
int fitting_item_amount = (m_scrolling_enabled ? m_needed_cols * row_amount : m_items.size());
|
||||
int fitting_item_amount = (m_scrolling_enabled ? m_needed_cols * row_amount
|
||||
: (int)m_items.size());
|
||||
|
||||
// ---- to determine which items go in which cell of the dynamic ribbon now,
|
||||
// we create a temporary 2D table and fill them with the ID of the item
|
||||
@ -980,7 +981,7 @@ void DynamicRibbonWidget::update(float dt)
|
||||
{
|
||||
int col_scroll = i + m_scroll_offset;
|
||||
int item_id = (col_scroll)*row_amount + n;
|
||||
if (item_id >= (int)m_items.size()) item_id -= m_items.size();
|
||||
if (item_id >= (int)m_items.size()) item_id -= (int)m_items.size();
|
||||
|
||||
assert(item_id >= 0);
|
||||
assert(item_id < (int)m_items.size());
|
||||
@ -1097,7 +1098,7 @@ bool DynamicRibbonWidget::setSelection(const std::string &item_codename,
|
||||
{
|
||||
if (m_deactivated && !evenIfDeactivated) return false;
|
||||
|
||||
const int item_count = m_items.size();
|
||||
const int item_count = (int)m_items.size();
|
||||
for (int n=0; n<item_count; n++)
|
||||
{
|
||||
if (m_items[n].m_code_name == item_codename)
|
||||
|
@ -91,7 +91,7 @@ KartStatsWidget::KartStatsWidget(core::recti area, const int player_id,
|
||||
m_skills[SKILL_MASS]->setLabel("WEIGHT");
|
||||
m_skills[SKILL_MASS]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_mass", m_player_id);
|
||||
|
||||
m_skills[SKILL_SPEED]->setValue((int)((props->getAbsMaxSpeed()-20)*20));
|
||||
m_skills[SKILL_SPEED]->setValue((int)((props->getAbsMaxSpeed()-20)*9));
|
||||
m_skills[SKILL_SPEED]->setLabel("SPEED");
|
||||
m_skills[SKILL_SPEED]->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_speed", m_player_id);
|
||||
|
||||
|
@ -404,7 +404,7 @@ int XMLNode::get(const std::string &attribute,
|
||||
if(!get(attribute, &s)) return 0;
|
||||
|
||||
*value = StringUtils::split(s,' ');
|
||||
return value->size();
|
||||
return (int) value->size();
|
||||
} // get(vector<string>)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -423,7 +423,7 @@ int XMLNode::get(const std::string &attribute,
|
||||
std::vector<std::string> v = StringUtils::split(s,' ');
|
||||
value->clear();
|
||||
|
||||
const unsigned int count = v.size();
|
||||
const unsigned int count = (unsigned int)v.size();
|
||||
for (unsigned int i=0; i<count; i++)
|
||||
{
|
||||
float curr;
|
||||
@ -436,7 +436,7 @@ int XMLNode::get(const std::string &attribute,
|
||||
|
||||
value->push_back(curr);
|
||||
}
|
||||
return value->size();
|
||||
return (int) value->size();
|
||||
} // get(vector<float>)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -454,7 +454,7 @@ int XMLNode::get(const std::string &attribute, std::vector<int> *value) const
|
||||
std::vector<std::string> v = StringUtils::split(s,' ');
|
||||
value->clear();
|
||||
|
||||
const unsigned int count = v.size();
|
||||
const unsigned int count = (unsigned int)v.size();
|
||||
for (unsigned int i=0; i<count; i++)
|
||||
{
|
||||
int val;
|
||||
@ -467,7 +467,7 @@ int XMLNode::get(const std::string &attribute, std::vector<int> *value) const
|
||||
|
||||
value->push_back(val);
|
||||
}
|
||||
return value->size();
|
||||
return (int) value->size();
|
||||
} // get(vector<int>)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -529,7 +529,6 @@ int XMLNode::get(core::vector3df *value) const
|
||||
{
|
||||
float f;
|
||||
int bits=0;
|
||||
core::vector3df result = *value;
|
||||
if(get("x", &f)) { value->X = f; bits |= 1; }
|
||||
if(get("h", &f)) { value->X = f; bits |= 1; }
|
||||
if(get("y", &f)) { value->Y = f; bits |= 2; }
|
||||
@ -551,7 +550,6 @@ int XMLNode::getXYZ(core::vector3df *value) const
|
||||
{
|
||||
float f;
|
||||
int bits=0;
|
||||
core::vector3df result = *value;
|
||||
if(get("x", &f)) { value->X = f; bits |= 1; }
|
||||
if(get("y", &f)) { value->Y = f; bits |= 2; }
|
||||
if(get("z", &f)) { value->Z = f; bits |= 4; }
|
||||
@ -570,7 +568,6 @@ int XMLNode::getXYZ(Vec3 *value) const
|
||||
{
|
||||
float f;
|
||||
int bits=0;
|
||||
Vec3 result = *value;
|
||||
if(get("x", &f)) { value->setX(f); bits |= 1; }
|
||||
if(get("y", &f)) { value->setY(f); bits |= 2; }
|
||||
if(get("z", &f)) { value->setZ(f); bits |= 4; }
|
||||
@ -589,7 +586,6 @@ int XMLNode::getHPR(core::vector3df *value) const
|
||||
{
|
||||
float f;
|
||||
int bits=0;
|
||||
core::vector3df result = *value;
|
||||
if(get("h", &f)) { value->X = f; bits |= 1; }
|
||||
if(get("p", &f)) { value->Y = f; bits |= 2; }
|
||||
if(get("r", &f)) { value->Z = f; bits |= 4; }
|
||||
@ -608,7 +604,6 @@ int XMLNode::getHPR(Vec3 *value) const
|
||||
{
|
||||
float f;
|
||||
int bits=0;
|
||||
Vec3 result = *value;
|
||||
if(get("h", &f)) { value->setX(f); bits |= 1; }
|
||||
if(get("p", &f)) { value->setY(f); bits |= 2; }
|
||||
if(get("r", &f)) { value->setZ(f); bits |= 4; }
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
const XMLNode *getNode(const std::string &name) const;
|
||||
const void getNodes(const std::string &s, std::vector<XMLNode*>& out) const;
|
||||
const XMLNode *getNode(unsigned int i) const;
|
||||
unsigned int getNumNodes() const {return m_nodes.size(); }
|
||||
unsigned int getNumNodes() const {return (unsigned int) m_nodes.size(); }
|
||||
int get(const std::string &attribute, std::string *value) const;
|
||||
int get(const std::string &attribute, core::stringw *value) const;
|
||||
int get(const std::string &attribute, int32_t *value) const;
|
||||
|
@ -207,9 +207,9 @@ void ItemManager::insertItem(Item *item)
|
||||
// Find where the item can be stored in the index list: either in a
|
||||
// previously deleted entry, otherwise at the end.
|
||||
int index = -1;
|
||||
for(index=m_all_items.size()-1; index>=0 && m_all_items[index]; index--) {}
|
||||
for(index=(int)m_all_items.size()-1; index>=0 && m_all_items[index]; index--) {}
|
||||
|
||||
if(index==-1) index = m_all_items.size();
|
||||
if(index==-1) index = (int)m_all_items.size();
|
||||
|
||||
if(index<(int)m_all_items.size())
|
||||
m_all_items[index] = item;
|
||||
@ -422,7 +422,7 @@ void ItemManager::deleteItem(Item *item)
|
||||
int sector = QuadGraph::UNKNOWN_SECTOR;
|
||||
QuadGraph::get()->findRoadSector(xyz, §or);
|
||||
unsigned int indx = sector==QuadGraph::UNKNOWN_SECTOR
|
||||
? m_items_in_quads->size()-1
|
||||
? (unsigned int) m_items_in_quads->size()-1
|
||||
: sector;
|
||||
AllItemTypes &items = (*m_items_in_quads)[indx];
|
||||
AllItemTypes::iterator it = std::find(items.begin(), items.end(),item);
|
||||
|
@ -111,7 +111,7 @@ public:
|
||||
void switchItems ();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the number of items. */
|
||||
unsigned int getNumberOfItems() const { return m_all_items.size(); }
|
||||
unsigned int getNumberOfItems() const { return (unsigned int) m_all_items.size(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a pointer to the n-th item. */
|
||||
const Item* getItem(unsigned int n) const { return m_all_items[n]; };
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "physics/physics.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "graphics/glwrap.hpp"
|
||||
|
||||
#include "utils/log.hpp" //TODO: remove after debugging is done
|
||||
|
||||
@ -69,6 +70,10 @@ RubberBand::RubberBand(Plunger *plunger, AbstractKart *kart)
|
||||
verts[i].Color = color;
|
||||
}
|
||||
|
||||
// Color
|
||||
mb->getMaterial().setTexture(0, getUnicolorTexture(video::SColor(255, 255, 255, 255)));
|
||||
// Gloss
|
||||
mb->getMaterial().setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0)));
|
||||
updatePosition();
|
||||
m_node = irr_driver->addMesh(m_mesh);
|
||||
irr_driver->applyObjectPassShader(m_node);
|
||||
|
@ -46,8 +46,6 @@ CannonAnimation::CannonAnimation(AbstractKart *kart, Ipo *ipo)
|
||||
const float dt = 0.1f;
|
||||
Vec3 xyz1;
|
||||
m_curve->update(dt, &xyz1);
|
||||
core::vector3df rot1 = (xyz1-m_previous_orig_xyz).toIrrVector()
|
||||
.getHorizontalAngle();
|
||||
core::vector3df rot = (m_previous_orig_xyz-xyz1).toIrrVector()
|
||||
.getHorizontalAngle();
|
||||
btQuaternion q(Vec3(0,1,0),rot.Y*DEGREE_TO_RAD);
|
||||
|
@ -194,9 +194,7 @@ void EndController::update(float dt)
|
||||
}
|
||||
/*Get information that is needed by more than 1 of the handling funcs*/
|
||||
//Detect if we are going to crash with the track and/or kart
|
||||
int steps = 0;
|
||||
|
||||
steps = calcSteps();
|
||||
calcSteps();
|
||||
|
||||
/*Response handling functions*/
|
||||
handleSteering(dt);
|
||||
|
@ -1118,7 +1118,7 @@ void SkiddingAI::evaluateItems(const Item *item, float kart_aim_angle,
|
||||
// This list is usually very short, so use a simple bubble sort
|
||||
list->push_back(item);
|
||||
int i;
|
||||
for(i=list->size()-2; i>=0; i--)
|
||||
for(i=(int)list->size()-2; i>=0; i--)
|
||||
{
|
||||
float d = ((*list)[i]->getXYZ() - m_kart->getXYZ()).length2_2d();
|
||||
if(d<=new_distance)
|
||||
|
@ -572,7 +572,6 @@ void Kart::createPhysics()
|
||||
{
|
||||
// First: Create the chassis of the kart
|
||||
// -------------------------------------
|
||||
float kart_width = getKartWidth();
|
||||
float kart_length = getKartLength();
|
||||
float kart_height = getKartHeight();
|
||||
|
||||
@ -2606,7 +2605,7 @@ void Kart::setOnScreenText(const wchar_t *text)
|
||||
if (irr_driver->isGLSL())
|
||||
{
|
||||
gui::ScalableFont* font = GUIEngine::getFont() ? GUIEngine::getFont() : GUIEngine::getTitleFont();
|
||||
STKTextBillboard* tb = new STKTextBillboard(text, font,
|
||||
new STKTextBillboard(text, font,
|
||||
video::SColor(255, 255, 225, 0),
|
||||
video::SColor(255, 255, 89, 0),
|
||||
getNode(), irr_driver->getSceneManager(), -1,
|
||||
|
@ -99,7 +99,7 @@ public:
|
||||
void removeLastSelectedKart() { m_selected_karts.pop_back(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the number of selected karts (used in networking only). */
|
||||
int getNumSelectedKarts() const { return m_selected_karts.size(); }
|
||||
int getNumSelectedKarts() const { return (int) m_selected_karts.size(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Sets a kartid to be selected (used in networking only). */
|
||||
void selectKart(int kartid) { m_selected_karts.push_back(kartid); }
|
||||
|
@ -468,6 +468,6 @@ unsigned int Skidding::getSkidBonus(float *bonus_time,
|
||||
*bonus_time = m_skid_bonus_time[i];
|
||||
*bonus_force = m_skid_bonus_force[i];
|
||||
}
|
||||
return m_skid_bonus_speed.size();
|
||||
return (unsigned int) m_skid_bonus_speed.size();
|
||||
} // getSkidBonusForce
|
||||
|
||||
|
@ -151,7 +151,7 @@ public:
|
||||
float getSkidReduceTurnMax () const { return m_skid_reduce_turn_max; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how many boni are defined for this kart. */
|
||||
int getNumberOfBonusTimes() const { return m_skid_bonus_time.size(); }
|
||||
int getNumberOfBonusTimes() const { return (int) m_skid_bonus_time.size(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns how long a kart must skid in order to reach the specified
|
||||
* bonus level.
|
||||
|
@ -452,8 +452,6 @@ void cmdLineHelp()
|
||||
" --mode=N N=1 novice, N=2 driver, N=3 racer.\n"
|
||||
" --type=N N=0 Normal, N=1 Time trial, N=2 FTL\n"
|
||||
" --reverse Play track in reverse (if allowed)\n"
|
||||
// TODO: add back "--players" switch
|
||||
// " --players n Define number of players to between 1 and 4.\n"
|
||||
" -f, --fullscreen Select fullscreen display.\n"
|
||||
" -w, --windowed Windowed display (default).\n"
|
||||
" -s, --screensize=WxH Set the screen size (e.g. 320x200).\n"
|
||||
@ -772,7 +770,7 @@ int handleCmdLine()
|
||||
const std::vector<std::string> l=StringUtils::split(std::string(s),',');
|
||||
race_manager->setDefaultAIKartList(l);
|
||||
// Add 1 for the player kart
|
||||
race_manager->setNumKarts(l.size()+1);
|
||||
race_manager->setNumKarts((int)l.size()+1);
|
||||
} // --ai
|
||||
|
||||
if(CommandLine::has( "--mode", &s))
|
||||
@ -1415,8 +1413,6 @@ int main(int argc, char *argv[] )
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
return 0 ;
|
||||
} // main
|
||||
|
||||
@ -1441,6 +1437,7 @@ static void cleanSuperTuxKart()
|
||||
if(Online::RequestManager::isRunning())
|
||||
Online::RequestManager::get()->stopNetworkThread();
|
||||
|
||||
SFXManager::get()->stopThread();
|
||||
irr_driver->updateConfigIfRelevant();
|
||||
AchievementsManager::destroy();
|
||||
Referee::cleanup();
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "audio/music_manager.hpp"
|
||||
#include "audio/sfx_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "graphics/material_manager.hpp"
|
||||
@ -140,7 +139,6 @@ void MainLoop::run()
|
||||
{
|
||||
PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00);
|
||||
music_manager->update(dt);
|
||||
SFXManager::get()->update();
|
||||
input_manager->update(dt);
|
||||
|
||||
#ifdef ENABLE_WIIUSE
|
||||
|
@ -87,7 +87,7 @@ void LinearWorld::reset()
|
||||
m_last_lap_sfx_played = false;
|
||||
m_last_lap_sfx_playing = false;
|
||||
|
||||
const unsigned int kart_amount = m_karts.size();
|
||||
const unsigned int kart_amount = (unsigned int) m_karts.size();
|
||||
for(unsigned int i=0; i<kart_amount; i++)
|
||||
{
|
||||
m_kart_info[i].reset();
|
||||
@ -650,7 +650,7 @@ void LinearWorld::updateRacePosition()
|
||||
{
|
||||
// Mostly for debugging:
|
||||
beginSetKartPositions();
|
||||
const unsigned int kart_amount = m_karts.size();
|
||||
const unsigned int kart_amount = (unsigned int) m_karts.size();
|
||||
|
||||
#ifdef DEBUG
|
||||
bool rank_changed = false;
|
||||
|
@ -120,7 +120,7 @@ void OverWorld::update(float dt)
|
||||
}
|
||||
WorldWithRank::update(dt);
|
||||
WorldWithRank::updateTrack(dt);
|
||||
const unsigned int kart_amount = m_karts.size();
|
||||
const unsigned int kart_amount = (unsigned int)m_karts.size();
|
||||
|
||||
// isn't it cool, on the overworld nitro is free!
|
||||
for(unsigned int n=0; n<kart_amount; n++)
|
||||
|
@ -263,7 +263,7 @@ void ProfileWorld::enterRaceOverState()
|
||||
for(std::set<std::string>::iterator it = all_groups.begin();
|
||||
it !=all_groups.end(); it++)
|
||||
{
|
||||
if(it->size()>max_len) max_len = it->size();
|
||||
if(it->size()>max_len) max_len = (unsigned int) it->size();
|
||||
}
|
||||
max_len++; // increase by 1 for one additional space after the name
|
||||
|
||||
@ -281,7 +281,7 @@ void ProfileWorld::enterRaceOverState()
|
||||
int expl_count = 0, off_track_count = 0;
|
||||
float skidding_time = 0.0f, rescue_time = 0.0f, expl_time = 0.0f;
|
||||
float av_time = 0.0f;
|
||||
for ( unsigned int i = 0; i < m_karts.size(); ++i)
|
||||
for ( unsigned int i = 0; i < (unsigned int)m_karts.size(); ++i)
|
||||
{
|
||||
KartWithStats* kart = dynamic_cast<KartWithStats*>(m_karts[i]);
|
||||
const std::string &name=kart->getController()->getControllerName();
|
||||
|
@ -87,7 +87,7 @@ const std::string& StandardRace::getIdent() const
|
||||
*/
|
||||
void StandardRace::endRaceEarly()
|
||||
{
|
||||
const unsigned int kart_amount = m_karts.size();
|
||||
const unsigned int kart_amount = (unsigned int)m_karts.size();
|
||||
std::vector<int> active_players;
|
||||
// Required for debugging purposes
|
||||
beginSetKartPositions();
|
||||
@ -110,7 +110,7 @@ void StandardRace::endRaceEarly()
|
||||
else
|
||||
{
|
||||
// AI karts finish
|
||||
setKartPosition(kartid, i - active_players.size());
|
||||
setKartPosition(kartid, i - (unsigned int) active_players.size());
|
||||
kart->finishedRace(estimateFinishTimeForKart(kart));
|
||||
}
|
||||
} // i <= kart_amount
|
||||
@ -118,7 +118,7 @@ void StandardRace::endRaceEarly()
|
||||
for (unsigned int i = 0; i < active_players.size(); i++)
|
||||
{
|
||||
int kartid = active_players[i];
|
||||
int position = getNumKarts() - active_players.size() + 1 + i;
|
||||
int position = getNumKarts() - (int) active_players.size() + 1 + i;
|
||||
setKartPosition(kartid, position);
|
||||
m_karts[kartid]->eliminate();
|
||||
} // Finish the active players
|
||||
|
@ -569,7 +569,7 @@ void World::resetAllKarts()
|
||||
if(UserConfigParams::m_track_debug)
|
||||
{
|
||||
// Loop over all karts, in case that some karts are dfferent
|
||||
for(unsigned int kart_id=0; kart_id<m_karts.size(); kart_id++)
|
||||
for(unsigned int kart_id=0; kart_id<(unsigned int)m_karts.size(); kart_id++)
|
||||
{
|
||||
for(unsigned int rescue_pos=0;
|
||||
rescue_pos<getNumberOfRescuePositions();
|
||||
@ -1020,7 +1020,7 @@ void World::updateHighscores(int* best_highscore_rank, int* best_finish_time,
|
||||
// if we ever decide to display a message (e.g. during a race)
|
||||
unsigned int *index = new unsigned int[m_karts.size()];
|
||||
|
||||
const unsigned int kart_amount = m_karts.size();
|
||||
const unsigned int kart_amount = (unsigned int) m_karts.size();
|
||||
for (unsigned int i=0; i<kart_amount; i++ )
|
||||
{
|
||||
index[i] = 999; // first reset the contents of the array
|
||||
|
@ -290,7 +290,7 @@ public:
|
||||
RaceGUIBase *getRaceGUI() const { return m_race_gui;}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the number of karts in the race. */
|
||||
unsigned int getNumKarts() const { return m_karts.size(); }
|
||||
unsigned int getNumKarts() const { return (unsigned int) m_karts.size(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the kart with a given world id. */
|
||||
AbstractKart *getKart(int kartId) const {
|
||||
|
@ -95,7 +95,10 @@ void* waitInput(void* data)
|
||||
clrp->voteRaceCount(cnt);
|
||||
}
|
||||
}
|
||||
else if (NetworkManager::getInstance()->getPeers().size() > 0)
|
||||
// If STK shuts down, but should receive an input after the network
|
||||
// manager was deleted, the getInstance call will return NULL.
|
||||
else if (NetworkManager::getInstance() &&
|
||||
NetworkManager::getInstance()->getPeers().size() > 0)
|
||||
{
|
||||
NetworkString msg;
|
||||
msg.ai8(0);
|
||||
@ -136,6 +139,14 @@ void ClientNetworkManager::run()
|
||||
|
||||
Log::info("ClientNetworkManager", "Host initialized.");
|
||||
|
||||
m_thread_keyboard = NULL;
|
||||
// This code can cause crashes atm (see #1529): if the
|
||||
// client_network_manager receives input after the network manager
|
||||
// has been deleted, stk will crash. And this happens on windows
|
||||
// in release mode (since there is no console, so no stdin), and
|
||||
// apparently on osx at shutdown time - getline returns an empty string
|
||||
// (not sure if it has an error condition).
|
||||
#ifdef RE_ENABLE_LATER
|
||||
// On windows in release mode the console is suppressed, so nothing can
|
||||
// be read from std::cin. Since getline(std::cin,...) then returns
|
||||
// an empty string, the waitInput thread is running all the time, consuming
|
||||
@ -146,6 +157,7 @@ void ClientNetworkManager::run()
|
||||
// listen keyboard console input
|
||||
m_thread_keyboard = (pthread_t*)(malloc(sizeof(pthread_t)));
|
||||
pthread_create(m_thread_keyboard, NULL, waitInput, NULL);
|
||||
#endif
|
||||
#endif
|
||||
NetworkManager::run();
|
||||
|
||||
|
@ -382,8 +382,7 @@ void btKart::updateVehicle( btScalar step )
|
||||
m_visual_wheels_touch_ground = true;
|
||||
for (int i=0;i<m_wheelInfo.size();i++)
|
||||
{
|
||||
btScalar depth;
|
||||
depth = rayCast( i);
|
||||
rayCast( i);
|
||||
if(m_wheelInfo[i].m_raycastInfo.m_isInContact)
|
||||
m_num_wheels_on_ground++;
|
||||
}
|
||||
|
@ -75,11 +75,13 @@ void* btKartRaycaster::castRay(const btVector3& from, const btVector3& to,
|
||||
if(m_smooth_normals &&
|
||||
rayCallback.getTriangleIndex()>-1)
|
||||
{
|
||||
#undef DEBUG_NORMALS
|
||||
#ifdef DEBUG_NORMALS
|
||||
btVector3 n=result.m_hitNormalInWorld;
|
||||
#endif
|
||||
result.m_hitNormalInWorld =
|
||||
tm.getInterpolatedNormal(rayCallback.getTriangleIndex(),
|
||||
result.m_hitPointInWorld);
|
||||
#undef DEBUG_NORMALS
|
||||
#ifdef DEBUG_NORMALS
|
||||
printf("old %f %f %f new %f %f %f\n",
|
||||
n.getX(), n.getY(), n.getZ(),
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "race/grand_prix_data.hpp"
|
||||
|
||||
#include "config/player_profile.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "config/player_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
@ -39,12 +40,13 @@
|
||||
/** Loads a grand prix definition from a file.
|
||||
* \param filename Name of the file to load.
|
||||
*/
|
||||
GrandPrixData::GrandPrixData(const std::string& filename)
|
||||
GrandPrixData::GrandPrixData(const std::string& filename, enum GPGroupType group)
|
||||
{
|
||||
m_filename = filename;
|
||||
m_id = StringUtils::getBasename(
|
||||
StringUtils::removeExtension(filename));
|
||||
setFilename(filename);
|
||||
m_id = StringUtils::getBasename(StringUtils::removeExtension(filename));
|
||||
m_editable = (filename.find(file_manager->getGPDir(), 0) == 0);
|
||||
m_group = group;
|
||||
|
||||
reload();
|
||||
} // GrandPrixData
|
||||
|
||||
@ -56,7 +58,7 @@ GrandPrixData::GrandPrixData(const std::string& filename)
|
||||
* \param new_tracks If true, new tracks are selected, otherwise existing
|
||||
* tracks will not be changed (used to e.g. increase the number of
|
||||
* tracks in an already existing random grand prix).
|
||||
*
|
||||
*
|
||||
*/
|
||||
void GrandPrixData::createRandomGP(const unsigned int number_of_tracks,
|
||||
const std::string &track_group,
|
||||
@ -67,6 +69,7 @@ void GrandPrixData::createRandomGP(const unsigned int number_of_tracks,
|
||||
m_id = "random";
|
||||
m_name = "Random Grand Prix";
|
||||
m_editable = false;
|
||||
m_group = GP_NONE;
|
||||
|
||||
if(new_tracks)
|
||||
{
|
||||
@ -202,6 +205,15 @@ void GrandPrixData::setEditable(const bool editable)
|
||||
m_editable = editable;
|
||||
} // setEditable
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets the group of this grand prix.
|
||||
* \param editable New value.
|
||||
*/
|
||||
void GrandPrixData::setGroup(const enum GPGroupType group)
|
||||
{
|
||||
m_group = group;
|
||||
} // setGroup
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Reloads grand prix from file.
|
||||
*/
|
||||
@ -241,10 +253,9 @@ void GrandPrixData::reload()
|
||||
const int amount = root->getNumNodes();
|
||||
if (amount == 0)
|
||||
{
|
||||
Log::error("GrandPrixData",
|
||||
"Error while trying to read grandprix file '%s': "
|
||||
"There is no track defined", m_filename.c_str());
|
||||
throw std::runtime_error("No track defined");
|
||||
Log::warn("GrandPrixData",
|
||||
"Grandprix file '%s': There is no track defined",
|
||||
m_filename.c_str());
|
||||
}
|
||||
|
||||
// Every iteration means parsing one track entry
|
||||
|
@ -36,6 +36,17 @@ class Track;
|
||||
*/
|
||||
class GrandPrixData
|
||||
{
|
||||
public:
|
||||
/** Used to classify GPs into groups */
|
||||
enum GPGroupType
|
||||
{
|
||||
GP_NONE = 0, ///< No group
|
||||
GP_STANDARD, ///< Standard GP, included with the game
|
||||
GP_USER_DEFINED, ///< Created by the user
|
||||
GP_ADDONS, ///< Add-on GP
|
||||
GP_GROUP_COUNT ///< Number of groups
|
||||
}; // GPGroupType
|
||||
|
||||
private:
|
||||
/** The name of the grand prix. */
|
||||
irr::core::stringw m_name;
|
||||
@ -60,6 +71,9 @@ private:
|
||||
/** Wether the user can edit this grand prix or not */
|
||||
bool m_editable;
|
||||
|
||||
/** Group to which this GP belongs. */
|
||||
enum GPGroupType m_group;
|
||||
|
||||
/** In the last GP Fort Magma can not be used untill the final challenge.
|
||||
* In order to provide still 5 tracks/GP, the last GP is only using 4
|
||||
* tracks in story mode, but once nolok is unlocked Fort Magma becomes
|
||||
@ -84,7 +98,7 @@ public:
|
||||
# pragma warning(disable:4290)
|
||||
#endif
|
||||
/** Load the GrandPrixData from the given filename */
|
||||
GrandPrixData(const std::string& filename);
|
||||
GrandPrixData(const std::string& filename, enum GPGroupType group);
|
||||
|
||||
/** Needed for simple creation of an instance of GrandPrixData */
|
||||
GrandPrixData() {};
|
||||
@ -103,6 +117,7 @@ public:
|
||||
void setName(const irr::core::stringw& name);
|
||||
void setFilename(const std::string& filename);
|
||||
void setEditable(const bool editable);
|
||||
void setGroup(const enum GPGroupType group);
|
||||
/** Load the grand prix from the file set by the constructor or the grand
|
||||
* prix editor */
|
||||
void reload();
|
||||
@ -141,6 +156,10 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the filename of the grand prix xml file. */
|
||||
const std::string& getFilename() const { return m_filename; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the group. */
|
||||
enum GPGroupType getGroup() const { return m_group; }
|
||||
}; // GrandPrixData
|
||||
|
||||
#endif
|
||||
|
@ -20,11 +20,11 @@
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "race/grand_prix_data.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <sstream>
|
||||
|
||||
GrandPrixManager *grand_prix_manager = NULL;
|
||||
@ -47,44 +47,47 @@ GrandPrixManager::~GrandPrixManager()
|
||||
// ----------------------------------------------------------------------------
|
||||
void GrandPrixManager::loadFiles()
|
||||
{
|
||||
// Add the directories to a set to avoid duplicates
|
||||
std::set<std::string> dirs;
|
||||
std::string dir;
|
||||
|
||||
// Add all the directories to a set to avoid duplicates
|
||||
dirs.insert(file_manager->getAsset(FileManager::GRANDPRIX, ""));
|
||||
dirs.insert(file_manager->getGPDir());
|
||||
dirs.insert(UserConfigParams::m_additional_gp_directory);
|
||||
//Standard GPs
|
||||
loadDir(file_manager->getAsset(FileManager::GRANDPRIX, ""), GrandPrixData::GP_STANDARD);
|
||||
|
||||
for (std::set<std::string>::const_iterator it = dirs.begin();
|
||||
it != dirs.end (); ++it)
|
||||
{
|
||||
std::string dir = *it;
|
||||
if (!dir.empty() && dir[dir.size() - 1] == '/')
|
||||
loadDir(dir);
|
||||
}
|
||||
//User defined GPs
|
||||
dir = file_manager->getGPDir();
|
||||
if (!dir.empty() && dir[dir.size() - 1] == '/' && dirs.count(dir) == 0)
|
||||
loadDir(dir, GrandPrixData::GP_USER_DEFINED);
|
||||
|
||||
//Add-on GPs
|
||||
dir = UserConfigParams::m_additional_gp_directory;
|
||||
if (!dir.empty() && dir[dir.size() - 1] == '/' && dirs.count(dir) == 0)
|
||||
loadDir(dir, GrandPrixData::GP_ADDONS);
|
||||
} // loadFiles
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GrandPrixManager::loadDir(const std::string& dir)
|
||||
void GrandPrixManager::loadDir(const std::string& dir, enum GrandPrixData::GPGroupType group)
|
||||
{
|
||||
Log::info("GrandPrixManager",
|
||||
"Loading Grand Prix files from %s", dir.c_str());
|
||||
assert(!dir.empty() && dir[dir.size() - 1] == '/');
|
||||
|
||||
// Findout which grand prix are available and load them
|
||||
// Find out which grand prix are available and load them
|
||||
std::set<std::string> result;
|
||||
file_manager->listFiles(result, dir);
|
||||
for(std::set<std::string>::iterator i = result.begin();
|
||||
i != result.end(); i++)
|
||||
for(std::set<std::string>::iterator i = result.begin(); i != result.end(); i++)
|
||||
{
|
||||
if (StringUtils::hasSuffix(*i, SUFFIX))
|
||||
load(dir + *i);
|
||||
load(dir + *i, group);
|
||||
}
|
||||
} // loadDir
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GrandPrixManager::load(const std::string& filename)
|
||||
void GrandPrixManager::load(const std::string& filename, enum GrandPrixData::GPGroupType group)
|
||||
{
|
||||
try
|
||||
{
|
||||
GrandPrixData* gp = new GrandPrixData(filename);
|
||||
GrandPrixData* gp = new GrandPrixData(filename, group);
|
||||
m_gp_data.push_back(gp);
|
||||
Log::debug("GrandPrixManager",
|
||||
"Grand Prix '%s' loaded from %s",
|
||||
@ -188,6 +191,7 @@ GrandPrixData* GrandPrixManager::createNewGP(const irr::core::stringw& newName)
|
||||
gp->setName(newName);
|
||||
gp->setFilename(file_manager->getGPDir() + newID + SUFFIX);
|
||||
gp->setEditable(true);
|
||||
gp->setGroup(GrandPrixData::GP_USER_DEFINED);
|
||||
gp->writeToFile();
|
||||
m_gp_data.push_back(gp);
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef HEADER_GRAND_PRIX_MANAGER_HPP
|
||||
#define HEADER_GRAND_PRIX_MANAGER_HPP
|
||||
|
||||
#include "race/grand_prix_data.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
@ -38,9 +40,9 @@ private:
|
||||
/** Load all the grands prix from the 3 directories known */
|
||||
void loadFiles();
|
||||
/** Load all the grands prix in one directory */
|
||||
void loadDir(const std::string& dir);
|
||||
void loadDir(const std::string& dir, enum GrandPrixData::GPGroupType group);
|
||||
/** Load a grand prix and add it to m_gp_data*/
|
||||
void load(const std::string &filename);
|
||||
void load(const std::string &filename, enum GrandPrixData::GPGroupType group);
|
||||
|
||||
/** Generates a new unique indentifier for a user defined grand prix */
|
||||
std::string generateId();
|
||||
@ -49,9 +51,7 @@ public:
|
||||
GrandPrixManager();
|
||||
~GrandPrixManager();
|
||||
void reload();
|
||||
GrandPrixData* getGrandPrix(const int i) const { return m_gp_data[i]; }
|
||||
GrandPrixData* getGrandPrix(const std::string& s) const;
|
||||
unsigned int getNumberOfGrandPrix() const { return m_gp_data.size(); }
|
||||
bool existsName(const irr::core::stringw& name) const;
|
||||
void checkConsistency();
|
||||
|
||||
@ -61,6 +61,13 @@ public:
|
||||
GrandPrixData* copy(const std::string& id,
|
||||
const irr::core::stringw& newName);
|
||||
void remove(const std::string& id);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns a pointer to the data for the specified GP.
|
||||
* \param i Index of the GP. */
|
||||
GrandPrixData* getGrandPrix(const int i) const { return m_gp_data[i]; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the number of GPs. */
|
||||
unsigned int getNumberOfGrandPrix() const { return (int)m_gp_data.size(); }
|
||||
}; // GrandPrixManager
|
||||
|
||||
extern GrandPrixManager *grand_prix_manager;
|
||||
|
@ -181,7 +181,7 @@ const AbstractKart *RaceManager::getKartWithGPRank(unsigned int n)
|
||||
*/
|
||||
int RaceManager::getLocalPlayerGPRank(const int player_id) const
|
||||
{
|
||||
const int amount = m_kart_status.size();
|
||||
const int amount = (int)m_kart_status.size();
|
||||
for (int n=0; n<amount; n++)
|
||||
{
|
||||
if (m_kart_status[n].m_local_player_id == player_id)
|
||||
@ -238,7 +238,7 @@ void RaceManager::setTrack(const std::string& track)
|
||||
*/
|
||||
void RaceManager::computeRandomKartList()
|
||||
{
|
||||
int n = m_num_karts - m_player_karts.size();
|
||||
int n = m_num_karts - (int)m_player_karts.size();
|
||||
if(UserConfigParams::logMisc())
|
||||
std::cout << "AI karts count = " << n << " for m_num_karts="
|
||||
<< m_num_karts << " and m_player_karts.size()="
|
||||
@ -309,7 +309,7 @@ void RaceManager::startNew(bool from_overworld)
|
||||
race_manager->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER
|
||||
? -1
|
||||
: 0;
|
||||
const unsigned int ai_kart_count = m_ai_kart_list.size();
|
||||
const unsigned int ai_kart_count = (unsigned int) m_ai_kart_list.size();
|
||||
for(unsigned int i=0; i<ai_kart_count; i++)
|
||||
{
|
||||
m_kart_status.push_back(KartStatus(m_ai_kart_list[i], i, -1, -1,
|
||||
@ -324,7 +324,7 @@ void RaceManager::startNew(bool from_overworld)
|
||||
|
||||
// Then the players, which start behind the AI karts
|
||||
// -------------------------------------------------
|
||||
for(unsigned int i=0; i<m_player_karts.size(); i++)
|
||||
for(unsigned int i=0; i<(int)m_player_karts.size(); i++)
|
||||
{
|
||||
KartType kt= m_player_karts[i].isNetworkPlayer() ? KT_NETWORK_PLAYER : KT_PLAYER;
|
||||
m_kart_status.push_back(KartStatus(m_player_karts[i].getKartName(), i,
|
||||
@ -408,7 +408,7 @@ void RaceManager::startNextRace()
|
||||
// the end because of the simple reason that they
|
||||
// are at the end when getting added. Keep them out
|
||||
// of the later sorting and they will stay there.
|
||||
player_last_offset = m_player_karts.size();
|
||||
player_last_offset = (int)m_player_karts.size();
|
||||
}
|
||||
|
||||
std::sort(m_kart_status.begin()+offset,
|
||||
@ -645,13 +645,13 @@ void RaceManager::exitRace(bool delete_world)
|
||||
StateManager::get()->resetAndGoToScreen( MainMenuScreen::getInstance() );
|
||||
|
||||
bool someHumanPlayerWon = false;
|
||||
const unsigned int kartStatusCount = m_kart_status.size();
|
||||
const unsigned int kart_status_count = (unsigned int)m_kart_status.size();
|
||||
|
||||
const int loserThreshold = 3;
|
||||
|
||||
std::string winners[3];
|
||||
std::vector<std::string> humanLosers; // because we don't care about AIs that lost
|
||||
for (unsigned int i=0; i < kartStatusCount; ++i)
|
||||
for (unsigned int i=0; i < kart_status_count; ++i)
|
||||
{
|
||||
if(UserConfigParams::logMisc())
|
||||
{
|
||||
|
@ -476,7 +476,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
unsigned int getNumLocalPlayers() const
|
||||
{
|
||||
return m_local_player_karts.size();
|
||||
return (unsigned int)m_local_player_karts.size();
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the selected number of karts (selected number of players and
|
||||
@ -488,7 +488,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
MinorRaceModeType getMinorMode() const { return m_minor_mode; }
|
||||
// ------------------------------------------------------------------------
|
||||
unsigned int getNumPlayers() const { return m_player_karts.size(); }
|
||||
unsigned int getNumPlayers() const { return (unsigned int) m_player_karts.size(); }
|
||||
// ------------------------------------------------------------------------
|
||||
/** \brief Returns the number lf laps.
|
||||
* In case of FTL or battle mode always return 9999, since they don't
|
||||
|
@ -67,7 +67,7 @@ void ArenasScreen::beforeAddingWidget()
|
||||
|
||||
bool soccer_mode = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;
|
||||
const std::vector<std::string>& groups = track_manager->getAllArenaGroups(soccer_mode);
|
||||
const int group_amount = groups.size();
|
||||
const int group_amount = (int)groups.size();
|
||||
|
||||
if (group_amount > 1)
|
||||
{
|
||||
@ -161,7 +161,7 @@ void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const
|
||||
}
|
||||
|
||||
RandomGenerator random;
|
||||
const int randomID = random.get(curr_group.size());
|
||||
const int randomID = random.get((int)curr_group.size());
|
||||
|
||||
Track* clicked_track = track_manager->getTrack( curr_group[randomID] );
|
||||
if (clicked_track != NULL)
|
||||
@ -218,9 +218,9 @@ void ArenasScreen::buildTrackList()
|
||||
|
||||
if (curr_group_name == ALL_ARENA_GROUPS_ID)
|
||||
{
|
||||
const int trackAmount = track_manager->getNumberOfTracks();
|
||||
const int track_amount = (int)track_manager->getNumberOfTracks();
|
||||
|
||||
for (int n=0; n<trackAmount; n++)
|
||||
for (int n=0; n<track_amount; n++)
|
||||
{
|
||||
Track* curr = track_manager->getTrack(n);
|
||||
if (soccer_mode)
|
||||
@ -248,9 +248,9 @@ void ArenasScreen::buildTrackList()
|
||||
else
|
||||
{
|
||||
const std::vector<int>& currArenas = track_manager->getArenasInGroup(curr_group_name, soccer_mode);
|
||||
const int trackAmount = currArenas.size();
|
||||
const int track_amount = (int)currArenas.size();
|
||||
|
||||
for (int n=0; n<trackAmount; n++)
|
||||
for (int n=0; n<track_amount; n++)
|
||||
{
|
||||
Track* curr = track_manager->getTrack(currArenas[n]);
|
||||
if (soccer_mode)
|
||||
|
@ -350,7 +350,7 @@ void CreditsScreen::onUpdate(float elapsed_time)
|
||||
color, false /* center h */, true /* center v */, NULL,
|
||||
true /* ignore RTL */ );
|
||||
|
||||
const int subamount = m_sections[m_curr_section]
|
||||
const int subamount = (int)m_sections[m_curr_section]
|
||||
.m_entries[m_curr_element].m_subentries.size();
|
||||
int suby = m_y + m_h/3;
|
||||
const int inc = subamount == 0 ? m_h/8
|
||||
|
@ -187,6 +187,7 @@ void EditGPScreen::init()
|
||||
loadList(m_selected);
|
||||
m_action.clear();
|
||||
}
|
||||
enableButtons();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -213,7 +214,10 @@ void EditGPScreen::onCancel()
|
||||
{
|
||||
ModalDialog::dismiss();
|
||||
if (m_action == "back")
|
||||
{
|
||||
m_gp->reload(); // Discard changes
|
||||
back();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -231,8 +235,14 @@ void EditGPScreen::loadList(const int selected)
|
||||
|
||||
Track* t = track_manager->getTrack(m_gp->getTrackId(i));
|
||||
assert(t != NULL);
|
||||
|
||||
video::ITexture* screenShot = irr_driver->getTexture(t->getScreenshotFile());
|
||||
assert(screenShot != NULL);
|
||||
if (screenShot == NULL)
|
||||
{
|
||||
screenShot = irr_driver->getTexture(
|
||||
file_manager->getAsset(FileManager::GUI, "main_help.png"));
|
||||
}
|
||||
assert (screenShot != NULL);
|
||||
m_icons.push_back(m_icon_bank->addTextureAsSprite(screenShot));
|
||||
|
||||
row.push_back(GUIEngine::ListWidget::ListCell(
|
||||
@ -264,15 +274,19 @@ void EditGPScreen::setModified(const bool modified)
|
||||
save_button->setActivated();
|
||||
else
|
||||
save_button->setDeactivated();
|
||||
|
||||
LabelWidget* header = getWidget<LabelWidget>("title");
|
||||
assert(header != NULL);
|
||||
header->setText(m_gp->getName() + (modified ? L" (+)" : L""), true);
|
||||
|
||||
enableButtons();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::setSelected(const int selected)
|
||||
{
|
||||
assert(getWidget<IconButtonWidget>("up") != NULL);
|
||||
assert(getWidget<IconButtonWidget>("down") != NULL);
|
||||
|
||||
m_selected = selected;
|
||||
enableButtons();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -327,3 +341,38 @@ bool EditGPScreen::canMoveDown() const
|
||||
{
|
||||
return (0 <= m_selected && m_selected < m_list->getItemCount() - 1);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditGPScreen::enableButtons()
|
||||
{
|
||||
IconButtonWidget* up_button = getWidget<IconButtonWidget>("up");
|
||||
IconButtonWidget* down_button = getWidget<IconButtonWidget>("down");
|
||||
IconButtonWidget* edit_button = getWidget<IconButtonWidget>("edit");
|
||||
IconButtonWidget* remove_button = getWidget<IconButtonWidget>("remove");
|
||||
assert(up_button != NULL);
|
||||
assert(down_button != NULL);
|
||||
assert(edit_button != NULL);
|
||||
assert(remove_button != NULL);
|
||||
|
||||
if (m_selected >= 0 && m_list->getItemCount() > 1)
|
||||
{
|
||||
up_button->setActivated();
|
||||
down_button->setActivated();
|
||||
}
|
||||
else
|
||||
{
|
||||
up_button->setDeactivated();
|
||||
down_button->setDeactivated();
|
||||
}
|
||||
|
||||
if (m_selected >= 0)
|
||||
{
|
||||
edit_button->setActivated();
|
||||
remove_button->setActivated();
|
||||
}
|
||||
else
|
||||
{
|
||||
edit_button->setDeactivated();
|
||||
remove_button->setDeactivated();
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,8 @@ class EditGPScreen :
|
||||
bool canMoveUp() const;
|
||||
bool canMoveDown() const;
|
||||
|
||||
void enableButtons();
|
||||
|
||||
GrandPrixData* m_gp;
|
||||
GUIEngine::ListWidget* m_list;
|
||||
irr::gui::STKModifiedSpriteBank* m_icon_bank;
|
||||
|
@ -173,7 +173,7 @@ void EditTrackScreen::init()
|
||||
// -----------------------------------------------------------------------------
|
||||
void EditTrackScreen::loadTrackList()
|
||||
{
|
||||
bool belongsToGroup;
|
||||
bool belongs_to_group;
|
||||
|
||||
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert(tracks_widget != NULL);
|
||||
@ -183,12 +183,11 @@ void EditTrackScreen::loadTrackList()
|
||||
for (unsigned int i = 0; i < track_manager->getNumberOfTracks(); i++)
|
||||
{
|
||||
Track* t = track_manager->getTrack(i);
|
||||
const std::vector<std::string>& groups = t->getGroups();
|
||||
belongsToGroup = (m_track_group.empty() ||
|
||||
belongs_to_group = (m_track_group.empty() ||
|
||||
m_track_group == ALL_TRACKS_GROUP_ID ||
|
||||
t->isInGroup(m_track_group) );
|
||||
if (!t->isArena() && !t->isSoccer() &&
|
||||
!t->isInternal() && belongsToGroup )
|
||||
!t->isInternal() && belongs_to_group )
|
||||
{
|
||||
tracks_widget->addItem(translations->fribidize(t->getName()),
|
||||
t->getIdent(),
|
||||
|
@ -429,16 +429,15 @@ void FeatureUnlockedCutScene::onUpdate(float dt)
|
||||
|
||||
if (!m_unlocked_stuff[n].m_pictures.empty())
|
||||
{
|
||||
const int pictureCount = m_unlocked_stuff[n].m_pictures.size();
|
||||
const int picture_count = (int)m_unlocked_stuff[n].m_pictures.size();
|
||||
|
||||
if (pictureCount > 1)
|
||||
if (picture_count > 1)
|
||||
{
|
||||
const int previousTextureID = m_unlocked_stuff[n].m_curr_image;
|
||||
const int textureID = int(m_global_time/1.2f) % pictureCount;
|
||||
const int textureID = int(m_global_time/1.2f) % picture_count;
|
||||
|
||||
if (textureID != previousTextureID)
|
||||
{
|
||||
scene::IMeshSceneNode* node = (scene::IMeshSceneNode*)m_unlocked_stuff[n].m_root_gift_node;
|
||||
scene::IMesh* mesh = m_unlocked_stuff[n].m_side_1->getMesh();
|
||||
|
||||
assert(mesh->getMeshBufferCount() == 1);
|
||||
@ -468,7 +467,7 @@ void FeatureUnlockedCutScene::onUpdate(float dt)
|
||||
|
||||
m_unlocked_stuff[n].m_curr_image = textureID;
|
||||
} // textureID != previousTextureID
|
||||
} // if pictureCount>1
|
||||
} // if picture_count>1
|
||||
} // if !m_unlocked_stuff[n].m_pictures.empty()
|
||||
|
||||
float scale = m_unlocked_stuff[n].m_scale;
|
||||
@ -539,16 +538,16 @@ void FeatureUnlockedCutScene::addUnlockedGP(const GrandPrixData* gp)
|
||||
else
|
||||
{
|
||||
const std::vector<std::string> gptracks = gp->getTrackNames();
|
||||
const int trackAmount = gptracks.size();
|
||||
const int track_amount = (int)gptracks.size();
|
||||
|
||||
if (trackAmount == 0)
|
||||
if (track_amount == 0)
|
||||
{
|
||||
std::cerr << "ERROR: Unlocked GP is empty???\n";
|
||||
video::ITexture* WTF_image = irr_driver->getTexture( file_manager->getAsset(FileManager::GUI,"main_help.png"));
|
||||
images.push_back(WTF_image);
|
||||
}
|
||||
|
||||
for (int t=0; t<trackAmount; t++)
|
||||
for (int t=0; t<track_amount; t++)
|
||||
{
|
||||
Track* track = track_manager->getTrack(gptracks[t]);
|
||||
|
||||
|
@ -80,7 +80,6 @@ void GPInfoScreen::loadedFromFile()
|
||||
// Only init the number of tracks here, this way the previously selected
|
||||
// number of tracks will be the default.
|
||||
m_num_tracks_spinner->setValue(1);
|
||||
int number_of_tracks = m_num_tracks_spinner->getValue();
|
||||
} // loadedFromFile
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -157,7 +156,6 @@ void GPInfoScreen::init()
|
||||
|
||||
bool random = m_gp.isRandomGP();
|
||||
|
||||
SpinnerWidget *reverse_spinner = getWidget<SpinnerWidget>("reverse-spinner");
|
||||
getWidget<LabelWidget >("track-text" )->setVisible(random);
|
||||
m_num_tracks_spinner->setVisible(random);
|
||||
getWidget<LabelWidget >("group-text" )->setVisible(random);
|
||||
@ -230,7 +228,7 @@ void GPInfoScreen::addTracks()
|
||||
|
||||
ListWidget *list = getWidget<ListWidget>("tracks");
|
||||
list->clear();
|
||||
for (unsigned int i = 0; i < tracks.size(); i++)
|
||||
for (unsigned int i = 0; i < (unsigned int)tracks.size(); i++)
|
||||
{
|
||||
const Track *track = track_manager->getTrack(tracks[i]);
|
||||
std::string s = StringUtils::toString(i);
|
||||
@ -314,8 +312,6 @@ void GPInfoScreen::eventCallback(Widget *, const std::string &name,
|
||||
? track_manager->getNumberOfRaceTracks()
|
||||
: track_manager->getTracksInGroup(m_group_name).size();
|
||||
m_num_tracks_spinner->setMax(max_num_tracks);
|
||||
int number_of_tracks = std::min(max_num_tracks,
|
||||
m_num_tracks_spinner->getValue());
|
||||
if (m_num_tracks_spinner->getValue() > max_num_tracks)
|
||||
m_num_tracks_spinner->setValue(max_num_tracks);
|
||||
// Create a new (i.e. with new tracks) random gp, since the old
|
||||
@ -364,4 +360,4 @@ void GPInfoScreen::onUpdate(float dt)
|
||||
std::string file = track->getScreenshotFile();
|
||||
m_screenshot_widget->setImage(file, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||
m_screenshot_widget->m_properties[PROP_ICON] = file;
|
||||
} // onUpdate
|
||||
} // onUpdate
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/icon_button_widget.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "race/grand_prix_data.hpp"
|
||||
#include "race/grand_prix_manager.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "states_screens/edit_gp_screen.hpp"
|
||||
@ -39,12 +38,27 @@ using namespace irr::core;
|
||||
|
||||
DEFINE_SCREEN_SINGLETON( GrandPrixEditorScreen );
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
GrandPrixEditorScreen::GrandPrixEditorScreen()
|
||||
: Screen("gpeditor.stkgui"), m_selection(NULL)
|
||||
: Screen("gpeditor.stkgui"), m_selection(NULL), m_gpgroup(GrandPrixData::GP_NONE)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void GrandPrixEditorScreen::beforeAddingWidget()
|
||||
{
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("gpgroups");
|
||||
assert (tabs != NULL);
|
||||
|
||||
tabs->clearAllChildren();
|
||||
for (int i = 0; i < GrandPrixData::GP_GROUP_COUNT; i++)
|
||||
{
|
||||
tabs->addTextChild(getGroupName((enum GrandPrixData::GPGroupType)i),
|
||||
StringUtils::toString(i));
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void GrandPrixEditorScreen::loadedFromFile()
|
||||
{
|
||||
@ -54,13 +68,20 @@ void GrandPrixEditorScreen::loadedFromFile()
|
||||
// -----------------------------------------------------------------------------
|
||||
void GrandPrixEditorScreen::eventCallback(Widget* widget, const std::string& name, const int playerID)
|
||||
{
|
||||
DynamicRibbonWidget* gplist_widget = getWidget<DynamicRibbonWidget>("gplist");
|
||||
assert (gplist_widget != NULL);
|
||||
std::string selected = gplist_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
if (!selected.empty())
|
||||
setSelection (grand_prix_manager->getGrandPrix(selected));
|
||||
|
||||
if (name == "menu")
|
||||
if (name == "gplist")
|
||||
{
|
||||
DynamicRibbonWidget* gplist_widget = getWidget<DynamicRibbonWidget>("gplist");
|
||||
assert (gplist_widget != NULL);
|
||||
std::string selected = gplist_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
if (!selected.empty())
|
||||
{
|
||||
if (m_selection != NULL && selected == m_selection->getId() && m_selection->isEditable())
|
||||
showEditScreen(m_selection);
|
||||
else
|
||||
setSelection (grand_prix_manager->getGrandPrix(selected));
|
||||
}
|
||||
}
|
||||
else if (name == "menu")
|
||||
{
|
||||
RibbonWidget* menu = getWidget<RibbonWidget>("menu");
|
||||
assert(menu != NULL);
|
||||
@ -70,52 +91,40 @@ void GrandPrixEditorScreen::eventCallback(Widget* widget, const std::string& nam
|
||||
{
|
||||
new EnterGPNameDialog(this, 0.5f, 0.4f);
|
||||
}
|
||||
else if (m_action == "edit")
|
||||
else if (m_action == "edit" && m_selection != NULL)
|
||||
{
|
||||
if (m_selection->isEditable())
|
||||
{
|
||||
showEditScreen(m_selection);
|
||||
}
|
||||
else
|
||||
{
|
||||
new MessageDialog(
|
||||
_("You can't edit the '%s' grand prix.\nYou might want to copy it first",
|
||||
m_selection->getName().c_str()),
|
||||
MessageDialog::MESSAGE_DIALOG_OK, NULL, false);
|
||||
}
|
||||
showEditScreen(m_selection);
|
||||
}
|
||||
else if (m_action == "remove")
|
||||
else if (m_action == "remove" && m_selection != NULL)
|
||||
{
|
||||
if (m_selection->isEditable())
|
||||
{
|
||||
new MessageDialog(
|
||||
_("Are you sure you want to remove '%s'?", m_selection->getName().c_str()),
|
||||
MessageDialog::MESSAGE_DIALOG_CONFIRM,
|
||||
this, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
new MessageDialog(
|
||||
_("You can't remove '%s'.", m_selection->getName().c_str()),
|
||||
MessageDialog::MESSAGE_DIALOG_OK, NULL, false);
|
||||
}
|
||||
new MessageDialog(
|
||||
_("Are you sure you want to remove '%s'?", m_selection->getName().c_str()),
|
||||
MessageDialog::MESSAGE_DIALOG_CONFIRM,
|
||||
this, false);
|
||||
}
|
||||
else if (m_action == "rename")
|
||||
else if (m_action == "rename" && m_selection != NULL)
|
||||
{
|
||||
if (m_selection->isEditable())
|
||||
{
|
||||
new EnterGPNameDialog(this, 0.5f, 0.4f);
|
||||
}
|
||||
else
|
||||
{
|
||||
new MessageDialog(
|
||||
_("You can't rename '%s'.", m_selection->getName().c_str()),
|
||||
MessageDialog::MESSAGE_DIALOG_OK, NULL, false);
|
||||
}
|
||||
new EnterGPNameDialog(this, 0.5f, 0.4f);
|
||||
}
|
||||
}
|
||||
else if (name == "gpgroups")
|
||||
{
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("gpgroups");
|
||||
assert(tabs != NULL);
|
||||
|
||||
enum GrandPrixData::GPGroupType group = (enum GrandPrixData::GPGroupType)atoi(
|
||||
tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str());
|
||||
if (m_gpgroup != group)
|
||||
{
|
||||
m_gpgroup = group;
|
||||
loadGPList();
|
||||
setSelection(NULL);
|
||||
}
|
||||
}
|
||||
else if (name == "back")
|
||||
{
|
||||
m_gpgroup = GrandPrixData::GP_NONE;
|
||||
setSelection(NULL);
|
||||
StateManager::get()->escapePressed();
|
||||
}
|
||||
}
|
||||
@ -123,27 +132,12 @@ void GrandPrixEditorScreen::eventCallback(Widget* widget, const std::string& nam
|
||||
// -----------------------------------------------------------------------------
|
||||
void GrandPrixEditorScreen::init()
|
||||
{
|
||||
if (grand_prix_manager->getNumberOfGrandPrix() > 0)
|
||||
{
|
||||
if (m_selection == NULL)
|
||||
{
|
||||
loadGPList();
|
||||
setSelection (grand_prix_manager->getGrandPrix(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string id = m_selection->getId();
|
||||
grand_prix_manager->reload();
|
||||
loadGPList();
|
||||
m_selection = grand_prix_manager->editGrandPrix(id);
|
||||
m_selection->reload();
|
||||
setSelection (m_selection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
loadGPList();
|
||||
}
|
||||
RibbonWidget* tabs = getWidget<RibbonWidget>("gpgroups");
|
||||
assert (tabs != NULL);
|
||||
|
||||
tabs->select (StringUtils::toString(m_gpgroup), PLAYER_ID_GAME_MASTER);
|
||||
loadGPList();
|
||||
setSelection(m_selection);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -153,11 +147,25 @@ void GrandPrixEditorScreen::setSelection (const GrandPrixData* gpdata)
|
||||
assert(gpname_widget != NULL);
|
||||
DynamicRibbonWidget* gplist_widget = getWidget<DynamicRibbonWidget>("gplist");
|
||||
assert (gplist_widget != NULL);
|
||||
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
|
||||
assert(tracks_widget != NULL);
|
||||
|
||||
m_selection = grand_prix_manager->editGrandPrix(gpdata->getId());
|
||||
gpname_widget->setText (gpdata->getName(), true);
|
||||
gplist_widget->setSelection(m_selection->getId(), PLAYER_ID_GAME_MASTER, true);
|
||||
loadTrackList (gpdata->getId());
|
||||
if (gpdata == NULL)
|
||||
{
|
||||
m_selection = NULL;
|
||||
gpname_widget->setText (L"Please select a Grand Prix", true);
|
||||
tracks_widget->clearItems();
|
||||
tracks_widget->updateItemDisplay();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_selection = grand_prix_manager->editGrandPrix(gpdata->getId());
|
||||
gpname_widget->setText (gpdata->getName(), true);
|
||||
gplist_widget->setSelection(m_selection->getId(), PLAYER_ID_GAME_MASTER, true);
|
||||
loadTrackList (gpdata->getId());
|
||||
}
|
||||
|
||||
enableButtons();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -219,9 +227,16 @@ void GrandPrixEditorScreen::loadGPList()
|
||||
Track* track = track_manager->getTrack(tracks[t]);
|
||||
sshot_files.push_back(track->getScreenshotFile());
|
||||
}
|
||||
if (sshot_files.empty())
|
||||
sshot_files.push_back(file_manager->getAsset(FileManager::GUI,"main_help.png"));
|
||||
|
||||
gplist_widget->addAnimatedItem(translations->fribidize(gp->getName()), gp->getId(),
|
||||
sshot_files, 2.0f, 0, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
|
||||
if (m_gpgroup == GrandPrixData::GP_NONE || m_gpgroup == gp->getGroup())
|
||||
{
|
||||
gplist_widget->addAnimatedItem(
|
||||
translations->fribidize(gp->getName()),
|
||||
gp->getId(), sshot_files, 2.0f, 0,
|
||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
|
||||
}
|
||||
}
|
||||
|
||||
gplist_widget->updateItemDisplay();
|
||||
@ -236,14 +251,45 @@ void GrandPrixEditorScreen::showEditScreen(GrandPrixData* gp)
|
||||
StateManager::get()->pushScreen(edit);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void GrandPrixEditorScreen::enableButtons()
|
||||
{
|
||||
IconButtonWidget* copy_button = getWidget<IconButtonWidget>("copy");
|
||||
IconButtonWidget* edit_button = getWidget<IconButtonWidget>("edit");
|
||||
IconButtonWidget* remove_button = getWidget<IconButtonWidget>("remove");
|
||||
IconButtonWidget* rename_button = getWidget<IconButtonWidget>("rename");
|
||||
assert(copy_button != NULL);
|
||||
assert(edit_button != NULL);
|
||||
assert(remove_button != NULL);
|
||||
assert(rename_button != NULL);
|
||||
|
||||
if (m_selection != NULL && m_selection->getNumberOfTracks() > 0)
|
||||
copy_button->setActivated();
|
||||
else
|
||||
copy_button->setDeactivated();
|
||||
|
||||
if (m_selection != NULL && m_selection->isEditable())
|
||||
{
|
||||
edit_button->setActivated();
|
||||
remove_button->setActivated();
|
||||
rename_button->setActivated();
|
||||
}
|
||||
else
|
||||
{
|
||||
edit_button->setDeactivated();
|
||||
remove_button->setDeactivated();
|
||||
rename_button->setDeactivated();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void GrandPrixEditorScreen::onNewGPWithName(const stringw& newName)
|
||||
{
|
||||
if (m_action == "copy")
|
||||
if (m_action == "copy" && m_selection != NULL)
|
||||
{
|
||||
setSelection(grand_prix_manager->copy(m_selection->getId(), newName));
|
||||
}
|
||||
else if (m_action == "rename")
|
||||
else if (m_action == "rename" && m_selection != NULL)
|
||||
{
|
||||
m_selection->setName(newName);
|
||||
m_selection->writeToFile();
|
||||
@ -254,14 +300,14 @@ void GrandPrixEditorScreen::onNewGPWithName(const stringw& newName)
|
||||
}
|
||||
|
||||
loadGPList();
|
||||
if (m_action != "rename")
|
||||
if (m_action != "rename" && m_selection != NULL)
|
||||
showEditScreen(m_selection);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void GrandPrixEditorScreen::onConfirm()
|
||||
{
|
||||
if (m_action == "remove")
|
||||
if (m_action == "remove" && m_selection != NULL)
|
||||
{
|
||||
grand_prix_manager->remove(m_selection->getId());
|
||||
loadGPList();
|
||||
@ -270,3 +316,16 @@ void GrandPrixEditorScreen::onConfirm()
|
||||
}
|
||||
ModalDialog::dismiss();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
const wchar_t* GrandPrixEditorScreen::getGroupName(enum GrandPrixData::GPGroupType group)
|
||||
{
|
||||
switch (group)
|
||||
{
|
||||
case GrandPrixData::GP_NONE: return _("All");
|
||||
case GrandPrixData::GP_STANDARD: return _("Standard");
|
||||
case GrandPrixData::GP_USER_DEFINED: return _("User defined");
|
||||
case GrandPrixData::GP_ADDONS: return _("Add-Ons");
|
||||
default: return L"???";
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define HEADER_GRAND_PRIX_EDITOR_SCREEN_HPP
|
||||
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "race/grand_prix_data.hpp"
|
||||
#include "states_screens/dialogs/enter_gp_name_dialog.hpp"
|
||||
#include "states_screens/dialogs/message_dialog.hpp"
|
||||
|
||||
@ -45,15 +46,22 @@ class GrandPrixEditorScreen :
|
||||
void loadGPList();
|
||||
void loadTrackList(const std::string& gpname);
|
||||
void showEditScreen(GrandPrixData* gp);
|
||||
void enableButtons();
|
||||
|
||||
void onNewGPWithName(const irr::core::stringw& newName);
|
||||
void onConfirm();
|
||||
|
||||
GrandPrixData* m_selection;
|
||||
std::string m_action;
|
||||
static const wchar_t* getGroupName(enum GrandPrixData::GPGroupType group);
|
||||
|
||||
GrandPrixData* m_selection;
|
||||
std::string m_action;
|
||||
enum GrandPrixData::GPGroupType m_gpgroup;
|
||||
|
||||
public:
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void beforeAddingWidget() OVERRIDE;
|
||||
|
||||
/** \brief implement callback from parent class GUIEngine::Screen */
|
||||
virtual void loadedFromFile() OVERRIDE;
|
||||
|
||||
|
@ -185,7 +185,7 @@ void GrandPrixLose::setKarts(std::vector<std::string> ident_arg)
|
||||
m_kart_y = KART_Y;
|
||||
m_kart_z = KART_Z;
|
||||
|
||||
const int count = ident_arg.size();
|
||||
const int count = (int)ident_arg.size();
|
||||
for (int n=0; n<count; n++)
|
||||
{
|
||||
const KartProperties* kart = kart_properties_manager->getKart(ident_arg[n]);
|
||||
|
@ -964,7 +964,7 @@ void KartSelectionScreen::beforeAddingWidget()
|
||||
|
||||
const std::vector<std::string>& groups =
|
||||
kart_properties_manager->getAllGroups();
|
||||
const int group_amount = groups.size();
|
||||
const int group_amount = (int)groups.size();
|
||||
|
||||
// add all group first
|
||||
if (group_amount > 1)
|
||||
@ -1446,8 +1446,8 @@ void KartSelectionScreen::playerConfirm(const int playerID)
|
||||
|
||||
// Check if we have enough karts for everybody. If there are more players
|
||||
// than karts then just allow duplicates
|
||||
const int availableKartCount = w->getItems().size();
|
||||
const bool willNeedDuplicates = (amount > availableKartCount);
|
||||
const int available_kart_count = (int) w->getItems().size();
|
||||
const bool will_need_duplicates = (amount > available_kart_count);
|
||||
|
||||
// make sure no other player selected the same identity or kart
|
||||
for (int n=0; n<amount; n++)
|
||||
@ -1464,7 +1464,7 @@ void KartSelectionScreen::playerConfirm(const int playerID)
|
||||
m_kart_widgets[playerID]);
|
||||
|
||||
if (player_ready && (ident_conflict || kart_conflict) &&
|
||||
!willNeedDuplicates)
|
||||
!will_need_duplicates)
|
||||
{
|
||||
if (UserConfigParams::logGUI())
|
||||
Log::warn("[KartSelectionScreen]", "You can't select this identity "
|
||||
@ -1667,7 +1667,7 @@ void KartSelectionScreen::eventCallback(Widget* widget,
|
||||
" lost their selection when switching tabs!!!",n);
|
||||
|
||||
// Select a random kart in this case
|
||||
const int count = w->getItems().size();
|
||||
const int count = (int) w->getItems().size();
|
||||
if (count > 0)
|
||||
{
|
||||
// FIXME: two players may be given the same kart by
|
||||
@ -1808,7 +1808,7 @@ void KartSelectionScreen::allPlayersDone()
|
||||
std::vector<ItemDescription> items = w->getItems();
|
||||
|
||||
// remove the 'random' item itself
|
||||
const int item_count = items.size();
|
||||
const int item_count = (int) items.size();
|
||||
for (int n=0; n<item_count; n++)
|
||||
{
|
||||
if (items[n].m_code_name == RANDOM_KART_ID)
|
||||
|
@ -92,15 +92,15 @@ void OptionsScreenUI::loadedFromFile()
|
||||
return;
|
||||
}
|
||||
|
||||
const int skinCount = m_skins.size();
|
||||
for (int n=0; n<skinCount; n++)
|
||||
const int skin_count = (int)m_skins.size();
|
||||
for (int n=0; n<skin_count; n++)
|
||||
{
|
||||
const std::string skinFileName = StringUtils::getBasename(m_skins[n]);
|
||||
const std::string skinName = StringUtils::removeExtension( skinFileName );
|
||||
skinSelector->addLabel( core::stringw(skinName.c_str()) );
|
||||
}
|
||||
skinSelector->m_properties[GUIEngine::PROP_MIN_VALUE] = "0";
|
||||
skinSelector->m_properties[GUIEngine::PROP_MAX_VALUE] = StringUtils::toString(skinCount-1);
|
||||
skinSelector->m_properties[GUIEngine::PROP_MAX_VALUE] = StringUtils::toString(skin_count-1);
|
||||
|
||||
|
||||
} // loadedFromFile
|
||||
@ -137,7 +137,7 @@ void OptionsScreenUI::init()
|
||||
|
||||
// --- select the right skin in the spinner
|
||||
bool currSkinFound = false;
|
||||
const int skinCount = m_skins.size();
|
||||
const int skinCount = (int) m_skins.size();
|
||||
for (int n=0; n<skinCount; n++)
|
||||
{
|
||||
const std::string skinFileName = StringUtils::getBasename(m_skins[n]);
|
||||
@ -164,7 +164,7 @@ void OptionsScreenUI::init()
|
||||
list_widget->addItem("system", _("System Language"));
|
||||
|
||||
const std::vector<std::string>* lang_list = translations->getLanguageList();
|
||||
const int amount = lang_list->size();
|
||||
const int amount = (int)lang_list->size();
|
||||
|
||||
// The names need to be sorted alphabetically. Store the 2-letter
|
||||
// language names in a mapping, to be able to get them from the
|
||||
|
@ -175,14 +175,17 @@ void OptionsScreenVideo::init()
|
||||
|
||||
const std::vector<IrrDriver::VideoMode>& modes =
|
||||
irr_driver->getVideoModes();
|
||||
const int amount = modes.size();
|
||||
const int amount = (int)modes.size();
|
||||
|
||||
bool found_config_res = false;
|
||||
|
||||
// for some odd reason, irrlicht sometimes fails to report the good
|
||||
// old standard resolutions
|
||||
// those are always useful for windowed mode
|
||||
// allow 800x600 only for debug mode
|
||||
#ifdef DEBUG
|
||||
bool found_800_600 = false;
|
||||
#endif
|
||||
bool found_1024_640 = false;
|
||||
bool found_1024_768 = false;
|
||||
|
||||
@ -200,7 +203,11 @@ void OptionsScreenVideo::init()
|
||||
|
||||
if (w == 800 && h == 600)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
found_800_600 = true;
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
else if (w == 1024 && h == 640)
|
||||
{
|
||||
@ -246,7 +253,9 @@ void OptionsScreenVideo::init()
|
||||
|
||||
if (w == 800 && h == 600)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
found_800_600 = true;
|
||||
#endif
|
||||
}
|
||||
else if (w == 1024 && h == 640)
|
||||
{
|
||||
@ -284,10 +293,12 @@ void OptionsScreenVideo::init()
|
||||
#undef ABOUT_EQUAL
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!found_800_600)
|
||||
{
|
||||
res->addItem(L"800\u00D7600", "800x600", "/gui/screen43.png");
|
||||
}
|
||||
#endif
|
||||
if (!found_1024_640)
|
||||
{
|
||||
res->addItem(L"1024\u00D7640", "1024x640", "/gui/screen1610.png");
|
||||
|
@ -734,8 +734,6 @@ void RaceGUI::drawSpeedEnergyRank(const AbstractKart* kart,
|
||||
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::dimension2du bar_size = bar_texture->getOriginalSize();
|
||||
video::S3DVertex vertices[5];
|
||||
unsigned int count;
|
||||
|
||||
|
@ -821,7 +821,6 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
|
||||
|
||||
if (info.special_title.size() > 0)
|
||||
{
|
||||
static video::SColor color = video::SColor(255, 255, 0, 0);
|
||||
core::rect<s32> pos(x+ICON_PLAYER_WIDTH, y+5,
|
||||
x+ICON_PLAYER_WIDTH, y+5);
|
||||
core::stringw s(info.special_title.c_str());
|
||||
|
@ -158,7 +158,7 @@ void RaceResultGUI::enableAllButtons()
|
||||
|
||||
// If something was unlocked
|
||||
// -------------------------
|
||||
int n = PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges().size();
|
||||
int n = (int)PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges().size();
|
||||
if(n>0)
|
||||
{
|
||||
top->setText(n==1 ? _("You completed a challenge!")
|
||||
@ -227,7 +227,7 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
|
||||
// If something was unlocked, the 'continue' button was
|
||||
// actually used to display "Show unlocked feature(s)" text.
|
||||
// ---------------------------------------------------------
|
||||
int n = PlayerManager::getCurrentPlayer()
|
||||
int n = (int)PlayerManager::getCurrentPlayer()
|
||||
->getRecentlyCompletedChallenges().size();
|
||||
if(n>0)
|
||||
{
|
||||
@ -627,7 +627,7 @@ void RaceResultGUI::renderGlobal(float dt)
|
||||
|
||||
m_timer += dt;
|
||||
assert(World::getWorld()->getPhase()==WorldStatus::RESULT_DISPLAY_PHASE);
|
||||
unsigned int num_karts = m_all_row_infos.size();
|
||||
unsigned int num_karts = (unsigned int)m_all_row_infos.size();
|
||||
|
||||
// First: Update the finite state machine
|
||||
// ======================================
|
||||
|
@ -45,24 +45,6 @@ const int CONFIG_CODE_SOCCER = 5;
|
||||
using namespace GUIEngine;
|
||||
DEFINE_SCREEN_SINGLETON( RaceSetupScreen );
|
||||
|
||||
class GameModeRibbonListener : public DynamicRibbonHoverListener
|
||||
{
|
||||
RaceSetupScreen* m_parent;
|
||||
public:
|
||||
|
||||
GameModeRibbonListener(RaceSetupScreen* parent)
|
||||
{
|
||||
m_parent = parent;
|
||||
}
|
||||
|
||||
virtual void onSelectionChanged(DynamicRibbonWidget* theWidget, const std::string& selectionID,
|
||||
const irr::core::stringw& selectionText, const int playerID)
|
||||
{
|
||||
// game mode changed!!
|
||||
m_parent->onGameModeChanged();
|
||||
}
|
||||
}; // GameModeRibbonListener
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
RaceSetupScreen::RaceSetupScreen() : Screen("racesetup.stkgui")
|
||||
@ -192,21 +174,6 @@ void RaceSetupScreen::assignDifficulty()
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void RaceSetupScreen::onGameModeChanged()
|
||||
{
|
||||
DynamicRibbonWidget* w2 = getWidget<DynamicRibbonWidget>("gamemode");
|
||||
assert( w2 != NULL );
|
||||
|
||||
std::string gamemode_str = w2->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||
if (gamemode_str == "locked") return;
|
||||
|
||||
RaceManager::MinorRaceModeType gamemode =
|
||||
RaceManager::getModeIDFromInternalName(gamemode_str);
|
||||
|
||||
} // onGameModeChanged
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void RaceSetupScreen::init()
|
||||
{
|
||||
Screen::init();
|
||||
@ -314,10 +281,6 @@ void RaceSetupScreen::init()
|
||||
break;
|
||||
}
|
||||
|
||||
m_mode_listener = new GameModeRibbonListener(this);
|
||||
w2->registerHoverListener(m_mode_listener);
|
||||
|
||||
|
||||
if (PlayerManager::getCurrentPlayer()->isLocked("difficulty_best"))
|
||||
{
|
||||
RibbonWidget* w = getWidget<RibbonWidget>("difficulty");
|
||||
|
@ -22,8 +22,6 @@
|
||||
|
||||
namespace GUIEngine { class Widget; }
|
||||
|
||||
class GameModeRibbonListener;
|
||||
|
||||
/**
|
||||
* \brief Screen with race setup options (difficulty, game mode, etc...)
|
||||
* \ingroup states_screens
|
||||
@ -31,12 +29,9 @@ class GameModeRibbonListener;
|
||||
class RaceSetupScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<RaceSetupScreen>
|
||||
{
|
||||
friend class GUIEngine::ScreenSingleton<RaceSetupScreen>;
|
||||
friend class GameModeRibbonListener;
|
||||
|
||||
RaceSetupScreen();
|
||||
|
||||
GameModeRibbonListener* m_mode_listener;
|
||||
|
||||
void onGameModeChanged();
|
||||
|
||||
void assignDifficulty();
|
||||
|
@ -326,7 +326,6 @@ void TrackInfoScreen::eventCallback(Widget* widget, const std::string& name,
|
||||
}
|
||||
else if (name=="ai-spinner")
|
||||
{
|
||||
SpinnerWidget* w = dynamic_cast<SpinnerWidget*>(widget);
|
||||
const int num_ai = m_ai_kart_spinner->getValue();
|
||||
race_manager->setNumKarts( race_manager->getNumLocalPlayers() + num_ai );
|
||||
UserConfigParams::m_num_karts = race_manager->getNumLocalPlayers() + num_ai;
|
||||
|
@ -141,7 +141,7 @@ void TracksScreen::beforeAddingWidget()
|
||||
tabs->clearAllChildren();
|
||||
|
||||
const std::vector<std::string>& groups = track_manager->getAllTrackGroups();
|
||||
const int group_amount = groups.size();
|
||||
const int group_amount = (int)groups.size();
|
||||
|
||||
if (group_amount > 1)
|
||||
{
|
||||
@ -161,7 +161,7 @@ void TracksScreen::beforeAddingWidget()
|
||||
tabs->addTextChild( _(groups[n].c_str()), groups[n] );
|
||||
|
||||
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
|
||||
tracks_widget->setItemCountHint( track_manager->getNumberOfTracks()+1 );
|
||||
tracks_widget->setItemCountHint( (int)track_manager->getNumberOfTracks()+1 );
|
||||
} // beforeAddingWidget
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -185,6 +185,10 @@ void TracksScreen::init()
|
||||
const GrandPrixData* gp = grand_prix_manager->getGrandPrix(n);
|
||||
const std::vector<std::string> tracks = gp->getTrackNames(true);
|
||||
|
||||
//Skip epmpty GPs
|
||||
if (gp->getNumberOfTracks()==0)
|
||||
continue;
|
||||
|
||||
std::vector<std::string> screenshots;
|
||||
for (unsigned int t=0; t<tracks.size(); t++)
|
||||
{
|
||||
@ -252,7 +256,7 @@ void TracksScreen::buildTrackList()
|
||||
|
||||
const std::string& curr_group_name = tabs->getSelectionIDString(0);
|
||||
|
||||
const int track_amount = track_manager->getNumberOfTracks();
|
||||
const int track_amount = (int)track_manager->getNumberOfTracks();
|
||||
|
||||
// First build a list of all tracks to be displayed
|
||||
// (e.g. exclude arenas, ...)
|
||||
|
@ -207,7 +207,7 @@ next:
|
||||
if (pedantic)
|
||||
warning("leading whitespace before string");
|
||||
|
||||
get_string_line(out, i);
|
||||
get_string_line(out, (unsigned int) i);
|
||||
goto next;
|
||||
}
|
||||
else if (isspace(current_line[i]))
|
||||
@ -245,7 +245,7 @@ POParser::parse_header(const std::string& header)
|
||||
if (has_prefix(line, "Content-Type:"))
|
||||
{
|
||||
// from_charset = line.substr(len);
|
||||
unsigned int len = strlen("Content-Type: text/plain; charset=");
|
||||
unsigned int len = (unsigned int) strlen("Content-Type: text/plain; charset=");
|
||||
if (line.compare(0, len, "Content-Type: text/plain; charset=") == 0)
|
||||
{
|
||||
from_charset = line.substr(len);
|
||||
|
@ -56,6 +56,6 @@ public:
|
||||
Vec3 getHPR(float t) const;
|
||||
|
||||
/** Returns the number of points in this bezier curve. */
|
||||
unsigned int getNumPoints() const {return m_all_data.size(); }
|
||||
unsigned int getNumPoints() const {return (unsigned int) m_all_data.size(); }
|
||||
}; // BezierCurve
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user