Attached Files |
-
hwCursor.patch (36,598 bytes) 2008-05-10 16:27
Index: rts/build/scons/config.py
===================================================================
--- rts/build/scons/config.py (revision 5850)
+++ rts/build/scons/config.py (working copy)
@@ -301,6 +301,8 @@
d += [Dependency(['SDLmain'], [])]
else:
d += [Dependency(['openal', 'openal32'], ['AL/al.h'])]
+ d += [Dependency(['Xcursor'], ['X11/Xcursor/Xcursor.h'])]
+ d += [Dependency(['X11'], ['X11/X.h'])]
d += [Dependency(['vorbisfile'], ['vorbis/vorbisfile.h'])]
d += [Dependency(['vorbis'], [])]
Index: rts/build/scons/rts.py
===================================================================
--- rts/build/scons/rts.py (revision 5850)
+++ rts/build/scons/rts.py (working copy)
@@ -270,6 +270,8 @@
level = args['optimize']
if level == 'no' or level == 'false': level = '0'
elif level == 'yes' or level == 'true': level = '2'
+
+ env.AppendUnique(CCFLAGS=['-finline-functions','-funroll-loops'])
else:
if env['debug']: level = '0'
else: level = '2'
@@ -392,9 +394,11 @@
include_path += ['/usr/local/include', '/usr/X11R6/include', '/usr/X11R6/include/GL']
lib_path += ['/usr/local/lib', '/usr/X11R6/lib']
env.AppendUnique(CCFLAGS = ['-pthread'], CXXFLAGS = ['-pthread'])
+ env.AppendUnique(CCFLAGS = ['-lX11','-lXcursor'], CXXFLAGS = ['-lX11','-lXcursor'])
elif env['platform'] == 'linux':
include_path += ['/usr/include', '/usr/include/GL']
env.AppendUnique(CCFLAGS = ['-pthread'], CXXFLAGS = ['-pthread'], LINKFLAGS = ['-Wl,-E'])
+ env.AppendUnique(CCFLAGS = ['-lX11','-lXcursor'], CXXFLAGS = ['-lX11','-lXcursor'])
elif env['platform'] == 'darwin':
include_path += ['/usr/include', '/usr/local/include', '/opt/local/include', '/usr/X11R6/include']
lib_path += ['/opt/local/lib', '/usr/local/lib']
Index: rts/Game/UI/GuiHandler.cpp
===================================================================
--- rts/Game/UI/GuiHandler.cpp (revision 5850)
+++ rts/Game/UI/GuiHandler.cpp (working copy)
@@ -966,32 +966,30 @@
void CGuiHandler::SetCursorIcon() const
{
- mouse->cursorText = "";
+ string newCursor = "cursornormal";
mouse->cursorScale = 1.0f;
CInputReceiver* ir = NULL;
- if (!game->hideInterface) {
+ if (!game->hideInterface)
ir = GetReceiverAt(mouse->lastx, mouse->lasty);
- }
if ((ir != NULL) && (ir != minimap)) {
+ mouse->SetCursor(newCursor);
return;
}
- if (ir == minimap) {
+ if (ir == minimap)
mouse->cursorScale = minimap->CursorScale();
- }
- const bool useMinimap =
- (minimap->ProxyMode() || ((activeReceiver != this) && (ir == minimap)));
+ const bool useMinimap = (minimap->ProxyMode() || ((activeReceiver != this) && (ir == minimap)));
if ((inCommand >= 0) && (inCommand<commands.size())) {
const CommandDescription& cmdDesc = commands[inCommand];
if (!cmdDesc.mouseicon.empty()) {
- mouse->cursorText = cmdDesc.mouseicon;
+ newCursor=cmdDesc.mouseicon;
} else {
- mouse->cursorText = cmdDesc.name;
+ newCursor=cmdDesc.name;
}
if (useMinimap && (cmdDesc.id < 0)) {
@@ -1004,9 +1002,9 @@
// does not consider it when checking for position blocking
CFeature* feature;
if(!uh->TestUnitBuildSquare(bi, feature, gu->myAllyTeam)) {
- mouse->cursorText = "BuildBad";
+ newCursor="BuildBad";
} else {
- mouse->cursorText = "BuildGood";
+ newCursor="BuildGood";
}
}
}
@@ -1021,16 +1019,17 @@
if ((defcmd >= 0) && (defcmd < commands.size())) {
const CommandDescription& cmdDesc = commands[defcmd];
if (!cmdDesc.mouseicon.empty()) {
- mouse->cursorText = cmdDesc.mouseicon;
+ newCursor=cmdDesc.mouseicon;
} else {
- mouse->cursorText = cmdDesc.name;
+ newCursor=cmdDesc.name;
}
}
}
- if (gatherMode && (mouse->cursorText == "Move")) {
- mouse->cursorText = "GatherWait";
- }
+ if (gatherMode && (mouse->cursorText == "Move"))
+ newCursor = "GatherWait";
+
+ mouse->SetCursor(newCursor);
}
@@ -4014,11 +4013,6 @@
}
glEnd();
- if(sizeDiv!=0){
- char c[40];
- SNPRINTF(c, 40, "%d", (int)(frontLen / sizeDiv) );
- mouse->cursorTextRight=c;
- }
glEnable(GL_FOG);
}
Index: rts/Game/UI/HwMouseCursor.cpp
===================================================================
--- rts/Game/UI/HwMouseCursor.cpp (revision 0)
+++ rts/Game/UI/HwMouseCursor.cpp (revision 0)
@@ -0,0 +1,543 @@
+#include "StdAfx.h"
+#include "bitops.h"
+#include "CommandColors.h"
+#include "FileSystem/FileHandler.h"
+#include "FileSystem/SimpleParser.h"
+#include "LogOutput.h"
+#include "MouseCursor.h"
+#include "HwMouseCursor.h"
+#include "myMath.h"
+#include "Rendering/GL/myGL.h"
+#include "Rendering/Textures/Bitmap.h"
+#include "mmgr.h"
+#include <SDL_syswm.h>
+
+#ifdef WIN32
+ #include "windows.h"
+ #include "MouseInput.h"
+#elif defined(__APPLE__)
+ /*do nothing (duno how to create cursors on runtime on macs)*/
+#else
+ #include <X11/Xcursor/Xcursor.h>
+#endif
+
+//int savedcount=0;
+
+//////////////////////////////////////////////////////////////////////
+// Platform dependent classes
+//////////////////////////////////////////////////////////////////////
+
+#ifdef __APPLE__
+// no hardware cursor support for mac's
+class CHwDummyCursor : public IHwCursor {
+ public:
+ void PushImage(int xsize, int ysize, void* mem){};
+ void SetDelay(float delay){};
+ void PushFrame(int index, float delay){};
+ void Finish(){};
+
+ bool needsYFlip() {return false;};
+
+ bool IsValid(){return false;};
+ void Bind(){};
+};
+#elif defined(WIN32)
+class CHwWinCursor : public IHwCursor {
+ public:
+ CHwWinCursor(void);
+ ~CHwWinCursor(void);
+
+ void PushImage(int xsize, int ysize, void* mem);
+ void SetDelay(float delay);
+ void PushFrame(int index, float delay);
+ void Finish();
+
+ bool needsYFlip() {return true;};
+
+ void Bind();
+
+ bool IsValid() {return (cursor!=NULL);};
+ protected:
+ HCURSOR cursor;
+
+ struct CursorDirectoryHeader {
+ byte xsize,ysize,ncolors,reserved1;
+ short hotx,hoty;
+ DWORD size,offset;
+ };
+
+ struct CursorInfoHeader {
+ DWORD size,width,height;
+ WORD planes, bpp;
+ DWORD res1,res2,res3,res4,res5,res6;
+ };
+
+ struct AnihStructure {
+ DWORD size,images,frames,width,height,bpp,planes,rate,flags;
+ };
+
+ protected:
+ struct ImageData {
+ unsigned char* data;
+ int width,height;
+ };
+
+ void buildIco(unsigned char* dst, ImageData &image);
+ void resizeImage(ImageData *image, int new_x, int new_y);
+
+ int xmaxsize, ymaxsize;
+ short hotx, hoty;
+
+ byte image_count;
+
+ std::vector<ImageData> icons;
+ std::vector<byte> frames;
+ std::vector<int> framerates;
+};
+#else
+class CHwX11Cursor : public IHwCursor {
+ public:
+ CHwX11Cursor(void);
+ ~CHwX11Cursor(void);
+
+ void PushImage(int xsize, int ysize, void* mem);
+ void SetDelay(float delay);
+ void PushFrame(int index, float delay);
+ void Finish();
+
+ bool needsYFlip() {return false;};
+
+ bool IsValid() {return (cursor!=0);};
+ void Bind();
+ protected:
+ int xmaxsize, ymaxsize;
+
+ void resizeImage(XcursorImage*& image, const int new_x, const int new_y);
+
+ Cursor cursor;
+ std::vector<XcursorImage*> cimages;
+};
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// GetHwCursor()
+//////////////////////////////////////////////////////////////////////
+
+IHwCursor* GetNewHwCursor()
+{
+#ifdef WIN32
+ return SAFE_NEW CHwWinCursor();
+#elif defined(__APPLE__)
+ return SAFE_NEW CHwDummyCursor();
+#else
+ return SAFE_NEW CHwX11Cursor();
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Implementation
+//////////////////////////////////////////////////////////////////////
+
+
+#ifdef __APPLE__
+ // no hardware cursor support for mac's
+#elif defined(WIN32)
+
+void CHwWinCursor::PushImage(int xsize, int ysize, void* mem)
+{
+ xmaxsize=std::max(xmaxsize,xsize);
+ ymaxsize=std::max(ymaxsize,ysize);
+
+ ImageData icon;
+ icon.data = new unsigned char[xsize*ysize*4];
+ icon.width = xsize;
+ icon.height = ysize;
+ memcpy(icon.data,mem,xsize*ysize*4);
+
+ icons.push_back(icon);
+
+ frames.push_back(image_count);
+ framerates.push_back(std::max((int)(defFrameLength*60.0f),1));
+ image_count++;
+}
+
+void CHwWinCursor::SetDelay(float delay)
+{
+ int &last_item = framerates.back();
+ last_item = std::max((int)(delay*60.0f),1);
+}
+
+void CHwWinCursor::PushFrame(int index, float delay)
+{
+ if (index>=image_count)
+ return;
+
+ frames.push_back((byte)index);
+ framerates.push_back(std::max((int)(delay*60.0f),1));
+}
+
+void CHwWinCursor::resizeImage(ImageData *image, int new_x, int new_y)
+{
+ if (image->width==new_x && image->height==new_y)
+ return;
+
+ unsigned char* newdata = new unsigned char[new_x*new_y*4];
+ memset(newdata, 0, new_x*new_y*4);
+
+ for (int y = 0; y < image->height; ++y)
+ for (int x = 0; x < image->width; ++x)
+ for (int v = 0; v < 4; ++v)
+ newdata[((y + (new_y-image->height))*new_x+x)*4+v] = image->data[(y*image->width+x)*4+v];
+
+ delete[] image->data;
+
+ image->data = newdata;
+
+ image->width = new_x;
+ image->height = new_y;
+}
+
+void CHwWinCursor::buildIco(unsigned char* dst, ImageData &image)
+{
+ const int xsize = image.width;
+ const int ysize = image.height;
+
+ //small header needed in .ani
+ strcpy((char*)dst,"icon");
+ dst += 4;
+ DWORD* cursize = (DWORD*)&dst[0];
+ cursize[0] = 3*sizeof(WORD)+sizeof(CursorDirectoryHeader)+sizeof(CursorInfoHeader)+xsize*ysize*4+xsize*ysize/8;
+ dst += 4;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ // the following code writes a full working .cur file in the memory (in a .ani container)
+
+ //file header
+ WORD* header = (WORD*)&dst[0]; int i=0;
+ header[i++] = 0; //reserved
+ header[i++] = 2; //is cursor
+ header[i++] = 1; //number of cursor in this file
+ dst += 3*sizeof(WORD);
+
+ CursorDirectoryHeader curHeader;
+ memset(&curHeader,0,sizeof(CursorDirectoryHeader));
+ curHeader.xsize = (byte)xsize; //width
+ curHeader.ysize = (byte)ysize; //height
+ curHeader.hotx = hotx;
+ curHeader.hoty = hoty;
+ curHeader.size = 40+xsize*ysize*4+xsize*ysize/8; //size of the bmp data (infoheader 40byte, 32bit color, 1bit mask)
+ curHeader.offset = 22; //offset, where the infoHeader starts
+ memcpy(dst, &curHeader, sizeof(CursorDirectoryHeader));
+ dst += sizeof(CursorDirectoryHeader);
+
+ CursorInfoHeader infoHeader;
+ memset(&infoHeader,0,sizeof(CursorInfoHeader));
+ infoHeader.size = 40; //size of the infoHeader
+ infoHeader.width = xsize; //cursor width
+ infoHeader.height = ysize*2; //cursor height + mask height
+ infoHeader.planes = 1; //number of color planes
+ infoHeader.bpp = 32; //bits per pixel
+ memcpy(dst, &infoHeader, sizeof(CursorInfoHeader));
+ dst += sizeof(CursorInfoHeader);
+
+ //copy colormap
+ unsigned char* src = image.data;
+ unsigned char* end = src+xsize*ysize*4;
+ do{
+ if (src[3]==0) {
+ dst[0] = dst[1] = dst[2] = dst[3] = 0;
+ }else{
+ dst[0]=src[2]; // B
+ dst[1]=src[1]; // G
+ dst[2]=src[0]; // R
+ dst[3]=src[3]; // A
+ }
+ dst+=4;
+ src+=4;
+ }while(src<end);
+
+ //create mask
+ src -= xsize*ysize*4;
+ int b = 0;
+ do{
+ dst[0] = 0x00;
+ for (b=0; b<8; b++) {
+ if (src[3]==0) //alpha greater zero?
+ dst[0] |= 128>>b;
+ src+=4;
+ }
+ dst++;
+ }while(src<end);
+
+/* char fname[256];
+ SNPRINTF(fname, sizeof(fname), "mycursor%d.cur", ++savedcount);
+ FILE * pFile = fopen( fname , "wb" );
+ fwrite(curs.back(), 1 , curmem-curs.back(), pFile );
+ fclose(pFile); */
+}
+
+void CHwWinCursor::Finish()
+{
+ if (frames.size()<1)
+ return;
+
+ hotx = (hotSpot==CMouseCursor::TopLeft) ? 0 : (short)xmaxsize/2;
+ hoty = (hotSpot==CMouseCursor::TopLeft) ? 0 : (short)ymaxsize/2;
+
+ //note: windows only except 16x16,32x32,64x64,etc. (and some more not 2^n ones)
+ int squaresize = next_power_of_2( std::max(xmaxsize,ymaxsize) );
+
+ //resize images
+ for (std::vector<ImageData>::iterator it=icons.begin(); it<icons.end(); it++)
+ resizeImage(&*it,squaresize,squaresize);
+
+ const int riffsize = 32 + sizeof(AnihStructure) + (frames.size()+2) * 2 * sizeof(DWORD);
+ const int iconssize = icons.size() * (2*sizeof(DWORD) + 3*sizeof(WORD) +
+ sizeof(CursorDirectoryHeader) +
+ sizeof(CursorInfoHeader) +
+ squaresize*squaresize*4 +
+ squaresize*squaresize/8);
+ const int totalsize = riffsize + iconssize;
+ unsigned char* mem = SAFE_NEW unsigned char[ totalsize ];
+
+ unsigned char* curmem = mem;
+ DWORD* dwmem;
+
+ //write RIFF header
+ strcpy((char*)curmem,"RIFF"); curmem+=4;
+ dwmem = (DWORD*)&curmem[0];
+ dwmem[0] = totalsize-8; curmem+=4; //filesize
+ strcpy((char*)curmem,"ACON"); curmem+=4;
+
+ //Anih header
+ strcpy((char*)curmem,"anih");
+ curmem += 4;
+ curmem[0] = 36;
+ curmem[1] = curmem[2] = curmem[3] = 0;
+ curmem += 4;
+
+ AnihStructure anih;
+ memset(&anih,0,sizeof(AnihStructure));
+ anih.size = 36; //anih structure size
+ anih.images = image_count; //number of images
+ anih.frames = framerates.size(); //number of frames
+ anih.flags = 0x3L; //using seq structure and .cur format for saving bmp data
+ memcpy(curmem, &anih, sizeof(AnihStructure));
+ curmem += sizeof(AnihStructure);
+
+ //LIST + icons
+ strcpy((char*)curmem,"LIST"); curmem+=4;
+ dwmem = (DWORD*)&curmem[0];
+ dwmem[0] = iconssize+4; curmem+=4;
+ strcpy((char*)curmem,"fram"); curmem+=4;
+
+ for (std::vector<ImageData>::iterator it=icons.begin(); it<icons.end(); it++) {
+ buildIco(curmem,*it);
+ curmem += 2*sizeof(DWORD) + 3*sizeof(WORD)+sizeof(CursorDirectoryHeader)+sizeof(CursorInfoHeader)+squaresize*squaresize*4+squaresize*squaresize/8;
+ }
+
+ //SEQ header
+ strcpy((char*)curmem,"seq ");
+ curmem += 4;
+ DWORD* seq = (DWORD*)&curmem[0];
+ seq[0] = frames.size()*sizeof(DWORD);
+ seq++;
+ for (int i=0; i<frames.size(); i++)
+ seq[i] = frames.at(i);
+ curmem += (frames.size()+1)*sizeof(DWORD);
+
+ //RATE header
+ strcpy((char*)curmem,"rate");
+ curmem += 4;
+ DWORD* rate = (DWORD*)&curmem[0];
+ rate[0] = framerates.size()*sizeof(DWORD);
+ rate++;
+ for (int i=0; i<framerates.size(); i++)
+ rate[i] = framerates.at(i);
+ curmem += (framerates.size()+1)*sizeof(DWORD);
+
+ /*char fname[256];
+ SNPRINTF(fname, sizeof(fname), "cursors/mycursor%d.ani", ++savedcount);
+ FILE * pFile = fopen( fname , "wb" );
+ fwrite(mem , 1 , curmem-mem, pFile );
+ fclose(pFile);*/
+
+ cursor = (HCURSOR)CreateIconFromResourceEx((PBYTE)mem,totalsize,FALSE,0x00030000,squaresize,squaresize,0);
+
+ delete[] mem;
+ for (std::vector<ImageData>::iterator it=icons.begin(); it<icons.end(); it++)
+ delete[] (*it).data;
+ icons.clear();
+
+ //if (cursor==NULL) logOutput.Print("hw cursor failed: x%d y%d",squaresize,squaresize);
+}
+
+void CHwWinCursor::Bind()
+{
+ /*SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+ if (!SDL_GetWMInfo(&info)) {
+ logOutput.Print("SDL error: can't get window handle");
+ return;
+ }
+ SetClassLong(info.window,GCL_HCURSOR,(LONG)cursor);*/ //SDL doesn't let us use it :<
+
+ SetCursor(cursor);
+ mouseInput->SetWMMouseCursor(cursor);
+}
+
+CHwWinCursor::CHwWinCursor(void)
+{
+ cursor = NULL;
+ hotSpot= CMouseCursor::Center;
+ image_count = 0;
+ xmaxsize = ymaxsize = 0;
+}
+
+CHwWinCursor::~CHwWinCursor(void)
+{
+ if (cursor!=NULL)
+ DestroyCursor(cursor);
+
+ for (std::vector<ImageData>::iterator it=icons.begin(); it<icons.end(); it++)
+ delete[] (*it).data;
+ icons.clear();
+}
+
+#else
+
+void CHwX11Cursor::resizeImage(XcursorImage*& image, const int new_x, const int new_y)
+{
+ if (image->width==new_x && image->height==new_y)
+ return;
+
+ const int old_x = image->width;
+ const int old_y = image->height;
+
+ XcursorImage* new_image = XcursorImageCreate(new_x, new_y);
+ new_image->delay = image->delay;
+
+ unsigned char* src = (unsigned char*)image->pixels;
+ unsigned char* dst = (unsigned char*)new_image->pixels;
+ memset(dst, 0, new_x*new_y*4);
+
+ for (int y = 0; y < old_y; ++y)
+ for (int x = 0; x < old_x; ++x)
+ for (int v = 0; v < 4; ++v)
+ dst[(y*new_x+x)*4+v] = src[(y*old_x+x)*4+v];
+
+ XcursorImageDestroy(image);
+ image = new_image;
+}
+
+void CHwX11Cursor::PushImage(int xsize, int ysize, void* mem)
+{
+ xmaxsize=std::max(xmaxsize,xsize);
+ ymaxsize=std::max(ymaxsize,ysize);
+
+ XcursorImage* image = XcursorImageCreate(xsize,ysize);
+ image->delay = (XcursorUInt)(defFrameLength*1000.0f);
+ char* dst=(char*)image->pixels;
+ char* src=(char*)mem;
+ char* end=src+xsize*ysize*4;
+ do{
+ dst[0]=src[2]; // B
+ dst[1]=src[1]; // G
+ dst[2]=src[0]; // R
+ dst[3]=src[3]; // A
+ dst+=4;
+ src+=4;
+ }while(src<end);
+
+ cimages.push_back(image);
+}
+
+void CHwX11Cursor::SetDelay(float delay)
+{
+ cimages.back()->delay = (XcursorUInt)(delay*1000.0f); //in millseconds
+}
+
+void CHwX11Cursor::PushFrame(int index, float delay)
+{
+ if (index>=cimages.size())
+ return;
+
+ if (cimages[index]->delay!=delay) {
+ // make a copy of the existing one
+ XcursorImage* ci = cimages[index];
+ PushImage( ci->width, ci->height, ci->pixels );
+ SetDelay(delay);
+ }else{
+ cimages.push_back( cimages[index] );
+ }
+}
+
+void CHwX11Cursor::Finish()
+{
+ if (cimages.size()<1)
+ return;
+
+ //resize images
+ for (std::vector<XcursorImage*>::iterator it=cimages.begin(); it<cimages.end(); it++)
+ resizeImage(*it,xmaxsize,ymaxsize);
+
+ XcursorImages *cis = XcursorImagesCreate(cimages.size());
+ cis->nimage = cimages.size();
+ for (int i=0; i < cimages.size(); i++ ) {
+ XcursorImage* ci = cimages[i];
+ ci->xhot = (hotSpot==CMouseCursor::TopLeft) ? 0 : ci->width/2;
+ ci->yhot = (hotSpot==CMouseCursor::TopLeft) ? 0 : ci->height/2;
+ cis->images[i] = ci;
+ }
+
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+ if (!SDL_GetWMInfo(&info)) {
+ XcursorImagesDestroy(cis);
+ cimages.clear();
+ logOutput.Print("SDL error: can't get X11 window info");
+ return;
+ }
+
+ cursor = XcursorImagesLoadCursor(info.info.x11.display,cis);
+ XcursorImagesDestroy(cis);
+ cimages.clear();
+}
+
+void CHwX11Cursor::Bind()
+{
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+ if (!SDL_GetWMInfo(&info)) {
+ logOutput.Print("SDL error: can't get X11 window info");
+ return;
+ }
+ XDefineCursor(info.info.x11.display,info.info.x11.window,cursor);
+}
+
+CHwX11Cursor::CHwX11Cursor(void)
+{
+ cursor = 0;
+ hotSpot=CMouseCursor::Center;
+ xmaxsize = ymaxsize = 0;
+}
+
+CHwX11Cursor::~CHwX11Cursor(void)
+{
+ for (std::vector<XcursorImage*>::iterator it=cimages.begin() ; it < cimages.end(); it++ )
+ XcursorImageDestroy(*it);
+ cimages.clear();
+
+ if (cursor!=0) {
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+ if (!SDL_GetWMInfo(&info)) {
+ logOutput.Print("SDL error: can't get X11 window info");
+ return;
+ }
+ XFreeCursor(info.info.x11.display,cursor);
+ }
+}
+
+#endif
Index: rts/Game/UI/HwMouseCursor.h
===================================================================
--- rts/Game/UI/HwMouseCursor.h (revision 0)
+++ rts/Game/UI/HwMouseCursor.h (revision 0)
@@ -0,0 +1,27 @@
+#ifndef HWMOUSECURSOR_H
+#define HWMOUSECURSOR_H
+
+#include <string>
+#include <vector>
+#include "MouseCursor.h"
+
+class CMouseCursor;
+
+class IHwCursor {
+ public:
+ virtual void PushImage(int xsize, int ysize, void* mem) {}
+ virtual void SetDelay(float delay) {}
+ virtual void PushFrame(int index, float delay) {}
+ virtual void Finish() {}
+
+ virtual bool needsYFlip() {} //windows needs flipped Y axis
+
+ virtual bool IsValid() {}
+ virtual void Bind() {}
+
+ CMouseCursor::HotSpot hotSpot;
+};
+
+IHwCursor* GetNewHwCursor();
+
+#endif /* HWMOUSECURSOR_H */
Index: rts/Game/UI/MouseCursor.cpp
===================================================================
--- rts/Game/UI/MouseCursor.cpp (revision 5850)
+++ rts/Game/UI/MouseCursor.cpp (working copy)
@@ -5,16 +5,16 @@
#include "FileSystem/SimpleParser.h"
#include "LogOutput.h"
#include "MouseCursor.h"
+#include "HwMouseCursor.h"
#include "myMath.h"
#include "Rendering/GL/myGL.h"
#include "Rendering/Textures/Bitmap.h"
#include "mmgr.h"
+//////////////////////////////////////////////////////////////////////
+// CMouseCursor Class
+//////////////////////////////////////////////////////////////////////
-static const float minFrameLength = 0.010f; // seconds
-static const float defFrameLength = 0.100f; // seconds
-
-
CMouseCursor* CMouseCursor::New(const string &name, HotSpot hs)
{
CMouseCursor* c = SAFE_NEW CMouseCursor(name, hs);
@@ -25,20 +25,21 @@
return c;
}
-
-//Would be nice if these were read from a gaf-file instead.
CMouseCursor::CMouseCursor(const string &name, HotSpot hs)
{
+ hwCursor = GetNewHwCursor();
+ hwCursor->hotSpot = hs;
hotSpot = hs;
- if (!BuildFromSpecFile(name)) {
+ if (!BuildFromSpecFile(name))
BuildFromFileNames(name, 123456);
- }
- if (frames.size() <= 0) {
+ if (frames.size() <= 0)
return;
- }
+ animated = (frames.size() > 1);
+ hwValid = hwCursor->IsValid();
+
animTime = 0.0f;
animPeriod = 0.0f;
currentFrame = 0;
@@ -66,10 +67,11 @@
CMouseCursor::~CMouseCursor(void)
{
+ delete hwCursor;
+
std::vector<ImageData>::iterator it;
- for (it = images.begin(); it != images.end(); ++it) {
+ for (it = images.begin(); it != images.end(); ++it)
glDeleteTextures(1, &it->texture);
- }
}
@@ -100,10 +102,12 @@
if (iit != imageIndexMap.end()) {
FrameData frame(images[iit->second], length);
frames.push_back(frame);
+ hwCursor->PushFrame(iit->second,length);
}
else {
ImageData image;
if (LoadCursorImage(imageName, image)) {
+ hwCursor->SetDelay(length);
imageIndexMap[imageName] = images.size();
images.push_back(image);
FrameData frame(image, length);
@@ -114,13 +118,15 @@
else if ((command == "hotspot") && (words.size() >= 1)) {
if (words[1] == "topleft") {
hotSpot = TopLeft;
+ hwCursor->hotSpot = TopLeft;
}
else if (words[1] == "center") {
hotSpot = Center;
+ hwCursor->hotSpot = Center;
}
else {
logOutput.Print("%s: unknown hotspot (%s)\n",
- specFile.c_str(), words[1].c_str());
+ specFile.c_str(), words[1].c_str());
}
}
else if ((command == "lastframe") && (words.size() >= 1)) {
@@ -136,6 +142,8 @@
return BuildFromFileNames(name, lastFrame);
}
+ hwCursor->Finish();
+
return true;
}
@@ -168,14 +176,15 @@
SNPRINTF(namebuf, sizeof(namebuf), "anims/%s_%d.%s",
name.c_str(), frames.size(), ext);
ImageData image;
- if (!LoadCursorImage(namebuf, image)) {
+ if (!LoadCursorImage(namebuf, image))
break;
- }
images.push_back(image);
FrameData frame(image, defFrameLength);
frames.push_back(frame);
}
+ hwCursor->Finish();
+
return true;
}
@@ -193,16 +202,24 @@
return false;
}
- b.ReverseYAxis();
-
- CBitmap* final = getAlignedBitmap(b);
-
- // coded bmp transparency mask
+ // hardcoded bmp transparency mask
if ((name.size() >= 3) &&
(StringToLower(name.substr(name.size() - 3)) == "bmp")) {
- setBitmapTransparency(*final, 84, 84, 252);
+ setBitmapTransparency(b, 84, 84, 252);
}
+ if (hwCursor->needsYFlip()) {
+ //WINDOWS
+ b.ReverseYAxis();
+ hwCursor->PushImage(b.xsize,b.ysize,b.mem);
+ }else{
+ //X11
+ hwCursor->PushImage(b.xsize,b.ysize,b.mem);
+ b.ReverseYAxis();
+ }
+
+ CBitmap* final = getAlignedBitmap(b);
+
GLuint texID = 0;
glGenTextures(1, &texID);
glBindTexture(GL_TEXTURE_2D, texID);
@@ -267,6 +284,8 @@
void CMouseCursor::Draw(int x, int y, float scale)
{
+ if (scale<0) scale=-scale;
+
const FrameData& frame = frames[currentFrame];
const int xs = int(float(frame.image.xAlignedSize) * scale);
const int ys = int(float(frame.image.yAlignedSize) * scale);
@@ -346,3 +365,8 @@
const FrameData& frame = frames[currentFrame];
glBindTexture(GL_TEXTURE_2D, frame.image.texture);
}
+
+bool CMouseCursor::BindHwCursor()
+{
+ hwCursor->Bind();
+}
Index: rts/Game/UI/MouseCursor.h
===================================================================
--- rts/Game/UI/MouseCursor.h (revision 5850)
+++ rts/Game/UI/MouseCursor.h (working copy)
@@ -4,22 +4,27 @@
#include <string>
#include <vector>
#include "Rendering/GL/myGL.h"
+//#include "HwMouseCursor.h"
class CBitmap;
+class IHwCursor;
-
class CMouseCursor {
public:
enum HotSpot {TopLeft, Center};
+ bool animated;
+ bool hwValid; //if hardware cursor is valid
+
static CMouseCursor* New(const std::string &name, HotSpot hs);
~CMouseCursor(void);
void Update();
- void Draw(int x, int y, float scale);
- void DrawQuad(int x, int y);
- void BindTexture();
+ void Draw(int x, int y, float scale); // software cursor draw
+ void DrawQuad(int x, int y); // draw command queue icon
+ void BindTexture(); // software mouse cursor
+ bool BindHwCursor(); // hardware mouse cursor
int GetMaxSizeX() const { return xmaxsize; }
int GetMaxSizeY() const { return ymaxsize; }
@@ -55,6 +60,8 @@
std::vector<ImageData> images;
std::vector<FrameData> frames;
+ IHwCursor* hwCursor; // hardware cursor
+
float animTime;
float animPeriod;
int currentFrame;
@@ -67,4 +74,8 @@
};
+static const float minFrameLength = 0.010f; // seconds
+static const float defFrameLength = 0.100f; // seconds
+
+
#endif /* MOUSECURSOR_H */
Index: rts/Game/UI/MouseHandler.cpp
===================================================================
--- rts/Game/UI/MouseHandler.cpp (revision 5850)
+++ rts/Game/UI/MouseHandler.cpp (working copy)
@@ -61,7 +61,9 @@
{
lastx=300;
lasty=200;
- hide=false;
+ hide=true;
+ hwHide=true;
+ currentCursor=NULL;
for(int a=1;a<=NUM_BUTTONS;a++){
buttons[a].pressed=false;
@@ -73,11 +75,18 @@
LoadCursors();
+ // hide the cursor until we are ingame (not in loading screen etc.)
SDL_ShowCursor(SDL_DISABLE);
+#ifndef __APPLE__
+ hardwareCursor = !!configHandler.GetInt("HardwareCursor", 0);
+#else
+ hardwareCursor = false;
+#endif
+
soundMultiselID = sound->GetWaveId("sounds/button9.wav");
- invertMouse=!!configHandler.GetInt("InvertMouse",1);
+ invertMouse = !!configHandler.GetInt("InvertMouse",1);
doubleClickTime = (float)configHandler.GetInt("DoubleClickTime", 200) / 1000.0f;
scrollWheelSpeed = (float)configHandler.GetInt("ScrollWheelSpeed", 25);
@@ -86,7 +95,8 @@
CMouseHandler::~CMouseHandler()
{
- SDL_ShowCursor(SDL_ENABLE);
+ if (hwHide)
+ SDL_ShowCursor(SDL_ENABLE);
std::map<std::string, CMouseCursor*>::iterator ci;
for (ci = cursorFileMap.begin(); ci != cursorFileMap.end(); ++ci) {
@@ -533,37 +543,7 @@
}
}
-void CMouseHandler::ShowMouse()
-{
- if(hide){
- SDL_ShowCursor(SDL_DISABLE);
- hide=false;
- }
-}
-
-void CMouseHandler::HideMouse()
-{
- if (!hide) {
- lastx = gu->viewSizeX / 2 + gu->viewPosX;
- lasty = gu->viewSizeY / 2 + gu->viewPosY;
- SDL_ShowCursor(SDL_DISABLE);
- mouseInput->SetPos(int2(lastx, lasty));
- hide = true;
- }
-}
-
-void CMouseHandler::ToggleState()
-{
- if(locked){
- locked=false;
- ShowMouse();
- } else {
- locked=true;
- HideMouse();
-}
-}
-
void CMouseHandler::WarpMouse(int x, int y)
{
if (!locked) {
@@ -631,6 +611,7 @@
return "";
}
+
void CMouseHandler::EmptyMsgQueUpdate(void)
{
if (!hide) {
@@ -653,29 +634,115 @@
}
}
+
+void CMouseHandler::ShowMouse()
+{
+ if(hide){
+ // I don't use SDL_ShowCursor here 'cos it would cause a flicker (with hwCursor)
+ // instead update state and cursor at the same time
+ if (hardwareCursor){
+ hwHide=true; //call SDL_ShowCursor(SDL_ENABLE) later!
+ }else{
+ SDL_ShowCursor(SDL_DISABLE);
+ }
+ cursorText=""; //force hardware cursor rebinding (else we have standard b&w cursor)
+ hide=false;
+ }
+}
+
+
+void CMouseHandler::HideMouse()
+{
+ if (!hide) {
+ hwHide = true;
+ SDL_ShowCursor(SDL_DISABLE);
+ mouseInput->SetWMMouseCursor(NULL);
+ lastx = gu->viewSizeX / 2 + gu->viewPosX;
+ lasty = gu->viewSizeY / 2 + gu->viewPosY;
+ mouseInput->SetPos(int2(lastx, lasty));
+ hide = true;
+ }
+}
+
+
+void CMouseHandler::ToggleState()
+{
+ if(locked){
+ locked=false;
+ ShowMouse();
+ } else {
+ locked=true;
+ HideMouse();
+ }
+}
+
+
+void CMouseHandler::UpdateHwCursor()
+{
+ if (hardwareCursor){
+ hwHide=true; //call SDL_ShowCursor(SDL_ENABLE) later!
+ }else{
+ mouseInput->SetWMMouseCursor(NULL);
+ SDL_ShowCursor(SDL_DISABLE);
+ }
+ cursorText = "";
+}
+
+
/******************************************************************************/
+void CMouseHandler::SetCursor(const std::string& cmdName)
+{
+ if (cursorText.compare(cmdName)==0)
+ return;
+
+ cursorText = cmdName;
+ map<string, CMouseCursor*>::iterator it = cursorCommandMap.find(cmdName);
+ if (it != cursorCommandMap.end()) {
+ currentCursor = it->second;
+ } else {
+ currentCursor = cursorFileMap["cursornormal"];
+ }
+
+ if (hardwareCursor && !hide && currentCursor) {
+ if (currentCursor->hwValid) {
+ if (hwHide) {
+ SDL_ShowCursor(SDL_ENABLE);
+ hwHide = false;
+ }
+ currentCursor->BindHwCursor();
+ }else{
+ hwHide = true;
+ SDL_ShowCursor(SDL_DISABLE);
+ mouseInput->SetWMMouseCursor(NULL);
+ }
+ }
+}
+
+
void CMouseHandler::UpdateCursors()
{
+ //we update all cursors, 'cos of the command queue icons
map<string, CMouseCursor *>::iterator it;
for (it = cursorFileMap.begin(); it != cursorFileMap.end(); ++it) {
- if (it->second != NULL) {
+ if (it->second != NULL)
it->second->Update();
- }
}
}
void CMouseHandler::DrawCursor(void)
{
- if (guihandler) {
+ if (guihandler)
guihandler->DrawCentroidCursor();
- }
- if (hide || (cursorText == "none")) {
+ if (hide || (cursorText == "none"))
return;
- }
+ if (currentCursor && (!hardwareCursor || !currentCursor->hwValid) )
+ currentCursor->Draw(lastx, lasty, cursorScale);
+
+/*
CMouseCursor* mc;
map<string, CMouseCursor*>::iterator it = cursorCommandMap.find(cursorText);
if (it != cursorCommandMap.end()) {
@@ -699,11 +766,10 @@
else {
nc->Draw(lastx, lasty, 1.0f);
if (mc != nc) {
- mc->Draw(lastx + nc->GetMaxSizeX(),
- lasty + nc->GetMaxSizeY(), -cursorScale);
+ mc->Draw(lastx + nc->GetMaxSizeX(), lasty + nc->GetMaxSizeY(), -cursorScale);
}
}
- }
+ }*/
}
Index: rts/Game/UI/MouseHandler.h
===================================================================
--- rts/Game/UI/MouseHandler.h (revision 5850)
+++ rts/Game/UI/MouseHandler.h (working copy)
@@ -16,15 +16,20 @@
class CCameraController;
-class CMouseHandler
+class CMouseHandler
{
public:
+ void SetCursor(const std::string& cmdName);
+
+ bool hardwareCursor;
+ void UpdateHwCursor(); //calls SDL_ShowCursor, used for ingame hwcursor enabling
+
void UpdateCursors();
void HideMouse();
void ShowMouse();
- void ToggleState();
+ void ToggleState(); // lock+hide (used by fps camera and middle click scrolling)
void WarpMouse(int x, int y);
- void Draw();
+ void Draw(); // draw mousebox (selection box)
void MouseRelease(int x,int y,int button);
void MousePress(int x,int y,int button);
void MouseMove(int x,int y);
@@ -32,9 +37,10 @@
CMouseHandler();
virtual ~CMouseHandler();
- int lastx;
- int lasty;
+ int lastx;
+ int lasty;
bool hide;
+ bool hwHide;
bool locked;
bool invertMouse;
float doubleClickTime;
@@ -53,23 +59,19 @@
};
ButtonPress buttons[NUM_BUTTONS + 1]; /* One-bottomed. */
+ int activeButton;
float3 dir;
- int activeButton;
+ int soundMultiselID;
- unsigned int cursorTex;
- std::string cursorText;
- std::string cursorTextRight;
- float cursorScale;
+ float cursorScale;
void DrawCursor(void);
std::string GetCurrentTooltip(void);
+ std::string cursorText; //current cursor name
+ CMouseCursor *currentCursor;
std::map<std::string, CMouseCursor*> cursorFileMap;
std::map<std::string, CMouseCursor*> cursorCommandMap;
- //CMouseCursor *mc;
-
- int soundMultiselID;
-
bool AssignMouseCursor(const std::string& cmdName,
const std::string& fileName,
CMouseCursor::HotSpot hotSpot,
Index: rts/System/MouseInput.cpp
===================================================================
--- rts/System/MouseInput.cpp (revision 5850)
+++ rts/System/MouseInput.cpp (working copy)
@@ -3,12 +3,17 @@
The code hacks around the mouse input from DirectInput, which SDL uses in fullscreen mode.
Instead it installs a window message proc and reads input from WM_MOUSEMOVE.
On non-windows, the normal SDL events are used for mouse input
+
+ new:
+ It also workarounds a issue with SDL+windows and hardware cursors (->it has to block WM_SETCURSOR),
+ so it is used now always even in window mode!
*/
#include "StdAfx.h"
#include "Platform/Win/win32.h"
#include "MouseInput.h"
#include "Game/UI/MouseHandler.h"
+#include "LogOutput.h"
#include <SDL_events.h>
#include <SDL_syswm.h>
@@ -24,6 +29,7 @@
//////////////////////////////////////////////////////////////////////
#ifdef WIN32
+
class CWin32MouseInput : public IMouseInput
{
public:
@@ -33,6 +39,7 @@
int2 mousepos;
bool mousemoved;
HWND wnd;
+ HCURSOR hCursor;
// SDL runs the window in a different thread, hence the indirectness of the mouse pos handling
static LRESULT CALLBACK SpringWndProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
@@ -41,10 +48,23 @@
inst->mousepos = int2(LOWORD(lparam),HIWORD(lparam));
inst->mousemoved = true;
return FALSE;
+ }else if (msg==WM_SETCURSOR) {
+ if (inst->hCursor!=NULL) {
+ Uint16 hittest = LOWORD(lparam);
+ if ( hittest == HTCLIENT ) {
+ SetCursor(inst->hCursor);
+ return TRUE;
+ }
+ }
}
return CallWindowProc((WNDPROC)inst->sdl_wndproc, wnd, msg, wparam, lparam);
}
+ void SetWMMouseCursor(void* wmcursor)
+ {
+ hCursor = (HCURSOR)wmcursor;
+ }
+
void InstallWndCallback()
{
sdl_wndproc = GetWindowLongPtr(wnd, GWLP_WNDPROC);
@@ -55,6 +75,8 @@
{
inst = this;
+ hCursor = NULL;
+
mousemoved = false;
sdl_wndproc = 0;
@@ -65,9 +87,7 @@
wnd = info.window;
- // In windowed mode, SDL uses straight Win32 API to handle mouse movement, which works ok.
- if (fullscreen)
- InstallWndCallback();
+ InstallWndCallback();
}
~CWin32MouseInput()
{
@@ -83,7 +103,7 @@
{
mousepos = pos;
if (fullscreen)
- SetCursorPos (pos.x, pos.y);
+ SetCursorPos(pos.x, pos.y);
else
SDL_WarpMouse(pos.x, pos.y);
}
@@ -111,12 +131,12 @@
mouse->MousePress (mousepos.x, mousepos.y, 5);
}
break;}
- case SDL_MOUSEMOTION: // the normal SDL method works fine in windowed mode
+ /*case SDL_MOUSEMOTION: // the normal SDL method works fine in windowed mode
if(!fullscreen) {
mousepos = int2(event.motion.x, event.motion.y);
mouse->MouseMove(mousepos.x, mousepos.y);
}
- break;
+ break;*/
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_WHEELUP)
mouse->MouseWheel(true);
Index: rts/System/MouseInput.h
===================================================================
--- rts/System/MouseInput.h (revision 5850)
+++ rts/System/MouseInput.h (working copy)
@@ -17,6 +17,8 @@
virtual void Update () {}
virtual void HandleSDLMouseEvent (SDL_Event& event) = 0;
+
+ virtual void SetWMMouseCursor (void* wmcursor) {}
};
-
units.patch (9,126 bytes) 2008-05-10 16:28
Index: rts/Lua/LuaUnitDefs.cpp
===================================================================
--- rts/Lua/LuaUnitDefs.cpp (revision 5850)
+++ rts/Lua/LuaUnitDefs.cpp (working copy)
@@ -799,6 +799,7 @@
ADD_BOOL("canCrash", ud.canCrash);
ADD_BOOL("canFireControl", ud.canFireControl);
ADD_INT( "fireState", ud.fireState);
+ ADD_INT( "moveState", ud.moveState);
ADD_BOOL("fullHealthFactory", ud.fullHealthFactory);
ADD_BOOL("factoryHeadingTakeoff", ud.factoryHeadingTakeoff);
Index: rts/Sim/Units/CommandAI/AirCAI.cpp
===================================================================
--- rts/Sim/Units/CommandAI/AirCAI.cpp (revision 5850)
+++ rts/Sim/Units/CommandAI/AirCAI.cpp (working copy)
@@ -5,7 +5,7 @@
#include "Game/GameHelper.h"
#include "Game/SelectedUnits.h"
#include "Game/UI/CommandColors.h"
-#include "Game/UI/CursorIcons.h"
+//#include "Game/UI/CursorIcons.h"
#include "Map/Ground.h"
#include "Rendering/GL/glExtra.h"
#include "Rendering/GL/myGL.h"
Index: rts/Sim/Units/CommandAI/BuilderCAI.cpp
===================================================================
--- rts/Sim/Units/CommandAI/BuilderCAI.cpp (revision 5850)
+++ rts/Sim/Units/CommandAI/BuilderCAI.cpp (working copy)
@@ -1102,7 +1102,7 @@
const CFeature* f = *fi;
if (f->def->reclaimable &&
(recAnyTeam || (f->allyteam != owner->allyteam))) {
- const float dist = f3Dist(f->pos, owner->pos);
+ const float dist = f3SqLen(f->pos - owner->pos);
if ((dist < bestDist) &&
(noResCheck ||
((f->def->metal > 0.0f) && (team->metal < team->metalStorage)) ||
@@ -1146,7 +1146,7 @@
for (fi = features.begin(); fi != features.end(); ++fi) {
const CFeature* f = *fi;
if (f->def->destructable && f->createdFromUnit != "") {
- const float dist = f3Dist(f->pos, owner->pos);
+ const float dist = f3SqLen(f->pos - owner->pos);
if (dist < bestDist) {
// dont lock-on to units outside of our reach (for immobile builders)
if (!owner->unitDef->canmove && !ObjInBuildRange(f)) {
@@ -1186,7 +1186,7 @@
if (!gs->Ally(myAllyteam, unit->allyteam) && (unit != owner) &&
!unit->beingBuilt && unit->unitDef->capturable) {
- const float dist = f3Dist(unit->pos, owner->pos);
+ const float dist = f3SqLen(unit->pos - owner->pos);
if (dist < bestDist) {
// dont lock-on to units outside of our reach (for immobile builders)
@@ -1251,7 +1251,7 @@
trySelfRepair = true;
continue;
}
- const float dist = f3Dist(unit->pos, owner->pos);
+ const float dist = f3SqLen(unit->pos - owner->pos);
if (dist < bestDist) {
bestDist = dist;
best = unit;
@@ -1260,7 +1260,7 @@
}
else {
if (attackEnemy && owner->unitDef->canAttack && (owner->maxRange > 0)) {
- const float dist = f3Dist(unit->pos, owner->pos);
+ const float dist = f3SqLen(unit->pos - owner->pos);
if ((dist < bestDist) || !haveEnemy) {
if (!owner->unitDef->canmove &&
((dist - unit->radius) > owner->maxRange)) {
Index: rts/Sim/Units/CommandAI/CommandAI.cpp
===================================================================
--- rts/Sim/Units/CommandAI/CommandAI.cpp (revision 5850)
+++ rts/Sim/Units/CommandAI/CommandAI.cpp (working copy)
@@ -219,7 +219,6 @@
c.params.push_back("Roam");
c.tooltip="Move State: Sets how far out of its way\n an unit will move to attack enemies";
possibleCommands.push_back(c);
- owner->moveState=1;
nonQueingCommands.insert(CMD_MOVE_STATE);
} else {
owner->moveState=0;
Index: rts/Sim/Units/CommandAI/MobileCAI.cpp
===================================================================
--- rts/Sim/Units/CommandAI/MobileCAI.cpp (revision 5850)
+++ rts/Sim/Units/CommandAI/MobileCAI.cpp (working copy)
@@ -7,7 +7,7 @@
#include "Game/SelectedUnits.h"
#include "Game/Team.h"
#include "Game/UI/CommandColors.h"
-#include "Game/UI/CursorIcons.h"
+//#include "Game/UI/CursorIcons.h"
#include "Map/Ground.h"
#include "Rendering/GL/myGL.h"
#include "Sim/Misc/AirBaseHandler.h"
Index: rts/Sim/Units/CommandAI/TransportCAI.cpp
===================================================================
--- rts/Sim/Units/CommandAI/TransportCAI.cpp (revision 5850)
+++ rts/Sim/Units/CommandAI/TransportCAI.cpp (working copy)
@@ -9,7 +9,7 @@
#include "Map/Ground.h"
#include "Sim/Misc/QuadField.h"
#include "Game/UI/CommandColors.h"
-#include "Game/UI/CursorIcons.h"
+//#include "Game/UI/CursorIcons.h"
#include "LogOutput.h"
#include "Rendering/GL/myGL.h"
#include "Rendering/GL/glExtra.h"
Index: rts/Sim/Units/Unit.cpp
===================================================================
--- rts/Sim/Units/Unit.cpp (revision 5850)
+++ rts/Sim/Units/Unit.cpp (working copy)
@@ -1452,7 +1452,7 @@
//All units are set as ground-blocking.
blocking = true;
- if(pos.y+model->height<1) //some torp launchers etc is exactly in the surface and should be considered uw anyway
+ if(pos.y+model->height<1) //some torp launchers etc are exactly in the surface and should be considered uw anyway
isUnderWater=true;
if(!unitDef->canKamikaze || unitDef->type=="Building" || unitDef->type=="Factory") //semi hack to make mines not block ground
@@ -1460,6 +1460,41 @@
UpdateTerrainType();
+ Command c;
+ if (unitDef->canmove || unitDef->builder) {
+ if (unitDef->moveState<0) {
+ if (builder!=NULL) {
+ moveState = builder->moveState;
+ }else{
+ moveState = 1;
+ }
+ } else {
+ moveState = unitDef->moveState;
+ }
+
+ c.id = CMD_MOVE_STATE;
+ c.params.push_back(moveState);
+ commandAI->GiveCommand(c);
+ c.params.clear();
+ }
+
+ if (commandAI->CanChangeFireState()) {
+ if (unitDef->fireState<0) {
+ if (builder!=NULL) {
+ fireState = builder->fireState;
+ }else{
+ fireState = 2;
+ }
+ } else {
+ fireState = unitDef->fireState;
+ }
+
+ c.id = CMD_FIRE_STATE;
+ c.params.push_back(fireState);
+ commandAI->GiveCommand(c);
+ c.params.clear();
+ }
+
luaCallIns.UnitCreated(this, builder);
globalAI->UnitCreated(this); // FIXME -- add builder?
}
Index: rts/Sim/Units/UnitDef.h
===================================================================
--- rts/Sim/Units/UnitDef.h (revision 5850)
+++ rts/Sim/Units/UnitDef.h (working copy)
@@ -263,6 +263,7 @@
bool canFireControl;
int fireState;
+ int moveState;
//aircraft stuff
float wingDrag;
Index: rts/Sim/Units/UnitDefHandler.cpp
===================================================================
--- rts/Sim/Units/UnitDefHandler.cpp (revision 5850)
+++ rts/Sim/Units/UnitDefHandler.cpp (working copy)
@@ -341,9 +341,6 @@
ud.canPatrol = udTable.GetBool("canPatrol", true);
ud.canGuard = udTable.GetBool("canGuard", true);
ud.canRepeat = udTable.GetBool("canRepeat", true);
- bool noAutoFire = udTable.GetBool("noAutoFire", false);
- ud.canFireControl = udTable.GetBool("canFireControl", !noAutoFire);
- ud.fireState = udTable.GetInt("fireState", ud.canFireControl ? -1 : 0);
ud.builder = udTable.GetBool("builder", true);
@@ -386,6 +383,13 @@
ud.maxDec = fabs(udTable.GetFloat("brakeRate", 3.0f*ud.maxAcc)) * (ud.canfly ? 0.1f : 1.f); // no negative values
ud.turnRate = udTable.GetFloat("turnRate", 0.0f);
+ bool noAutoFire = udTable.GetBool("noAutoFire", false);
+ ud.canFireControl = udTable.GetBool("canFireControl", !noAutoFire);
+ ud.fireState = udTable.GetInt("fireState", ud.canFireControl ? -1 : 2);
+ ud.fireState = std::min(ud.fireState,2);
+ ud.moveState = udTable.GetInt("moveState", (ud.canmove && ud.speed>0.0f) ? -1 : 1);
+ ud.moveState = std::min(ud.moveState,2);
+
ud.buildRange3D = udTable.GetBool("buildRange3D", false);
ud.buildDistance = udTable.GetFloat("buildDistance", 128.0f);
ud.buildDistance = std::max(128.0f, ud.buildDistance);
Index: rts/Sim/Units/UnitTypes/Builder.cpp
===================================================================
--- rts/Sim/Units/UnitTypes/Builder.cpp (revision 5850)
+++ rts/Sim/Units/UnitTypes/Builder.cpp (working copy)
@@ -327,7 +327,7 @@
curCapture->lineage = this->lineage;
gs->Team(oldLineage)->LeftLineage(curCapture);
}
- curCapture->captureProgress=0.5f; //make units somewhat easier to capture back after first capture
+ curCapture->captureProgress=0.0f;
StopBuild(true);
}
} else {
Index: rts/Sim/Units/UnitTypes/Factory.cpp
===================================================================
--- rts/Sim/Units/UnitTypes/Factory.cpp (revision 5850)
+++ rts/Sim/Units/UnitTypes/Factory.cpp (working copy)
@@ -193,20 +193,6 @@
curBuild->SetGroup(group);
}
- Command c;
- c.options = 0;
-
- c.id = CMD_MOVE_STATE;
- c.params.push_back(moveState);
- curBuild->commandAI->GiveCommand(c);
- c.params.clear();
-
- if(curBuild->unitDef->fireState < 0) {
- c.id = CMD_FIRE_STATE;
- c.params.push_back(fireState);
- curBuild->commandAI->GiveCommand(c);
- }
-
bool userOrders = true;
if (curBuild->commandAI->commandQue.empty() ||
(dynamic_cast<CMobileCAI*>(curBuild->commandAI) &&
-
LuaCallins.patch (4,845 bytes) 2008-05-10 16:28
Index: rts/Game/GameServer.cpp
===================================================================
--- rts/Game/GameServer.cpp (revision 5850)
+++ rts/Game/GameServer.cpp (working copy)
@@ -27,6 +27,7 @@
#include "Player.h"
#include "Team.h"
#include "Server/MsgStrings.h"
+#include "Lua/LuaRules.h"
#ifdef DEDICATED
#include <iostream>
@@ -1214,8 +1215,8 @@
if (numActiveTeams[a] != 0)
++numActiveAllyTeams;
- if (numActiveAllyTeams <= 1)
- {
+ bool gameOver = (numActiveAllyTeams <= 1);
+ if (luaRules!=NULL && luaRules->IsGameOver(gameOver)) {
gameEndTime=SDL_GetTicks();
serverNet->SendSendPlayerStat();
}
Index: rts/Lua/LuaRules.cpp
===================================================================
--- rts/Lua/LuaRules.cpp (revision 5850)
+++ rts/Lua/LuaRules.cpp (working copy)
@@ -109,6 +109,7 @@
return;
}
+ haveIsGameOver = HasCallIn("IsGameOver");
haveCommandFallback = HasCallIn("CommandFallback");
haveAllowCommand = HasCallIn("AllowCommand");
haveAllowUnitCreation = HasCallIn("AllowUnitCreation");
@@ -222,7 +223,9 @@
bool CLuaRules::SyncedUpdateCallIn(const string& name)
{
- if (name == "CommandFallback") {
+ if (name == "IsGameOver") {
+ haveIsGameOver = HasCallIn("IsGameOver");
+ } else if (name == "CommandFallback") {
haveCommandFallback = HasCallIn("CommandFallback");
} else if (name == "AllowCommand") {
haveAllowCommand = HasCallIn("AllowCommand");
@@ -265,6 +268,43 @@
}
+bool CLuaRules::IsGameOver(const bool gameOver)
+{
+ if (!haveIsGameOver) {
+ return gameOver; // the call is not defined
+ }
+
+ LUA_CALL_IN_CHECK(L);
+ lua_checkstack(L, 8);
+ static const LuaHashString cmdStr("IsGameOver");
+ if (!cmdStr.GetGlobalFunc(L)) {
+ return gameOver; // the call is not defined
+ }
+
+ lua_pushboolean(L, gameOver);
+
+ // call the function
+ if (!RunCallIn(cmdStr, 1, 1)) {
+ return gameOver;
+ }
+
+ // get the results
+ const int args = lua_gettop(L);
+ if (!lua_isboolean(L, -1)) {
+ logOutput.Print("%s() bad return value (%i)\n",
+ cmdStr.GetString().c_str(), args);
+ lua_pop(L, 1);
+ return gameOver;
+ }
+
+ const bool retval = !!lua_toboolean(L, -1);
+ lua_pop(L, 1);
+
+ // return 'true' to remove the command
+ return retval;
+}
+
+
bool CLuaRules::CommandFallback(const CUnit* unit, const Command& cmd)
{
if (!haveCommandFallback) {
@@ -493,7 +533,7 @@
// get the results
const int args = lua_gettop(L);
- if ((args != 1) || !lua_isboolean(L, -1)) {
+ if (!lua_isboolean(L, -1)) {
logOutput.Print("%s() bad return value (%i)\n",
cmdStr.GetString().c_str(), args);
lua_pop(L, 1);
@@ -533,7 +573,7 @@
// get the results
const int args = lua_gettop(L);
- if ((args != 1) || !lua_isboolean(L, -1)) {
+ if (!lua_isboolean(L, -1)) {
logOutput.Print("%s() bad return value (%i)\n",
cmdStr.GetString().c_str(), args);
lua_pop(L, 1);
@@ -573,7 +613,7 @@
// get the results
const int args = lua_gettop(L);
- if ((args != 1) || !lua_isboolean(L, -1)) {
+ if (!lua_isboolean(L, -1)) {
logOutput.Print("%s() bad return value (%i)\n",
cmdStr.GetString().c_str(), args);
lua_pop(L, 1);
@@ -649,7 +689,7 @@
// get the results
const int args = lua_gettop(L);
- if ((args != 1) || !lua_isboolean(L, -1)) {
+ if (!lua_isboolean(L, -1)) {
logOutput.Print("%s() bad return value (%i)\n",
cmdStr.GetString().c_str(), args);
lua_pop(L, 1);
@@ -687,7 +727,7 @@
// get the results
const int args = lua_gettop(L);
- if ((args != 1) || !lua_isboolean(L, -1)) {
+ if (!lua_isboolean(L, -1)) {
logOutput.Print("%s() bad return value (%i)\n",
cmdStr.GetString().c_str(), args);
lua_pop(L, 1);
@@ -815,7 +855,7 @@
}
const int args = lua_gettop(L);
- if ((args != 1) || !lua_isboolean(L, -1)) {
+ if (!lua_isboolean(L, -1)) {
logOutput.Print("%s() bad return value (%i)\n",
cmdStr.GetString().c_str(), args);
lua_pop(L, 1);
Index: rts/Lua/LuaRules.h
===================================================================
--- rts/Lua/LuaRules.h (revision 5850)
+++ rts/Lua/LuaRules.h (working copy)
@@ -43,6 +43,7 @@
bool SyncedUpdateCallIn(const string& name);
bool UnsyncedUpdateCallIn(const string& name);
+ bool IsGameOver(const bool gameOver);
bool CommandFallback(const CUnit* unit, const Command& cmd);
bool BuilderTerraformComplete(const CUnit* unit, const CUnit* build);
bool AllowCommand(const CUnit* unit, const Command& cmd, bool fromSynced);
@@ -105,6 +106,7 @@
static void CobCallback(int retCode, void* p1, void* p2);
private:
+ bool haveIsGameOver;
bool haveCommandFallback;
bool haveAllowCommand;
bool haveAllowUnitCreation;
-
LuaCallouts.patch (12,807 bytes) 2008-05-10 16:29
Index: rts/Lua/LuaOpenGL.cpp
===================================================================
--- rts/Lua/LuaOpenGL.cpp (revision 5850)
+++ rts/Lua/LuaOpenGL.cpp (working copy)
@@ -3404,6 +3404,16 @@
lua_pushboolean(L, true);
}
}
+ else if (texture == "$shading") {
+ glBindTexture(GL_TEXTURE_2D, readmap->GetShadingTexture());
+ glEnable(GL_TEXTURE_2D);
+ lua_pushboolean(L, true);
+ }
+ else if (texture == "$grass") {
+ glBindTexture(GL_TEXTURE_2D, readmap->GetGrassShadingTexture());
+ glEnable(GL_TEXTURE_2D);
+ lua_pushboolean(L, true);
+ }
else {
lua_pushboolean(L, false);
}
@@ -3634,6 +3644,16 @@
HSTR_PUSH_NUMBER(L, "ysize", heightMapTexture.GetSizeY());
}
}
+ else if (texture == "$shading") {
+ lua_newtable(L);
+ HSTR_PUSH_NUMBER(L, "xsize", gs->pwr2mapx);
+ HSTR_PUSH_NUMBER(L, "ysize", gs->pwr2mapy);
+ }
+ else if (texture == "$grass") {
+ lua_newtable(L);
+ HSTR_PUSH_NUMBER(L, "xsize", 1024);
+ HSTR_PUSH_NUMBER(L, "ysize", 1024);
+ }
}
else {
const CNamedTextures::TexInfo* texInfo;
@@ -3664,8 +3684,8 @@
if (tex == NULL) {
return 0;
}
- glBindTexture(GL_TEXTURE_2D, tex->id);
- glEnable(GL_TEXTURE_2D); // leave it bound and enabled
+ glBindTexture(tex->target, tex->id);
+ glEnable(tex->target); // leave it bound and enabled
const GLint xoff = (GLint)luaL_checknumber(L, 2);
const GLint yoff = (GLint)luaL_checknumber(L, 3);
@@ -3673,11 +3693,13 @@
const GLint y = (GLint)luaL_checknumber(L, 5);
const GLsizei w = (GLsizei)luaL_checknumber(L, 6);
const GLsizei h = (GLsizei)luaL_checknumber(L, 7);
- const GLenum target = (GLenum)luaL_optnumber(L, 8, GL_TEXTURE_2D);
+ const GLenum target = (GLenum)luaL_optnumber(L, 8, tex->target);
const GLenum level = (GLenum)luaL_optnumber(L, 9, 0);
glCopyTexSubImage2D(target, level, xoff, yoff, x, y, w, h);
+ if (tex->target != GL_TEXTURE_2D) {glDisable(tex->target);}
+
return 0;
}
@@ -4232,6 +4254,7 @@
} else {
luaL_error(L, "Incorrect arguments to gl.LoadMatrix()");
}
+ return 0;
}
else if (luaType == LUA_TTABLE) {
if (ParseFloatArray(L, matrix, 16) != 16) {
@@ -4262,6 +4285,7 @@
} else {
luaL_error(L, "Incorrect arguments to gl.MultMatrix()");
}
+ return 0;
}
else if (luaType == LUA_TTABLE) {
if (ParseFloatArray(L, matrix, 16) != 16) {
Index: rts/Lua/LuaSyncedCtrl.cpp
===================================================================
--- rts/Lua/LuaSyncedCtrl.cpp (revision 5850)
+++ rts/Lua/LuaSyncedCtrl.cpp (working copy)
@@ -59,6 +59,12 @@
using namespace std;
+static int heightMapx1;
+static int heightMapx2;
+static int heightMapz1;
+static int heightMapz2;
+
+
/******************************************************************************/
/******************************************************************************/
@@ -68,6 +74,7 @@
bool LuaSyncedCtrl::inCreateFeature = false;
bool LuaSyncedCtrl::inDestroyFeature = false;
bool LuaSyncedCtrl::inGiveOrder = false;
+bool LuaSyncedCtrl::inHeightMap = false;
/******************************************************************************/
@@ -164,11 +171,14 @@
REGISTER_LUA_CFUNC(GiveOrderArrayToUnitMap);
REGISTER_LUA_CFUNC(GiveOrderArrayToUnitArray);
-
REGISTER_LUA_CFUNC(LevelHeightMap);
REGISTER_LUA_CFUNC(AdjustHeightMap);
REGISTER_LUA_CFUNC(RevertHeightMap);
+ REGISTER_LUA_CFUNC(SetHeight);
+ REGISTER_LUA_CFUNC(SetTerraform);
+ REGISTER_LUA_CFUNC(HeightMapFunc);
+
REGISTER_LUA_CFUNC(EditUnitCmdDesc);
REGISTER_LUA_CFUNC(InsertUnitCmdDesc);
REGISTER_LUA_CFUNC(RemoveUnitCmdDesc);
@@ -2401,6 +2411,116 @@
/******************************************************************************/
/******************************************************************************/
+int LuaSyncedCtrl::SetHeight(lua_State* L)
+{
+ if (!inHeightMap) {
+ luaL_error(L, "SetHeight() can only be called in Spring.HeightMapFunc()");
+ }
+
+ const int args = lua_gettop(L);
+
+ if (args != 3 || !lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3)) {
+ luaL_error(L, "Incorrect arguments to Spring.SetHeight(x,z,h)");
+ }
+
+ const float xl = (float)lua_tonumber(L, 1);
+ const float zl = (float)lua_tonumber(L, 2);
+ const float h = (float)lua_tonumber(L, 3);
+
+ // quantize and clamp
+ const int x = (int)max(0 , min(gs->mapx, (int)(xl / SQUARE_SIZE)));
+ const int z = (int)max(0 , min(gs->mapy, (int)(zl / SQUARE_SIZE)));
+
+ const int index = (z * (gs->mapx + 1)) + x;
+
+ readmap->GetHeightmap()[index] = h;
+
+ //update RecalcArea()
+ if (x<heightMapx1) heightMapx1 = x;
+ if (x>heightMapx2) heightMapx2 = x;
+ if (z<heightMapz1) heightMapz1 = z;
+ if (z>heightMapz2) heightMapz2 = z;
+
+ return 0;
+}
+
+
+int LuaSyncedCtrl::SetTerraform(lua_State* L)
+{
+ if (!inHeightMap) {
+ luaL_error(L, "SetTerraform() can only be called in Spring.HeightMapFunc()");
+ }
+
+ const int args = lua_gettop(L);
+
+ if (args != 4 || !lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4)) {
+ luaL_error(L, "Incorrect arguments to Spring.SetTerraform(x,z,height,terraformScale)");
+ }
+
+ const float xl = (float)lua_tonumber(L, 1);
+ const float zl = (float)lua_tonumber(L, 2);
+ const float h = (float)lua_tonumber(L, 3);
+ const float t = (float)lua_tonumber(L, 3);
+
+ // quantize and clamp
+ const int x = (int)max(0 , min(gs->mapx, (int)(xl / SQUARE_SIZE)));
+ const int z = (int)max(0 , min(gs->mapy, (int)(zl / SQUARE_SIZE)));
+
+ const int index = (z * (gs->mapx + 1)) + x;
+
+ float& heightMap = readmap->GetHeightmap()[index];
+ heightMap += (h - heightMap) * t;
+
+ //update RecalcArea()
+ if (x<heightMapx1) heightMapx1 = x;
+ if (x>heightMapx2) heightMapx2 = x;
+ if (z<heightMapz1) heightMapz1 = z;
+ if (z>heightMapz2) heightMapz2 = z;
+
+ return 0;
+}
+
+
+int LuaSyncedCtrl::HeightMapFunc(lua_State* L)
+{
+ if (mapDamage->disabled) {
+ return 0;
+ }
+
+ const int args = lua_gettop(L); // number of arguments
+ if ((args < 1) || !lua_isfunction(L, 1)) {
+ luaL_error(L, "Incorrect arguments to Spring.HeightMapFunc(func, ...)");
+ }
+
+ if (inHeightMap) {
+ luaL_error(L, "HeightMapFunc() recursion is not permitted");
+ }
+
+ heightMapx1 = -1;
+ heightMapx2 = gs->mapx;
+ heightMapz1 = -1;
+ heightMapz2 = gs->mapy;
+
+ inHeightMap = true;
+ const int error = lua_pcall(L, (args-1), 0, 0);
+ inHeightMap = false;
+
+ if (error != 0) {
+ logOutput.Print("Spring.HeightMapFunc: error(%i) = %s",
+ error, lua_tostring(L, -1));
+ lua_error(L);
+ }
+
+ if (heightMapx1 != -1) {
+ mapDamage->RecalcArea(heightMapx1, heightMapx2, heightMapz1, heightMapz2);
+ }
+ return 0;
+}
+
+
+/******************************************************************************/
+/******************************************************************************/
+
int LuaSyncedCtrl::SetNoPause(lua_State* L)
{
if (!FullCtrl()) {
Index: rts/Lua/LuaSyncedCtrl.h
===================================================================
--- rts/Lua/LuaSyncedCtrl.h (revision 5850)
+++ rts/Lua/LuaSyncedCtrl.h (working copy)
@@ -20,6 +20,7 @@
static bool inCreateFeature;
static bool inDestroyFeature;
static bool inGiveOrder;
+ static bool inHeightMap;
private:
// all LuaHandleSynced
@@ -95,6 +96,10 @@
static int AdjustHeightMap(lua_State* L);
static int RevertHeightMap(lua_State* L);
+ static int SetHeight(lua_State* L);
+ static int SetTerraform(lua_State* L);
+ static int HeightMapFunc(lua_State* L);
+
// LuaRules (fullCtrl)
static int EditUnitCmdDesc(lua_State* L);
static int InsertUnitCmdDesc(lua_State* L);
Index: rts/Lua/LuaSyncedRead.cpp
===================================================================
--- rts/Lua/LuaSyncedRead.cpp (revision 5850)
+++ rts/Lua/LuaSyncedRead.cpp (working copy)
@@ -56,6 +56,7 @@
#include "Sim/Units/CommandAI/LineDrawer.h"
#include "Sim/Weapons/PlasmaRepulser.h"
#include "Sim/Weapons/Weapon.h"
+#include "Sim/Weapons/WeaponDefHandler.h"
#include "System/myMath.h"
#include "System/LogOutput.h"
#include "System/TdfParser.h"
@@ -139,6 +140,7 @@
REGISTER_LUA_CFUNC(GetPlayerInfo);
REGISTER_LUA_CFUNC(GetPlayerControlledUnit);
+ REGISTER_LUA_CFUNC(GetPlayerStats);
REGISTER_LUA_CFUNC(GetTeamInfo);
REGISTER_LUA_CFUNC(GetTeamResources);
@@ -190,6 +192,7 @@
REGISTER_LUA_CFUNC(GetUnitRadius);
REGISTER_LUA_CFUNC(GetUnitPosition);
REGISTER_LUA_CFUNC(GetUnitBasePosition);
+ REGISTER_LUA_CFUNC(GetUnitVectors);
REGISTER_LUA_CFUNC(GetUnitDirection);
REGISTER_LUA_CFUNC(GetUnitHeading);
REGISTER_LUA_CFUNC(GetUnitVelocity);
@@ -199,6 +202,7 @@
REGISTER_LUA_CFUNC(GetUnitIsTransporting);
REGISTER_LUA_CFUNC(GetUnitShieldState);
REGISTER_LUA_CFUNC(GetUnitWeaponState);
+ REGISTER_LUA_CFUNC(GetUnitWeaponVectors);
REGISTER_LUA_CFUNC(GetUnitTravel);
REGISTER_LUA_CFUNC(GetUnitEstimatedPath);
REGISTER_LUA_CFUNC(GetUnitLosState);
@@ -1247,6 +1251,31 @@
}
+int LuaSyncedRead::GetPlayerStats(lua_State* L)
+{
+ const int args = lua_gettop(L); // number of arguments
+ if ((args != 1) || !lua_isnumber(L, 1)) {
+ luaL_error(L, "Incorrect arguments to GetPlayerStats(playerID)");
+ }
+
+ const CPlayer* player = ParsePlayer(L, __FUNCTION__, 1);
+ if (player == NULL) {
+ return 0;
+ }
+
+ if (!IsAlliedTeam(player->team)) {
+ return 0;
+ }
+
+ lua_pushnumber(L, player->currentStats->mousePixels);
+ lua_pushnumber(L, player->currentStats->mouseClicks);
+ lua_pushnumber(L, player->currentStats->keyPresses);
+ lua_pushnumber(L, player->currentStats->numCommands);
+ lua_pushnumber(L, player->currentStats->unitCommands);
+ return 5;
+}
+
+
int LuaSyncedRead::AreTeamsAllied(lua_State* L)
{
const int args = lua_gettop(L); // number of arguments
@@ -2556,7 +2585,29 @@
return 3;
}
+int LuaSyncedRead::GetUnitVectors(lua_State* L)
+{
+ CUnit* unit = ParseInLosUnit(L, __FUNCTION__, 1);
+ if (unit == NULL) {
+ return 0;
+ }
+#define PACK_VECTOR(n) \
+ HSTR_PUSH(L, #n); \
+ lua_newtable(L); \
+ lua_pushnumber(L, 1); lua_pushnumber(L, unit-> n .x); lua_rawset(L, -3); \
+ lua_pushnumber(L, 2); lua_pushnumber(L, unit-> n .y); lua_rawset(L, -3); \
+ lua_pushnumber(L, 3); lua_pushnumber(L, unit-> n .z); lua_rawset(L, -3); \
+ lua_rawset(L, -3)
+
+ PACK_VECTOR(frontdir);
+ PACK_VECTOR(updir);
+ PACK_VECTOR(rightdir);
+
+ return 3;
+}
+
+
int LuaSyncedRead::GetUnitDirection(lua_State* L)
{
CUnit* unit = ParseInLosUnit(L, __FUNCTION__, 1);
@@ -2704,6 +2755,39 @@
}
+int LuaSyncedRead::GetUnitWeaponVectors(lua_State* L)
+{
+ CUnit* unit = ParseAllyUnit(L, __FUNCTION__, 1);
+ if (unit == NULL) {
+ return 0;
+ }
+ const int args = lua_gettop(L); // number of arguments
+ if ((args < 2) || !lua_isnumber(L, 2)) {
+ luaL_error(L, "Incorrect arguments to GetUnitWeaponVectors(unitID,weaponNum)");
+ }
+ const int weaponNum = (int)lua_tonumber(L, 2);
+ if ((weaponNum < 0) || (weaponNum >= unit->weapons.size())) {
+ return 0;
+ }
+ const float3& weaponPos = unit->weapons[weaponNum]->weaponMuzzlePos;
+ float3& weaponDir = unit->weapons[weaponNum]->wantedDir;
+ const string& wtype = unit->weapons[weaponNum]->weaponDef->type;
+
+ if (wtype=="StarburstLauncher" || wtype=="TorpedoLauncher" || wtype=="MissileLauncher")
+ weaponDir = unit->weapons[weaponNum]->weaponDir;
+
+ lua_pushnumber(L, weaponPos.x);
+ lua_pushnumber(L, weaponPos.y);
+ lua_pushnumber(L, weaponPos.z);
+
+ lua_pushnumber(L, weaponDir.x);
+ lua_pushnumber(L, weaponDir.y);
+ lua_pushnumber(L, weaponDir.z);
+
+ return 6;
+}
+
+
int LuaSyncedRead::GetUnitTravel(lua_State* L)
{
CUnit* unit = ParseAllyUnit(L, __FUNCTION__, 1);
Index: rts/Lua/LuaSyncedRead.h
===================================================================
--- rts/Lua/LuaSyncedRead.h (revision 5850)
+++ rts/Lua/LuaSyncedRead.h (working copy)
@@ -51,6 +51,7 @@
static int GetPlayerInfo(lua_State* L); // no name for synced scripts
static int GetPlayerControlledUnit(lua_State* L);
+ static int GetPlayerStats(lua_State* L);
static int GetTeamInfo(lua_State* L);
static int GetTeamResources(lua_State* L);
@@ -102,6 +103,7 @@
static int GetUnitRadius(lua_State* L);
static int GetUnitPosition(lua_State* L);
static int GetUnitBasePosition(lua_State* L);
+ static int GetUnitVectors(lua_State* L);
static int GetUnitDirection(lua_State* L);
static int GetUnitHeading(lua_State* L);
static int GetUnitVelocity(lua_State* L);
@@ -111,6 +113,7 @@
static int GetUnitIsTransporting(lua_State* L);
static int GetUnitShieldState(lua_State* L);
static int GetUnitWeaponState(lua_State* L);
+ static int GetUnitWeaponVectors(lua_State* L);
static int GetUnitTravel(lua_State* L);
static int GetUnitEstimatedPath(lua_State* L);
-
rendering.patch (90,543 bytes) 2008-05-10 16:29
Index: rts/Map/SM3/terrain/Lightcalc.cpp
===================================================================
--- rts/Map/SM3/terrain/Lightcalc.cpp (revision 5850)
+++ rts/Map/SM3/terrain/Lightcalc.cpp (working copy)
@@ -33,6 +33,7 @@
#include "Textures.h"
#include "Lightcalc.h"
#include "Map/ReadMap.h"
+#include "Rendering/GL/myGL.h"
#include <SDL.h>
#include <IL/il.h>
@@ -171,7 +172,7 @@
SaveImage ("lightmap.png", 4, IL_UNSIGNED_BYTE, w,w, shadingTexData);
- gluBuild2DMipmaps(GL_TEXTURE_2D, 4, w,w, GL_RGBA, GL_UNSIGNED_BYTE, shadingTexData);
+ glBuildMipmaps(GL_TEXTURE_2D, 4, w,w, GL_RGBA, GL_UNSIGNED_BYTE, shadingTexData);
delete[] shadingTexData;
id = shadingTex;
Index: rts/Map/SMF/BFGroundTextures.cpp
===================================================================
--- rts/Map/SMF/BFGroundTextures.cpp (revision 5850)
+++ rts/Map/SMF/BFGroundTextures.cpp (working copy)
@@ -9,11 +9,19 @@
#include "Platform/errorhandler.h"
#include "SmfReadMap.h"
#include "mmgr.h"
+#include "FastMath.h"
using namespace std;
CBFGroundTextures::CBFGroundTextures(CSmfReadMap* rm)
{
+ usePBO = false;
+ if (GLEW_EXT_pixel_buffer_object && rm->usePBO) {
+ glGenBuffers(30, pboIDs);
+ currentPBO=0;
+ usePBO = true;
+ }
+
CFileHandler* ifs = rm->ifs;
map = rm;
@@ -98,7 +106,6 @@
GroundSquare* square = &squares[y * numBigTexX + x];
square->texLevel = 1;
square->lastUsed = -100;
-
LoadSquare(x, y, 2);
}
}
@@ -111,6 +118,9 @@
delete[] squares;
delete[] tileMap;
delete[] tiles;
+ if (usePBO) {
+ glDeleteBuffers(30,pboIDs);
+ }
}
@@ -126,7 +136,7 @@
static const int heightDataX = gs->mapx + 1;
static const int bigTexW = (gs->mapx << 3) / numBigTexX;
static const int bigTexH = (gs->mapy << 3) / numBigTexY;
- static const float bigTexSquareRadius = sqrt(float(bigTexW * bigTexW + bigTexH * bigTexH));
+ static const float bigTexSquareRadius = fastmath::sqrt(float(bigTexW * bigTexW + bigTexH * bigTexH));
const int x = btx * bigTexW + (bigTexW >> 1);
const int y = bty * bigTexH + (bigTexH >> 1);
@@ -160,7 +170,7 @@
float dx = cam2->pos.x - x * bigSquareSize * SQUARE_SIZE - 64 * SQUARE_SIZE;
dx = max(0.0f, float(fabs(dx) - 64.0f * SQUARE_SIZE));
- float dist = sqrt(dx * dx + dy * dy);
+ float dist = fastmath::sqrt(dx * dx + dy * dy);
if (square->lastUsed < gs->frameNum - 60)
dist = 8000;
@@ -204,11 +214,29 @@
void CBFGroundTextures::LoadSquare(int x, int y, int level)
{
+ int size = 1024 >> level;
+
+ GLubyte* buf=NULL; bool usedPBO=false;
+
+ if (usePBO) {
+ if (currentPBO > 29) currentPBO=0;
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIDs[currentPBO++]);
+
+ glBufferData(GL_PIXEL_UNPACK_BUFFER, size * size / 2, 0, GL_STREAM_DRAW);
+
+ //map the buffer object into client's memory
+ buf = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
+ usedPBO = true;
+ }
+
+ if(buf==NULL) {
+ buf = SAFE_NEW GLubyte[size * size / 2];
+ usedPBO = false;
+ }
+
GroundSquare* square = &squares[y * numBigTexX + x];
square->texLevel = level;
- int size = 1024 >> level;
- char* buf = SAFE_NEW char[size * size / 2];
int numblocks = 8 / (1 << level);
for (int y1 = 0; y1 < 32; y1++) {
@@ -217,10 +245,11 @@
for (int yt = 0; yt < numblocks; yt++) {
for (int xt = 0; xt < numblocks; xt++) {
- char* sbuf = &tile[(xt + yt * numblocks) * 8];
- char* dbuf = &buf[(x1 * numblocks+xt + (y1 * numblocks + yt) * (numblocks * 32)) * 8];
+ GLfloat* sbuf = (GLfloat*)&tile[(xt + yt * numblocks) * 8];
+ GLfloat* dbuf = (GLfloat*)&buf[(x1 * numblocks + xt + (y1 * numblocks + yt) * (numblocks * 32)) * 8];
- for (int i = 0; i < 8; i++) {
+ //copy 4 bytes at once
+ for (int i = 0; i < 2; i++) {
dbuf[i] = sbuf[i];
}
}
@@ -234,12 +263,16 @@
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ if (map->anisotropy != 0.0f)
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, map->anisotropy);
- if (map->anisotropy != 0.0f) {
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, map->anisotropy);
+ if (usedPBO) {
+ glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, size, size, 0, size * size / 2, 0);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER, 0, 0, GL_STREAM_DRAW); //free it
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ }else{
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, size, size, 0, size * size / 2, buf);
+ delete[] buf;
}
-
- glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, size, size, 0, size * size / 2, buf);
-
- delete[] buf;
}
Index: rts/Map/SMF/BFGroundTextures.h
===================================================================
--- rts/Map/SMF/BFGroundTextures.h (revision 5850)
+++ rts/Map/SMF/BFGroundTextures.h (working copy)
@@ -52,6 +52,11 @@
int tileMapXSize;
int tileMapYSize;
+ // use Pixel Buffer Objects for async. uploading (DMA)?
+ bool usePBO;
+ GLuint pboIDs[30];
+ int currentPBO;
+
float anisotropy;
inline bool TexSquareInView(int, int);
Index: rts/Map/SMF/SmfReadMap.cpp
===================================================================
--- rts/Map/SMF/SmfReadMap.cpp (revision 5850)
+++ rts/Map/SMF/SmfReadMap.cpp (working copy)
@@ -34,6 +34,7 @@
PrintLoadMsg("Opening map file");
ConfigureAnisotropy();
+ usePBO = !!configHandler.GetInt("UsePBO", 1);
for(int a=0;a<1024;++a){
for(int b=0;b<3;++b){
@@ -104,7 +105,7 @@
glBindTexture(GL_TEXTURE_2D, detailTex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,bm.xsize, bm.ysize, GL_RGBA, GL_UNSIGNED_BYTE, bm.mem);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,bm.xsize, bm.ysize, GL_RGBA, GL_UNSIGNED_BYTE, bm.mem);
if (anisotropy != 0.0f) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
}
Index: rts/Map/SMF/SmfReadMap.h
===================================================================
--- rts/Map/SMF/SmfReadMap.h (revision 5850)
+++ rts/Map/SMF/SmfReadMap.h (working copy)
@@ -36,6 +36,7 @@
MapHeader header;
CFileHandler *ifs;
+ bool usePBO;
float anisotropy;
unsigned char waterHeightColors[1024*4];
Index: rts/Rendering/Env/AdvSky.cpp
===================================================================
--- rts/Rendering/Env/AdvSky.cpp (revision 5850)
+++ rts/Rendering/Env/AdvSky.cpp (working copy)
@@ -246,7 +246,7 @@
glBindTexture(GL_TEXTURE_2D, cdtex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR/*_MIPMAP_NEAREST*/);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_LUMINANCE ,256, 256, GL_LUMINANCE, GL_UNSIGNED_BYTE, mem);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_LUMINANCE ,256, 256, GL_LUMINANCE, GL_UNSIGNED_BYTE, mem);
unsigned char randDetailMatrix[32*32];
glGenTextures(12, detailTextures);
@@ -290,7 +290,7 @@
glBindTexture(GL_TEXTURE_2D, skyTex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,512, 512, GL_RGBA, GL_UNSIGNED_BYTE, skytex[0][0]);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,512, 512, GL_RGBA, GL_UNSIGNED_BYTE, skytex[0][0]);
delete[] skytex;
unsigned char skytex2[256][256][4];
@@ -311,7 +311,7 @@
glBindTexture(GL_TEXTURE_2D, skyDot3Tex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,256, 256, GL_RGBA, GL_UNSIGNED_BYTE, skytex2[0][0]);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,256, 256, GL_RGBA, GL_UNSIGNED_BYTE, skytex2[0][0]);
for(int a=0;a<CLOUD_DETAIL;a++){
CreateRandMatrix(randMatrix[a],1-a*0.03f);
@@ -660,7 +660,7 @@
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,128, 128, GL_RGBA, GL_UNSIGNED_BYTE, mem);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,128, 128, GL_RGBA, GL_UNSIGNED_BYTE, mem);
for(int y=0;y<4;++y){
for(int x=0;x<32;++x){
Index: rts/Rendering/Env/AdvTreeDrawer.cpp
===================================================================
--- rts/Rendering/Env/AdvTreeDrawer.cpp (revision 5850)
+++ rts/Rendering/Env/AdvTreeDrawer.cpp (working copy)
@@ -158,7 +158,7 @@
SetArray(TEX_LEAF_END_X1+xdif ,TEX_LEAF_END_Y4+ydif ,base-side*width+float3(0,height,0));
SetArray(TEX_LEAF_END_X1+xdif ,TEX_LEAF_START_Y4+ydif,base-side*width);
}
- glNewList(td->trees[y*treesX+x].farDisplist,GL_COMPILE);
+ glNewList(tss->farDisplist,GL_COMPILE);
va->DrawArrayT(GL_QUADS);
glEndList();
}
Index: rts/Rendering/Env/AdvTreeGenerator.cpp
===================================================================
--- rts/Rendering/Env/AdvTreeGenerator.cpp (revision 5850)
+++ rts/Rendering/Env/AdvTreeGenerator.cpp (working copy)
@@ -58,7 +58,7 @@
glBindTexture(GL_TEXTURE_2D, leafTex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,bm.xsize, bm.ysize, GL_RGBA, GL_UNSIGNED_BYTE, bm.mem);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,bm.xsize, bm.ysize, GL_RGBA, GL_UNSIGNED_BYTE, bm.mem);
CreateLeafTex(leafTex,256,0,tree);
CreateLeafTex(leafTex,512,0,tree);
Index: rts/Rendering/Env/BaseSky.cpp
===================================================================
--- rts/Rendering/Env/BaseSky.cpp (revision 5850)
+++ rts/Rendering/Env/BaseSky.cpp (working copy)
@@ -13,6 +13,7 @@
CBaseSky::CBaseSky(void)
{
+ wireframe = false;
}
CBaseSky::~CBaseSky(void)
Index: rts/Rendering/Env/BaseSky.h
===================================================================
--- rts/Rendering/Env/BaseSky.h (revision 5850)
+++ rts/Rendering/Env/BaseSky.h (working copy)
@@ -21,6 +21,8 @@
bool dynamicSky;
float cloudDensity;
+ bool wireframe;
+
float fogStart;
float3 skyColor;
float3 sunColor;
Index: rts/Rendering/Env/BasicSky.cpp
===================================================================
--- rts/Rendering/Env/BasicSky.cpp (revision 5850)
+++ rts/Rendering/Env/BasicSky.cpp (working copy)
@@ -75,6 +75,7 @@
glGetError();
displist=glGenLists(1);
glNewList(displist, GL_COMPILE);
+
glDisable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glDisable(GL_ALPHA_TEST);
@@ -245,6 +246,8 @@
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
+ if (wireframe) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
glPushMatrix();
// glTranslatef(camera->pos.x,camera->pos.y,camera->pos.z);
CMatrix44f m(camera->pos,sundir1,UpVector,sundir2);
@@ -257,8 +260,6 @@
glTranslatef((gs->frameNum%20000)*0.00005f+modCamera.x*0.000025f,modCamera.z*0.000025f,0);
glMatrixMode(GL_MODELVIEW);
-
-
glCallList(displist);
glMatrixMode(GL_TEXTURE); // Select The Projection Matrix
@@ -267,6 +268,8 @@
glPopMatrix();
+ if (wireframe) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
if (gu->drawFog) {
@@ -338,7 +341,7 @@
glBindTexture(GL_TEXTURE_2D, skyTex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,512, 512, GL_RGBA, GL_UNSIGNED_BYTE, skytex[0][0]);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,512, 512, GL_RGBA, GL_UNSIGNED_BYTE, skytex[0][0]);
// delete[] skytex;
for(y=0;y<256;y++){
@@ -359,7 +362,7 @@
glBindTexture(GL_TEXTURE_2D, skyDot3Tex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,256, 256, GL_RGBA, GL_UNSIGNED_BYTE, skytex2[0][0]);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,256, 256, GL_RGBA, GL_UNSIGNED_BYTE, skytex2[0][0]);
for(int a=0;a<CLOUD_DETAIL;a++){
CreateRandMatrix(randMatrix[a],1-a*0.03f);
@@ -685,7 +688,7 @@
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,128, 128, GL_RGBA, GL_UNSIGNED_BYTE, mem);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,128, 128, GL_RGBA, GL_UNSIGNED_BYTE, mem);
for(int y=0;y<2;++y){
for(int x=0;x<32;++x){
Index: rts/Rendering/Env/BasicTreeDrawer.cpp
===================================================================
--- rts/Rendering/Env/BasicTreeDrawer.cpp (revision 5850)
+++ rts/Rendering/Env/BasicTreeDrawer.cpp (working copy)
@@ -246,7 +246,7 @@
glCallList(tss->farDisplist);
}
- if(dist<SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance){ //midle distance trees
+ if(dist<SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance){ //middle distance trees
tss->lastSeen=gs->frameNum;
if(!tss->displist){
va=GetVertexArray();
@@ -376,52 +376,7 @@
glBindTexture(GL_TEXTURE_2D, texnum);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
- int mipnum=0;
- glTexImage2D(GL_TEXTURE_2D,mipnum,GL_RGBA8 ,xsize, ysize,0, GL_RGBA, GL_UNSIGNED_BYTE, data);
- while(xsize!=1 || ysize!=1){
- mipnum++;
- if(xsize!=1)
- xsize/=2;
- if(ysize!=1)
- ysize/=2;
- for(int y=0;y<ysize;++y){
- for(int x=0;x<xsize;++x){
-/* for(int a=0;a<3;a++){
- int temp=0;
- int num=0;
- if(data[(y*2*xsize*2+x*2)*4+3]){
- temp+=data[(y*2*xsize*2+x*2)*4+a];
- num++;
- }
- if(data[((y*2+1)*xsize*2+x*2)*4+3]){
- temp+=data[((y*2+1)*xsize*2+x*2)*4+a];
- num++;
- }
- if(data[((y*2)*xsize*2+x*2+1)*4+3]){
- temp+=data[((y*2)*xsize*2+x*2+1)*4+a];
- num++;
- }
- if(data[((y*2+1)*xsize*2+x*2+1)*4+3]){
- temp+=data[((y*2+1)*xsize*2+x*2+1)*4+a];
- num++;
- }
- if(num>1)
- temp/=num;
- data[(y*xsize+x)*4+a]=temp;
- }
-*/ data[(y*xsize+x)*4+0]=(data[(y*2*xsize*2+x*2)*4+0]+data[((y*2+1)*xsize*2+x*2)*4+0]+data[(y*2*xsize*2+x*2+1)*4+0]+data[((y*2+1)*xsize*2+x*2+1)*4+0])/4;
- data[(y*xsize+x)*4+1]=(data[(y*2*xsize*2+x*2)*4+1]+data[((y*2+1)*xsize*2+x*2)*4+1]+data[(y*2*xsize*2+x*2+1)*4+1]+data[((y*2+1)*xsize*2+x*2+1)*4+1])/4;
- data[(y*xsize+x)*4+2]=(data[(y*2*xsize*2+x*2)*4+2]+data[((y*2+1)*xsize*2+x*2)*4+2]+data[(y*2*xsize*2+x*2+1)*4+2]+data[((y*2+1)*xsize*2+x*2+1)*4+2])/4;
- data[(y*xsize+x)*4+3]=(data[(y*2*xsize*2+x*2)*4+3]+data[((y*2+1)*xsize*2+x*2)*4+3]+data[(y*2*xsize*2+x*2+1)*4+3]+data[((y*2+1)*xsize*2+x*2+1)*4+3])/4;
- if(data[(y*xsize+x)*4+3]>=127){
- data[(y*xsize+x)*4+3]=255;
- } else {
- data[(y*xsize+x)*4+3]=0;
- }
- }
- }
- glTexImage2D(GL_TEXTURE_2D,mipnum,GL_RGBA8 ,xsize, ysize,0, GL_RGBA, GL_UNSIGNED_BYTE, data);
- }
+ glBuildMipmaps(GL_TEXTURE_2D, GL_RGBA8, xsize, ysize, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
void CBasicTreeDrawer::ResetPos(const float3& pos)
Index: rts/Rendering/Env/BasicWater.cpp
===================================================================
--- rts/Rendering/Env/BasicWater.cpp (revision 5850)
+++ rts/Rendering/Env/BasicWater.cpp (working copy)
@@ -26,7 +26,7 @@
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,pic.xsize, pic.ysize, GL_RGBA, GL_UNSIGNED_BYTE, pic.mem);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,pic.xsize, pic.ysize, GL_RGBA, GL_UNSIGNED_BYTE, pic.mem);
displist=0;
Index: rts/Rendering/Env/DynWater.cpp
===================================================================
--- rts/Rendering/Env/DynWater.cpp (revision 5850)
+++ rts/Rendering/Env/DynWater.cpp (working copy)
@@ -8,6 +8,7 @@
#include "Map/MapInfo.h"
#include "Map/ReadMap.h"
#include "LogOutput.h"
+#include "bitops.h"
#include "Map/BaseGroundDrawer.h"
#include "Rendering/Env/BaseSky.h"
#include "Rendering/UnitModels/UnitDrawer.h"
@@ -80,18 +81,20 @@
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA16F_ARB ,64, 64, 0,GL_RGBA, GL_FLOAT, temp);
- unsigned char* scrap=SAFE_NEW unsigned char[256*256*4];
CBitmap foam;
- if (!foam.Load("bitmaps/foam.jpg") || foam.xsize != 256 || foam.ysize != 256)
- throw content_error("Could not load foam from file bitmaps/foam.jpg");
- for(int a=0;a<256*256;++a)
+ if (!foam.Load(mapInfo->water.foamTexture))
+ throw content_error("Could not load foam from file " + mapInfo->water.foamTexture);
+ if (count_bits_set(foam.xsize)!=1 || count_bits_set(foam.ysize)!=1)
+ throw content_error("Foam texture not power of two!");
+ unsigned char* scrap=SAFE_NEW unsigned char[foam.xsize*foam.ysize*4];
+ for(int a=0;a<foam.xsize*foam.ysize;++a)
scrap[a]=foam.mem[a*4];
glGenTextures(1, &foamTex);
glBindTexture(GL_TEXTURE_2D, foamTex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_LUMINANCE,256, 256, GL_LUMINANCE, GL_UNSIGNED_BYTE, scrap);
+ glBuildMipmaps(GL_TEXTURE_2D, GL_LUMINANCE,foam.xsize,foam.ysize, GL_LUMINANCE, GL_UNSIGNED_BYTE, scrap);
delete[] scrap;
@@ -331,7 +334,7 @@
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glDisable( GL_VERTEX_PROGRAM_ARB );
-
+/*
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D,0);
@@ -348,6 +351,7 @@
glActiveTextureARB(GL_TEXTURE7_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE0_ARB);
+ */
}
void CDynWater::UpdateWater(CGame* game)
Index: rts/Rendering/Env/GrassDrawer.cpp
===================================================================
--- rts/Rendering/Env/GrassDrawer.cpp (revision 5850)
+++ rts/Rendering/Env/GrassDrawer.cpp (working copy)
@@ -103,7 +103,7 @@
glBindTexture(GL_TEXTURE_2D, grassBladeTex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,256, 64, GL_RGBA, GL_UNSIGNED_BYTE, gbt);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,256, 64, GL_RGBA, GL_UNSIGNED_BYTE, gbt);
CreateFarTex();
@@ -759,7 +759,7 @@
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,1024*sizeMod, 64*sizeMod, GL_RGBA, GL_UNSIGNED_BYTE, buf);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,1024*sizeMod, 64*sizeMod, GL_RGBA, GL_UNSIGNED_BYTE, buf);
delete[] buf;
delete[] buf2;
Index: rts/Rendering/GL/myGL.cpp
===================================================================
--- rts/Rendering/GL/myGL.cpp (revision 5850)
+++ rts/Rendering/GL/myGL.cpp (working copy)
@@ -13,15 +13,16 @@
#include "FPUCheck.h"
#include <SDL.h>
#include "mmgr.h"
+#include "System/GlobalStuff.h"
#include "IFramebuffer.h"
using namespace std;
-static CVertexArray* vertexArray1 = 0;
-static CVertexArray* vertexArray2 = 0;
-static CVertexArray* currentVertexArray = 0;
+static CVertexArray* vertexArray1 = NULL;
+static CVertexArray* vertexArray2 = NULL;
+static CVertexArray* currentVertexArray = NULL;
static GLuint startupTexture = 0;
@@ -56,6 +57,24 @@
logOutput.Print("GL: %s\n", glGetString(GL_RENDERER));
logOutput.Print("GLEW: %s\n", glewGetString(GLEW_VERSION));
+ /* Get available fullscreen/hardware modes */
+/*
+ SDL_Rect **modes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_OPENGL|SDL_RESIZABLE);
+
+ if (modes == (SDL_Rect **)0) {
+ logOutput.Print("SDL_ListModes: No modes available!\n");
+ }else if (modes == (SDL_Rect **)-1) {
+ logOutput.Print("SDL_ListModes: Resolution is restricted.\n");
+ }else{
+ char buffer[512];
+ unsigned char n = 0;
+ for(int i=0;modes[i];++i) {
+ n += SNPRINTF(&buffer[n], 512-n, "%dx%d, ", modes[i]->w, modes[i]->h);
+ }
+ logOutput.Print("SDL_ListModes: %s\n",buffer);
+ }
+*/
+
if(!GLEW_ARB_multitexture || !GLEW_ARB_texture_env_combine){
handleerror(0,"Needed extension GL_ARB_texture_env_combine not found","Update drivers",0);
exit(0);
@@ -83,10 +102,41 @@
{
delete vertexArray1;
delete vertexArray2;
+}
+/******************************************************************************/
+
+void glBuildMipmaps(const GLenum target,GLint internalFormat,const GLsizei width,const GLsizei height,const GLenum format,const GLenum type,const void *data)
+{
+ if (gu->compressTextures) {
+ switch ( internalFormat ) {
+ case 3:
+ case GL_RGB8 :
+ case GL_RGB : internalFormat = GL_COMPRESSED_RGB_ARB; break;
+
+ case 4:
+ case GL_RGBA8 :
+ case GL_RGBA : internalFormat = GL_COMPRESSED_RGBA_ARB; break;
+
+ case GL_LUMINANCE: internalFormat = GL_COMPRESSED_LUMINANCE_ARB; break;
+ }
+ }
+
+ // create mipmapped texture
+ if (glGenerateMipmapEXT) {
+ //if (GLEW_EXT_framebuffer_object) { // Hurray (again), ATi only supports half of the extension
+ // newest method
+ glTexImage2D(target, 0, internalFormat, width, height, 0, format, type, data);
+ glGenerateMipmapEXT(GL_TEXTURE_2D);
+ }else if (GLEW_VERSION_1_4) {
+ // This required GL-1.4
+ // instead of using glu, we rely on glTexImage2D to create the Mipmaps.
+ glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAP,true);
+ glTexImage2D(target, 0, internalFormat, width, height, 0, format, type, data);
+ } else
+ gluBuild2DMipmaps(target, internalFormat, width, height, format, type, data);
}
-
/******************************************************************************/
static void AppendStringVec(vector<string>& dst, const vector<string>& src)
Index: rts/Rendering/GL/myGL.h
===================================================================
--- rts/Rendering/GL/myGL.h (revision 5850)
+++ rts/Rendering/GL/myGL.h (working copy)
@@ -27,9 +27,28 @@
glTranslatef(v.x,v.y,v.z);
}
+inline void glSecondaryColorf3(const float3& v)
+{
+ glSecondaryColor3f(v.x,v.y,v.z);
+}
+
+inline void glColorf4(const float3& v, const float& alpha)
+{
+ glColor4f(v.x,v.y,v.z,alpha);
+}
+
+inline void glUniformf3(const GLint& location, const float3 &v)
+{
+ glUniform3f(location, v.x,v.y,v.z);
+}
+
+
+void glBuildMipmaps(const GLenum target,GLint internalFormat,const GLsizei width,const GLsizei height,const GLenum format,const GLenum type,const void *data);
+
void LoadStartPicture(const std::string& sidePref);
void PrintLoadMsg(const char* text, bool swapbuffers = true);
void UnloadStartPicture();
+
bool ProgramStringIsNative(GLenum target, const char* filename);
unsigned int LoadVertexProgram(const char* filename);
unsigned int LoadFragmentProgram(const char* filename);
Index: rts/Rendering/glFont.cpp
===================================================================
--- rts/Rendering/glFont.cpp (revision 5850)
+++ rts/Rendering/glFont.cpp (working copy)
@@ -14,16 +14,20 @@
using namespace std;
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
+/*******************************************************************************/
+/*******************************************************************************/
CglFont *font, *smallFont;
+#define GLYPH_MARGIN 3 // margin between glyphs in texture-atlas
+
class texture_size_exception : public std::exception
{
};
+/*******************************************************************************/
+/*******************************************************************************/
+
/**
* A utility class for CglFont which collects all glyphs of
* a font into one square luminance/alpha texture.
@@ -82,15 +86,15 @@
}
outX = curX; outY = curY;
- curX += bmp.width + 1; // leave one pixel space between each glyph
- cur += 2*(bmp.width + 1);
+ curX += bmp.width + GLYPH_MARGIN; // leave one pixel space between each glyph
+ cur += 2*(bmp.width + GLYPH_MARGIN); // 2channels (luminance and alpha))
curHeight = max(curHeight, bmp.rows);
}
void CFontTextureRenderer::BreakLine()
{
curX = 0;
- curY += curHeight;
+ curY += curHeight + GLYPH_MARGIN;
curHeight = 0;
if (curY >= height)
Index: rts/Rendering/GroundDecalHandler.cpp
===================================================================
--- rts/Rendering/GroundDecalHandler.cpp (revision 5850)
+++ rts/Rendering/GroundDecalHandler.cpp (working copy)
@@ -49,7 +49,7 @@
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,512, 512, GL_RGBA, GL_UNSIGNED_BYTE, buf);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,512, 512, GL_RGBA, GL_UNSIGNED_BYTE, buf);
scarFieldX=gs->mapx/32;
scarFieldY=gs->mapy/32;
Index: rts/Rendering/InMapDraw.cpp
===================================================================
--- rts/Rendering/InMapDraw.cpp (revision 5850)
+++ rts/Rendering/InMapDraw.cpp (working copy)
@@ -124,7 +124,7 @@
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8, 128, 64, GL_RGBA, GL_UNSIGNED_BYTE, tex[0]);
+ glBuildMipmaps(GL_TEXTURE_2D, GL_RGBA8, 128, 64, GL_RGBA, GL_UNSIGNED_BYTE, tex[0]);
blippSound=sound->GetWaveId("sounds/beep6.wav");
}
Index: rts/Rendering/Textures/Bitmap.cpp
===================================================================
--- rts/Rendering/Textures/Bitmap.cpp (revision 5850)
+++ rts/Rendering/Textures/Bitmap.cpp (working copy)
@@ -343,14 +343,7 @@
{
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
- // create mipmapped texture
- if (GLEW_VERSION_1_4) {
- // This required GL-1.4
- // instead of using glu, we rely on glTexImage2D to create the Mipmaps.
- glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAP,true);
- glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8 ,xsize, ysize, 0,GL_RGBA, GL_UNSIGNED_BYTE, mem);
- } else
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,xsize, ysize,GL_RGBA, GL_UNSIGNED_BYTE, mem);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,xsize, ysize,GL_RGBA, GL_UNSIGNED_BYTE, mem);
}
else
{
@@ -380,6 +373,7 @@
case nv_dds::TextureFlat: // 1D, 2D, and rectangle textures
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texobj);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
if(!ddsimage->upload_texture2D()) {
glDeleteTextures(1, &texobj);
texobj = 0;
Index: rts/Rendering/Textures/NamedTextures.cpp
===================================================================
--- rts/Rendering/Textures/NamedTextures.cpp (revision 5850)
+++ rts/Rendering/Textures/NamedTextures.cpp (working copy)
@@ -138,7 +138,7 @@
GL_RGBA, GL_UNSIGNED_BYTE, bitmap.mem);
} else {
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8, bitmap.xsize, bitmap.ysize,
- GL_RGBA, GL_UNSIGNED_BYTE, bitmap.mem);
+ GL_RGBA, GL_UNSIGNED_BYTE, bitmap.mem); // make power of two!
}
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -147,8 +147,9 @@
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8, bitmap.xsize, bitmap.ysize,
- GL_RGBA, GL_UNSIGNED_BYTE, bitmap.mem);
+
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,bitmap.xsize, bitmap.ysize, GL_RGBA, GL_UNSIGNED_BYTE, bitmap.mem);
+
}
if (aniso && GLEW_EXT_texture_filter_anisotropic) {
Index: rts/Rendering/Textures/TextureAtlas.cpp
===================================================================
--- rts/Rendering/Textures/TextureAtlas.cpp (revision 5850)
+++ rts/Rendering/Textures/TextureAtlas.cpp (working copy)
@@ -9,6 +9,9 @@
CR_BIND(AtlasedTexture, );
CR_BIND_DERIVED(GroundFXTexture, AtlasedTexture, );
+//texture spacing in the atlas (in pixels)
+#define TEXMARGIN 1
+
bool CTextureAtlas::debug;
CTextureAtlas::CTextureAtlas(int maxxsize, int maxysize)
@@ -99,7 +102,7 @@
if(maxy>ysize){
if(IncreaseSize())
{
- nextSub.clear();
+ nextSub.clear();
thisSub.clear();
cury=maxy=curx=0;
recalc=true;
@@ -131,11 +134,11 @@
done=true;
- if(thisSub.front().y+curtex->ysize<maxy){
- nextSub.push_back(int2(thisSub.front().x,thisSub.front().y+curtex->ysize));
+ if(thisSub.front().y+curtex->ysize+TEXMARGIN<maxy){
+ nextSub.push_back(int2(thisSub.front().x+TEXMARGIN,thisSub.front().y+curtex->ysize+TEXMARGIN));
}
- thisSub.front().x+=curtex->xsize;
+ thisSub.front().x+=curtex->xsize+TEXMARGIN;
while(thisSub.size()>1 && thisSub.front().x >= (++thisSub.begin())->x){
(++thisSub.begin())->x=thisSub.front().x;
thisSub.erase(thisSub.begin());
@@ -179,54 +182,17 @@
{
unsigned char *data;
- //for(int i=0,xmip=0,ymip=0; (xsize>>i) || (ysize>>i); i++)
- //{
- // data[i] = SAFE_NEW unsigned char[(xsize>>xmip)*(ysize>>ymip)*4];
-
- // xmip = (xsize>>i)>1 ? xmip+=1 : xmip;
- // ymip = (ysize>>i)>1 ? ymip+=1 : ymip;
- //}
-
- //for(int i=0; i<memtextures.size(); i++)
- //{
- // MemTex *tex = memtextures[i];
- // for(int mip=0,xmip=0,ymip=0; (tex->xsize>>mip) || (tex->ysize>>mip); mip++)
- // {
- // unsigned char *mipcell;
-
- // if(mip==0)
- // mipcell = (unsigned char*)tex->data;
- // else
- // {
- // mipcell = SAFE_NEW unsigned char[(tex->xsize>>xmip)*(tex->ysize>>ymip)*4];
- // gluScaleImage(GL_RGBA, tex->xsize, tex->ysize, GL_UNSIGNED_BYTE, tex->data, (tex->xsize>>xmip), (tex->ysize>>ymip), GL_UNSIGNED_BYTE, mipcell);
- // }
-
- // for(int x=0; x<tex->xsize>>xmip; x++)
- // {
- // for(int y=0; y<tex->ysize>>ymip; y++)
- // {
- // ((int*)data[mip])[(tex->xpos>>xmip)+x+((tex->ypos>>ymip)+y)*(xsize>>mip)] = ((int*)mipcell)[x+y*(tex->xsize>>xmip)];
- // }
- // }
-
- // if(mip)
- // delete [] mipcell;
- // xmip = (xsize>>mip)>1 ? xmip+=1 : xmip;
- // ymip = (ysize>>mip)>1 ? ymip+=1 : ymip;
- // }
- //}
-
data = SAFE_NEW unsigned char[xsize*ysize*4];
+ memset(data,0,xsize*ysize*4); // make spacing between textures black transparent to avoid ugly lines with linear filtering
for(int i=0; i<memtextures.size(); i++)
{
MemTex *tex = memtextures[i];
- for(int x=0; x<tex->xsize; x++)
- for(int y=0; y<tex->ysize; y++)
- {
+ for(int x=0; x<tex->xsize; x++) {
+ for(int y=0; y<tex->ysize; y++) {
((int*)data)[tex->xpos+x+(tex->ypos+y)*xsize] = ((int*)tex->data)[x+y*tex->xsize];
}
+ }
}
if (debug) {
@@ -248,20 +214,18 @@
glBindTexture(GL_TEXTURE_2D, gltex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,/*GL_NEAREST_MIPMAP_LINEAR*/GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
+ if (GLEW_EXT_texture_edge_clamp) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ } else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ }
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,xsize, ysize, GL_RGBA, GL_UNSIGNED_BYTE, data);
+ glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,xsize, ysize, GL_RGBA, GL_UNSIGNED_BYTE, data);
delete [] data;
- //for(int i=0; (xsize>>i) || (ysize>>i); i++)
- //{
- // glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, xsize>>i, ysize>>i, 0, GL_RGBA, GL_UNSIGNED_BYTE, data[i]);
- // delete [] data[i];
- //}
-
-
initialized=true;
}
Index: rts/Rendering/Textures/TextureHandler.cpp
===================================================================
--- rts/Rendering/Textures/TextureHandler.cpp (revision 5850)
+++ rts/Rendering/Textures/TextureHandler.cpp (working copy)
@@ -210,7 +210,8 @@
glBindTexture(GL_TEXTURE_2D, globalTex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR/*_MIPMAP_NEAREST*/);
- gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,bigTexX, bigTexY, GL_RGBA, GL_UNSIGNED_BYTE, tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8 ,bigTexX, bigTexY, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex);
+ //glBuildMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,bigTexX, bigTexY, GL_RGBA, GL_UNSIGNED_BYTE, tex);
// CBitmap save(tex,bigTexX,bigTexY);
//save.Save("unittex-1x.jpg");
Index: rts/Rendering/UnitModels/3DModelParser.cpp
===================================================================
--- rts/Rendering/UnitModels/3DModelParser.cpp (revision 5850)
+++ rts/Rendering/UnitModels/3DModelParser.cpp (working copy)
@@ -352,9 +352,9 @@
glTranslatef(offset.x, offset.y, offset.z);
if (anim) {
- glTranslatef(-anim->coords[0] / CORDDIV,
- anim->coords[1] / CORDDIV,
- anim->coords[2] / CORDDIV);
+ glTranslatef(anim->coords[0] / CORDDIV,
+ anim->coords[1] / CORDDIV,
+ anim->coords[2] / CORDDIV);
if (anim->rot[1]) { glRotatef( anim->rot[1] / ANGDIV, 0.0f, 1.0f, 0.0f); }
if (anim->rot[0]) { glRotatef( anim->rot[0] / ANGDIV, 1.0f, 0.0f, 0.0f); }
if (anim->rot[2]) { glRotatef(-anim->rot[2] / ANGDIV, 0.0f, 0.0f, 1.0f); }
Index: rts/Rendering/UnitModels/UnitDrawer.cpp
===================================================================
--- rts/Rendering/UnitModels/UnitDrawer.cpp (revision 5850)
+++ rts/Rendering/UnitModels/UnitDrawer.cpp (working copy)
@@ -1810,16 +1810,16 @@
const double plane0[4] = {0, -1, 0 , start + height * (unit->buildProgress * 3 - 2)};
glClipPlane(GL_CLIP_PLANE0, plane0);
- if (shadowHandler->drawShadows && !water->drawReflection) {
+ //if (shadowHandler->drawShadows && !water->drawReflection) {
glPolygonOffset(1.0f, 1.0f);
glEnable(GL_POLYGON_OFFSET_FILL);
- }
+ //}
DrawUnitModel(unit);
- if (shadowHandler->drawShadows && !water->drawReflection) {
+ //if (shadowHandler->drawShadows && !water->drawReflection) {
glDisable(GL_POLYGON_OFFSET_FILL);
- }
+ //}
}
glDisable(GL_CLIP_PLANE0);
Index: rts/Sim/Projectiles/ProjectileHandler.cpp
===================================================================
--- rts/Sim/Projectiles/ProjectileHandler.cpp (revision 5850)
+++ rts/Sim/Projectiles/ProjectileHandler.cpp (working copy)
@@ -93,7 +93,7 @@
for (int i = 0; i < 12; i++) {
char num[10];
sprintf(num, "%02i", i);
- textureAtlas->AddTexFromFile(std::string("ismoke") + num, std::string("bitmaps/")+resources.SGetValueDef(std::string("smoke/smoke") + num +".tga",std::string("resources\\graphics\\smoke\\smoke")+num+"alpha"));
+ textureAtlas->AddTexFromFile(std::string("ismoke") + num, std::string("bitmaps/")+resources.SGetValueDef(std::string("smoke/smoke") + num +".tga",std::string("resources\\graphics\\smoke\\smoke")+num));
blockMapTexNames.insert(std::string("ismoke") + num);
}
@@ -240,7 +240,7 @@
glBindTexture(GL_TEXTURE_2D, perlinTex[a]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
- gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8,16, 16, GL_RGBA, GL_UNSIGNED_BYTE, tempmem);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16,16, 0, GL_RGBA, GL_UNSIGNED_BYTE, tempmem);
}
drawPerlinTex=false;
Index: rts/System/GlobalStuff.cpp
===================================================================
--- rts/System/GlobalStuff.cpp (revision 5850)
+++ rts/System/GlobalStuff.cpp (working copy)
@@ -218,6 +218,7 @@
viewRange=MAX_VIEW_RANGE;
timeOffset=0;
drawFog=true;
+ compressTextures=false;
teamNanospray=false;
autoQuit=false;
quitTime=0;
Index: rts/System/GlobalStuff.h
===================================================================
--- rts/System/GlobalStuff.h (revision 5850)
+++ rts/System/GlobalStuff.h (working copy)
@@ -442,7 +442,7 @@
public:
CR_DECLARE(CGlobalUnsyncedStuff);
CGlobalUnsyncedStuff(); //!< Constructor
- ~CGlobalUnsyncedStuff(); //!< Destructor
+ ~CGlobalUnsyncedStuff(); //!< Destructor
int usRandInt(); //!< Unsynced random int
float usRandFloat(); //!< Unsynced random float
@@ -586,6 +586,13 @@
* Whether fog (of war) is drawn or not
*/
bool drawFog;
+
+ /**
+ * @brief compressTextures
+ *
+ * If set, many (not all) textures will compressed on run-time.
+ */
+ bool compressTextures;
/**
* @brief quit automatically?
Index: rts/System/SpringApp.cpp
===================================================================
--- rts/System/SpringApp.cpp (revision 5850)
+++ rts/System/SpringApp.cpp (working copy)
@@ -1,987 +1,997 @@
-#include "StdAfx.h"
-#include "SpringApp.h"
-
-#include <signal.h>
-#include <SDL.h>
-#include <SDL_syswm.h>
-
-#include "Game/GameVersion.h"
-#include "Game/GameSetup.h"
-#include "Game/GameController.h"
-#include "Game/PreGame.h"
-#include "Game/Game.h"
-#include "Game/Team.h"
-#include "Game/UI/KeyBindings.h"
-#include "Lua/LuaGaia.h"
-#include "Lua/LuaRules.h"
-#include "Lua/LuaOpenGL.h"
-#include "Platform/BaseCmd.h"
-#include "Platform/ConfigHandler.h"
-#include "Platform/errorhandler.h"
-#include "Platform/FileSystem.h"
-#include "Rendering/glFont.h"
-#include "Rendering/GLContext.h"
-#include "Rendering/GL/myGL.h"
-#include "Rendering/VerticalSync.h"
-#include "Rendering/Textures/TAPalette.h"
-#include "Rendering/Textures/NamedTextures.h"
-#include "Rendering/Textures/TextureAtlas.h"
-#include "Sim/Projectiles/ExplosionGenerator.h"
-#include "LogOutput.h"
-#include "MouseInput.h"
-#include "bitops.h"
-#include "Sync/Syncify.h"
-
-#include "mmgr.h"
-
-#ifdef WIN32
-#ifdef __GNUC__
- #include "Platform/Win/CrashHandler.h"
-#endif
- #include "Platform/Win/win32.h"
- #include <winreg.h>
- #include <direct.h>
- #include "Platform/Win/seh.h"
-#endif // WIN32
-
-using std::string;
-
-CGameController* activeController = 0;
-bool globalQuit = false;
-Uint8 *keys = 0;
-bool fullscreen = true;
-char *win_lpCmdLine = 0;
-
-/**
- * @brief xres default
- *
- * Defines the default X resolution as 1024
- */
-const int XRES_DEFAULT = 1024;
-
-/**
- * @brief yres default
- *
- * Defines the default Y resolution as 768
- */
-const int YRES_DEFAULT = 768;
-
-void SpringApp::SigAbrtHandler(int unused)
-{
- // cause an exception if on windows
- // TODO FIXME do a proper stacktrace dump here
- #ifdef WIN32
- *((int*)(0)) = 0;
- #endif
-}
-
-/**
- * Initializes SpringApp variables
- */
-SpringApp::SpringApp ()
-{
- cmdline = 0;
- screenWidth = screenHeight = 0;
- FSAA = false;
-
- signal(SIGABRT, SigAbrtHandler);
-}
-
-/**
- * Destroys SpringApp variables
- */
-SpringApp::~SpringApp()
-{
- if (cmdline) delete cmdline;
- if (keys) delete[] keys;
-
- creg::System::FreeClasses ();
-}
-
-#ifdef _CRASHRPT_H_
-/**
- * @brief crash callback
- * @return whether callback was successful
- * @param crState current state
- *
- * Callback function executed when
- * game crashes (win32 only)
- */
-bool crashCallback(void* crState)
-{
- logOutput.RemoveAllSubscribers();
- logOutput.Print("Spring has crashed");
-
- // Stop writing to infolog.txt
- logOutput.End();
-
- // FIXME needs to be updated for new netcode
- //bool wasRecording = false;
- //if (net->recordDemo) {
- // delete net->recordDemo;
- // wasRecording = true;
- //}
-
- AddFile("infolog.txt", "Spring information log");
-
- //if (wasRecording)
- // AddFile(net->demoName.c_str(), "Spring game demo");
-
- SDL_Quit();
-
- return true;
-}
-#endif
-
-/**
- * @brief Initializes the SpringApp instance
- * @return whether initialization was successful
- */
-bool SpringApp::Initialize ()
-{
- logOutput.SetMirrorToStdout(!!configHandler.GetInt("StdoutDebug",0));
-
- // Initialize class system
- creg::System::InitializeClasses ();
-
- // Initialize crash reporting
-#ifdef _WIN32
-#if defined(_CRASHRPT_H_)
- Install( (LPGETLOGFILE) crashCallback, "taspringcrash@clan-sy.com", "Spring Crashreport");
- if (!GetInstance())
- {
- ErrorMessageBox("Error installing crash reporter", "CrashReport error:", MBF_OK);
- return false;
- }
-#elif defined(CRASHHANDLER_H)
- CrashHandler::Install();
-#endif
- InitializeSEH();
-#endif
-
- ParseCmdLine();
- FileSystemHandler::Initialize(true);
-
- if (!InitWindow(("Spring " + std::string(VERSION_STRING)).c_str())) {
- SDL_Quit();
- return false;
- }
-
- mouseInput = IMouseInput::Get ();
-
- // Global structures
- ENTER_SYNCED;
- gs=SAFE_NEW CGlobalSyncedStuff();
- ENTER_UNSYNCED;
- gu=SAFE_NEW CGlobalUnsyncedStuff();
-
- if (cmdline->result("minimise")) {
- gu->active = false;
- SDL_WM_IconifyWindow();
- }
-
- // Enable auto quit?
- int quit_time;
- if (cmdline->result("quit", quit_time)) {
- gu->autoQuit = true;
- gu->quitTime = quit_time;
- }
-
- InitOpenGL();
- palette.Init();
-
- // Initialize keyboard
- SDL_EnableUNICODE(1);
- SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
- SDL_SetModState (KMOD_NONE);
-
- keys = SAFE_NEW Uint8[SDLK_LAST];
- memset (keys,0,sizeof(Uint8)*SDLK_LAST);
-
- // Initialize font
- const int charFirst = configHandler.GetInt("FontCharFirst", 32);
- const int charLast = configHandler.GetInt("FontCharLast", 255);
- std::string fontFile = configHandler.GetString("FontFile", "fonts/Luxi.ttf");
-
- const float fontSize = 0.027f; // ~20 pixels at 1024x768
- const float smallFontSize = 0.016f; // ~12 pixels at 1024x768
-
- try {
- font = CglFont::TryConstructFont(fontFile, charFirst, charLast, fontSize);
- smallFont = CglFont::TryConstructFont(fontFile, charFirst, charLast, smallFontSize);
- } catch(content_error&) {
- // If the standard location fails, retry in fonts directory or vice versa.
- if (fontFile.substr(0, 6) == "fonts/")
- fontFile = fontFile.substr(6);
- else
- fontFile = "fonts/" + fontFile;
- font = CglFont::TryConstructFont(fontFile, charFirst, charLast, fontSize);
- smallFont = CglFont::TryConstructFont(fontFile, charFirst, charLast, smallFontSize);
- }
-
- // Initialize GLEW
- LoadExtensions();
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- SDL_GL_SwapBuffers();
-
- // Initialize named texture handler
- CNamedTextures::Init();
-
- // Initialize Lua GL
- LuaOpenGL::Init();
-
- // Create CGameSetup and CPreGame objects
- CreateGameSetup ();
-
- return true;
-}
-
-/**
- * @brief multisample test
- * @return whether the multisampling test was successful
- *
- * Tests if a user has requested FSAA, if it's a valid
- * FSAA mode, and if it's supported by the current GL context
- */
-static bool MultisampleTest(void)
-{
- if (!GL_ARB_multisample)
- return false;
- GLuint fsaa = configHandler.GetInt("FSAA",0);
- if (!fsaa)
- return false;
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,1);
- GLuint fsaalevel = std::max(std::min(configHandler.GetInt("FSAALevel", 2), 8), 0);
-
- make_even_number(fsaalevel);
-
- SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,fsaalevel);
- return true;
-}
-
-/**
- * @brief multisample verify
- * @return whether verification passed
- *
- * Tests whether FSAA was actually enabled
- */
-static bool MultisampleVerify(void)
-{
- GLint buffers, samples;
- glGetIntegerv(GL_SAMPLE_BUFFERS_ARB, &buffers);
- glGetIntegerv(GL_SAMPLES_ARB, &samples);
- if (buffers && samples) {
- return true;
- }
- return false;
-}
-
-
-/**
- * @return whether window initialization succeeded
- * @param title char* string with window title
- *
- * Initializes the game window
- */
-bool SpringApp::InitWindow (const char* title)
-{
- unsigned int sdlInitFlags = SDL_INIT_VIDEO | SDL_INIT_TIMER;
-#ifdef WIN32
- // the crash reporter should be catching the errors
- sdlInitFlags |= SDL_INIT_NOPARACHUTE;
-#endif
- if ((SDL_Init(sdlInitFlags) == -1)) {
- handleerror(NULL,"Could not initialize SDL.","ERROR",MBF_OK|MBF_EXCL);
- return false;
- }
-
- // Sets window manager properties
- SDL_WM_SetIcon(SDL_LoadBMP("spring.bmp"),NULL);
- SDL_WM_SetCaption(title, title);
-
- if (!SetSDLVideoMode ())
- return false;
-
- return true;
-}
-
-/**
- * @return whether setting the video mode was successful
- *
- * Sets SDL video mode options/settings
- */
-bool SpringApp::SetSDLVideoMode ()
-{
- int sdlflags = SDL_OPENGL | SDL_RESIZABLE;
-
- //conditionally_set_flag(sdlflags, SDL_FULLSCREEN, fullscreen);
- sdlflags |= fullscreen ? SDL_FULLSCREEN : 0;
-
- int bitsPerPixel = configHandler.GetInt("BitsPerPixel", 0);
-
- if (bitsPerPixel == 32)
- {
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); // enable alpha channel
- }
- else
- {
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
- // no alpha in 16bit mode
-
- if (bitsPerPixel != 16 && bitsPerPixel != 0)
- bitsPerPixel = 0; // it should be either 0, 16, or 32
- }
-
-#ifdef __APPLE__
- const int defaultDepthSize = 32;
-#else
- const int defaultDepthSize = 16;
-#endif
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, configHandler.GetInt("DepthBufferBits", defaultDepthSize));
- SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, configHandler.GetInt("StencilBufferBits", 1));
-
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
- FSAA = MultisampleTest();
-
- SDL_Surface *screen = SDL_SetVideoMode(screenWidth, screenHeight, bitsPerPixel, sdlflags);
- if (!screen) {
- char buf[1024];
- SNPRINTF(buf, sizeof(buf), "Could not set video mode:\n%s", SDL_GetError());
- handleerror(NULL, buf, "ERROR", MBF_OK|MBF_EXCL);
- return false;
- }
-
-#ifdef STREFLOP_H
- // Something in SDL_SetVideoMode (OpenGL drivers?) messes with the FPU control word.
- // Set single precision floating point math.
- streflop_init<streflop::Simple>();
-#endif
-
- if (FSAA) {
- FSAA = MultisampleVerify();
- }
-
- // setup GL smoothing
- const int defaultSmooth = 0; // FSAA ? 0 : 3; // until a few things get fixed
- const int lineSmoothing = configHandler.GetInt("SmoothLines", defaultSmooth);
- if (lineSmoothing > 0) {
- GLenum hint = GL_FASTEST;
- if (lineSmoothing >= 3) {
- hint = GL_NICEST;
- } else if (lineSmoothing >= 2) {
- hint = GL_DONT_CARE;
- }
- glEnable(GL_LINE_SMOOTH);
- glHint(GL_LINE_SMOOTH_HINT, hint);
- }
- const int pointSmoothing = configHandler.GetInt("SmoothPoints", defaultSmooth);
- if (pointSmoothing > 0) {
- GLenum hint = GL_FASTEST;
- if (pointSmoothing >= 3) {
- hint = GL_NICEST;
- } else if (pointSmoothing >= 2) {
- hint = GL_DONT_CARE;
- }
- glEnable(GL_POINT_SMOOTH);
- glHint(GL_POINT_SMOOTH_HINT, hint);
- }
-
- // there must be a way to see if this is necessary, compare old/new context pointers?
- if (!!configHandler.GetInt("FixAltTab", 0)) {
- // free GL resources
- GLContext::Free();
-
- // initialize any GL resources that were lost
- GLContext::Init();
- }
-
- // initialize the stencil
- glClearStencil(0);
- glClear(GL_STENCIL_BUFFER_BIT); SDL_GL_SwapBuffers();
- glClear(GL_STENCIL_BUFFER_BIT); SDL_GL_SwapBuffers();
-
- int bits;
- SDL_GL_GetAttribute(SDL_GL_BUFFER_SIZE, &bits);
- logOutput.Print("Video mode set to %i x %i / %i bit", screenWidth, screenHeight, bits );
- VSync.Init();
-
- return true;
-}
-
-
-// origin for our coordinates is the bottom left corner
-bool SpringApp::GetDisplayGeometry()
-{
- SDL_SysWMinfo info;
- SDL_VERSION(&info.version);
-
- if (!SDL_GetWMInfo(&info)) {
- return false;
- }
-
-#ifdef __APPLE__
- return false;
-#elif !defined(_WIN32)
- info.info.x11.lock_func();
- {
- Display* display = info.info.x11.display;
- Window window = info.info.x11.window;
-
- XWindowAttributes attrs;
- XGetWindowAttributes(display, window, &attrs);
- const Screen* screen = attrs.screen;
- gu->screenSizeX = WidthOfScreen(screen);
- gu->screenSizeY = HeightOfScreen(screen);
- gu->winSizeX = attrs.width;
- gu->winSizeY = attrs.height;
-
- Window tmp;
- int xp, yp;
- XTranslateCoordinates(display, window, attrs.root, 0, 0, &xp, &yp, &tmp);
- gu->winPosX = xp;
- gu->winPosY = gu->screenSizeY - gu->winSizeY - yp;
- }
- info.info.x11.unlock_func();
-#else
- gu->screenSizeX = GetSystemMetrics(SM_CXFULLSCREEN);
- gu->screenSizeY = GetSystemMetrics(SM_CYFULLSCREEN);
-
- RECT rect;
- if (!GetClientRect(info.window, &rect)) {
- return false;
- }
-
- if((rect.right - rect.left)==0 || (rect.bottom - rect.top)==0)
- return false;
-
- gu->winSizeX = rect.right - rect.left;
- gu->winSizeY = rect.bottom - rect.top;
-
- // translate from client coords to screen coords
- MapWindowPoints(info.window, HWND_DESKTOP, (LPPOINT)&rect, 2);
- gu->winPosX = rect.left;
- gu->winPosY = gu->screenSizeY - gu->winSizeY - rect.top;
-#endif // _WIN32
- return true;
-}
-
-
-void SpringApp::SetupViewportGeometry()
-{
- if (!GetDisplayGeometry()) {
- gu->screenSizeX = screenWidth;
- gu->screenSizeY = screenHeight;
- gu->winSizeX = screenWidth;
- gu->winSizeY = screenHeight;
- gu->winPosX = 0;
- gu->winPosY = 0;
- }
-
- gu->dualScreenMode = !!configHandler.GetInt("DualScreenMode", 0);
- if (gu->dualScreenMode) {
- gu->dualScreenMiniMapOnLeft =
- !!configHandler.GetInt("DualScreenMiniMapOnLeft", 0);
- } else {
- gu->dualScreenMiniMapOnLeft = false;
- }
-
- if (!gu->dualScreenMode) {
- gu->viewSizeX = gu->winSizeX;
- gu->viewSizeY = gu->winSizeY;
- gu->viewPosX = 0;
- gu->viewPosY = 0;
- }
- else {
- gu->viewSizeX = gu->winSizeX / 2;
- gu->viewSizeY = gu->winSizeY;
- if (gu->dualScreenMiniMapOnLeft) {
- gu->viewPosX = gu->winSizeX / 2;
- gu->viewPosY = 0;
- } else {
- gu->viewPosX = 0;
- gu->viewPosY = 0;
- }
- }
-
- gu->pixelX = 1.0f / (float)gu->viewSizeX;
- gu->pixelY = 1.0f / (float)gu->viewSizeY;
-
- // NOTE: gu->viewPosY is not currently used
-
- gu->aspectRatio = (float)gu->viewSizeX / (float)gu->viewSizeY;
-}
-
-
-/**
- * Initializes OpenGL
- */
-void SpringApp::InitOpenGL ()
-{
- SetupViewportGeometry();
-
- glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
-
- gluPerspective(45.0f, (GLfloat)gu->viewSizeX / (GLfloat)gu->viewSizeY, 2.8f, MAX_VIEW_RANGE);
-
- // Initialize some GL states
- glShadeModel(GL_SMOOTH);
- glClearDepth(1.0f);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
-}
-
-/**
- * @return whether commandline parsing was successful
- *
- * Parse command line arguments
- */
-void SpringApp::ParseCmdLine()
-{
- cmdline->addoption('f', "fullscreen", OPTPARM_NONE, "", "Run in fullscreen mode");
- cmdline->addoption('w', "window", OPTPARM_NONE, "", "Run in windowed mode");
- cmdline->addoption('x', "xresolution", OPTPARM_INT, "", "Set X resolution");
- cmdline->addoption('y', "yresolution", OPTPARM_INT, "", "Set Y resolution");
- cmdline->addoption('m', "minimise", OPTPARM_NONE, "", "Start minimised");
- cmdline->addoption('s', "server", OPTPARM_NONE, "", "Run as a server");
- cmdline->addoption('c', "client", OPTPARM_NONE, "", "Run as a client");
- cmdline->addoption('p', "projectiledump", OPTPARM_NONE, "", "Dump projectile class info in projectiles.txt");
- cmdline->addoption('t', "textureatlas", OPTPARM_NONE, "", "Dump each finalized textureatlas in textureatlasN.tga");
- cmdline->addoption('q', "quit", OPTPARM_INT, "T", "Quit immediately on game over or after T seconds");
- cmdline->addoption('n', "name", OPTPARM_STRING, "", "Set your player name");
- cmdline->parse();
-
-#ifdef _DEBUG
- fullscreen = false;
-#else
- fullscreen = configHandler.GetInt("Fullscreen", 1) != 0;
-#endif
-
- // mutually exclusive options that cause spring to quit immediately
- if (cmdline->result("help")) {
- cmdline->usage("Spring",VERSION_STRING);
- exit(0);
- } else if (cmdline->result("version")) {
- std::cout << "Spring " << VERSION_STRING << std::endl;
- exit(0);
- } else if (cmdline->result("projectiledump")) {
- CCustomExplosionGenerator::OutputProjectileClassInfo();
- exit(0);
- }
-
- // flags
- if (cmdline->result("window")) {
- fullscreen = false;
- } else if (cmdline->result("fullscreen")) {
- fullscreen = true;
- }
-
- if (cmdline->result("textureatlas")) {
- CTextureAtlas::debug = true;
- }
-
- string name;
- if (cmdline->result("name", name)) {
- configHandler.SetString("name", name);
- }
-
-
- if (!cmdline->result("xresolution", screenWidth)) {
- screenWidth = configHandler.GetInt("XResolution", XRES_DEFAULT);
- } else {
- screenWidth = std::max(screenWidth, 1);
- }
-
- if (!cmdline->result("yresolution", screenHeight)) {
- screenHeight = configHandler.GetInt("YResolution", YRES_DEFAULT);
- } else {
- screenHeight = std::max(screenHeight, 1);
- }
-
-}
-
-/**
- * @param argc argument count
- * @param argv array of argument strings
- *
- * Checks if a demo SDF file or a startscript has
- * been specified on the command line
- */
-void SpringApp::CheckCmdLineFile(int argc, char *argv[])
-{
- // Check if the commandline parameter is specifying a demo file
-#ifdef _WIN32
- // find the correct dir
- char exe[128];
- GetModuleFileName(0, exe, sizeof(exe));
- int a,s = strlen(exe);
- for (a=s-1;a>0;a--)
- // Running in gdb causes the last dir separator to be a forward slash.
- if (exe[a] == '\\' || exe[a] == '/') break;
- if (a > 0) {
- string path(exe, exe+a);
- if (path.at(0) == '"')
- path.append(1,'"');
- _chdir(path.c_str());
- }
-
- // If there are any options, they will start before the demo file name.
-
- if (win_lpCmdLine == 0)
- logOutput.Print("ERROR");
- string cmdLineStr = win_lpCmdLine;
- string::size_type offset = 0;
- //Simply assumes that any argument coming after a argument starting with /q is a variable to /q.
- for(int i=1; i < argc && (argv[i][0] == '/' || (argv[i-1][0] == '/' && (argv[i-1][1] == 'q' || argv[i-1][1] == 'a'))); i++){
- offset += strlen(argv[i]);
- offset = cmdLineStr.find_first_not_of(' ', offset);
- if(offset == string::npos)
- break;
- }
-
- string command;
- if(offset != string::npos)
- command = cmdLineStr.substr(offset);
-
-
- if (!command.empty()) {
- if (command[0] == '"' && *command.rbegin() == '"' && command.length() > 2)
- command = command.substr(1, command.length()-2);
- if (command.rfind("sdf") == command.size()-3) {
- demofile = command;
- logOutput << "Using demofile " << demofile.c_str() << "\n";
- } else if (command.rfind("ssf") == command.size()-3) {
- savefile = command;
- logOutput << "Using savefile " << savefile.c_str() << "\n";
- } else {
- startscript = command;
- logOutput << "Using script " << startscript.c_str() << "\n";
- }
- }
-#else
- // is there a reason for not using this in windows?
- for (int i = 1; i < argc; i++)
- if (argv[i][0] != '-')
- {
- string command(argv[i]);
- int idx = command.rfind("sdf");
- if (idx == command.size()-3) {
- demofile = command;
- logOutput << "Using demofile " << demofile.c_str() << "\n";
- } else if (command.rfind("ssf") == command.size()-3) {
- savefile = command;
- logOutput << "Using savefile " << savefile.c_str() << "\n";
- } else {
- startscript = command;
- logOutput << "Using script " << startscript.c_str() << "\n";
- }
- }
-#endif
-}
-
-/**
- * Initializes instance of GameSetup
- */
-void SpringApp::CreateGameSetup()
-{
- ENTER_SYNCED;
-
- if (!startscript.empty()) {
- gameSetup = SAFE_NEW CGameSetup();
- if (!gameSetup->Init(startscript)) {
- delete gameSetup;
- gameSetup = 0;
- }
- }
-
- if (!gameSetup && demofile.empty()) {
- gs->noHelperAIs = !!configHandler.GetInt("NoHelperAIs", 0);
- const string luaGaiaStr = configHandler.GetString("LuaGaia", "1");
- const string luaRulesStr = configHandler.GetString("LuaRules", "1");
- gs->useLuaGaia = CLuaGaia::SetConfigString(luaGaiaStr);
- gs->useLuaRules = CLuaRules::SetConfigString(luaRulesStr);
- if (gs->useLuaGaia) {
- gs->gaiaTeamID = gs->activeTeams;
- gs->gaiaAllyTeamID = gs->activeAllyTeams;
- gs->activeTeams++;
- gs->activeAllyTeams++;
- CTeam* team = gs->Team(gs->gaiaTeamID);
- team->color[0] = 255;
- team->color[1] = 255;
- team->color[2] = 255;
- team->color[3] = 255;
- team->gaia = true;
- gs->SetAllyTeam(gs->gaiaTeamID, gs->gaiaAllyTeamID);
- }
- }
-
- ENTER_MIXED;
-
- bool server = true;
-
- if (!demofile.empty()) {
- server = false;
- }
- else if (gameSetup) {
- // first real player is demo host
- server = (gameSetup->myPlayerNum == gameSetup->numDemoPlayers) && !cmdline->result("client");
- }
- else {
- server = !cmdline->result("client") || cmdline->result("server");
- }
-
-#ifdef SYNCDEBUG
- // initialize sync debugger as soon as we know whether we will be server
- CSyncDebugger::GetInstance()->Initialize(server);
-#endif
-
- if (!demofile.empty()) {
- pregame = SAFE_NEW CPreGame(false, demofile, "");
- } else {
- pregame = SAFE_NEW CPreGame(server, "", savefile);
- }
-}
-
-
-/**
- * @return return code of activecontroller draw function
- *
- * Draw function repeatedly called, it calls all the
- * other draw functions
- */
-int SpringApp::Update ()
-{
- if (FSAA)
- glEnable(GL_MULTISAMPLE_ARB);
-
- mouseInput->Update();
-
- int ret = 1;
- if (activeController) {
- if (!activeController->Update()) {
- ret = 0;
- } else {
- ret = activeController->Draw();
- }
- }
-
- VSync.Delay();
- SDL_GL_SwapBuffers();
-
- if (FSAA)
- glDisable(GL_MULTISAMPLE_ARB);
-
- return ret;
-}
-
-/**
- * Tests SDL keystates and sets values
- * in key array
- */
-void SpringApp::UpdateSDLKeys ()
-{
- int numkeys;
- Uint8 *state;
- state = SDL_GetKeyState(&numkeys);
- memcpy(keys, state, sizeof(Uint8) * numkeys);
-
- const SDLMod mods = SDL_GetModState();
- keys[SDLK_LALT] = (mods & KMOD_ALT) ? 1 : 0;
- keys[SDLK_LCTRL] = (mods & KMOD_CTRL) ? 1 : 0;
- keys[SDLK_LMETA] = (mods & KMOD_META) ? 1 : 0;
- keys[SDLK_LSHIFT] = (mods & KMOD_SHIFT) ? 1 : 0;
-}
-
-/**
- * @param argc argument count
- * @param argv array of argument strings
- *
- * Executes the application
- * (contains main game loop)
- */
-int SpringApp::Run (int argc, char *argv[])
-{
- INIT_SYNCIFY;
- CheckCmdLineFile (argc, argv);
- cmdline = BaseCmd::initialize(argc,argv);
-/*
- logOutput.Print ("Testing error catching");
- try {
- int *i_=0;
- *i_=1;
- logOutput.Print ("Error catching doesn't work!");
- } catch(...) {
- logOutput.Print ("Error catching works!");
- }
-*/
- if (!Initialize ())
- return -1;
-
-#ifdef WIN32
- SDL_EventState (SDL_SYSWMEVENT, SDL_ENABLE);
-#endif
-
- SDL_Event event;
- bool done = false;
-
- while (!done) {
- ENTER_UNSYNCED;
- while (SDL_PollEvent(&event)) {
- switch (event.type) {
- case SDL_VIDEORESIZE: {
- screenWidth = event.resize.w;
- screenHeight = event.resize.h;
-#ifndef WIN32
- // HACK We don't want to break resizing on windows (again?),
- // so someone should test this very well before enabling it.
- SetSDLVideoMode();
-#endif
- InitOpenGL();
- activeController->ResizeEvent();
- break;
- }
- case SDL_VIDEOEXPOSE: {
- // re-initialize the stencil
- glClearStencil(0);
- glClear(GL_STENCIL_BUFFER_BIT); SDL_GL_SwapBuffers();
- glClear(GL_STENCIL_BUFFER_BIT); SDL_GL_SwapBuffers();
- SetupViewportGeometry();
- break;
- }
- case SDL_QUIT: {
- done = true;
- break;
- }
- case SDL_ACTIVEEVENT: {
- if (event.active.state & SDL_APPACTIVE) {
- gu->active = !!event.active.gain;
- }
- break;
- }
- case SDL_MOUSEMOTION:
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
- case SDL_SYSWMEVENT: {
- mouseInput->HandleSDLMouseEvent (event);
- break;
- }
- case SDL_KEYDOWN: {
- int i = event.key.keysym.sym;
-
- const bool isRepeat = !!keys[i];
-
- UpdateSDLKeys ();
-
- if (activeController) {
- if (i <= SDLK_DELETE) {
- i = tolower(i);
- }
- else if (i == SDLK_RSHIFT) { i = SDLK_LSHIFT; }
- else if (i == SDLK_RCTRL) { i = SDLK_LCTRL; }
- else if (i == SDLK_RMETA) { i = SDLK_LMETA; }
- else if (i == SDLK_RALT) { i = SDLK_LALT; }
-
- if (keyBindings) {
- const int fakeMetaKey = keyBindings->GetFakeMetaKey();
- if (fakeMetaKey >= 0) {
- keys[SDLK_LMETA] |= keys[fakeMetaKey];
- }
- }
-
- activeController->KeyPressed(i, isRepeat);
-
- if (activeController->userWriting){
- // use unicode for printed characters
- i = event.key.keysym.unicode;
- if ((i >= SDLK_SPACE) && (i <= SDLK_DELETE)) {
- CGameController* ac = activeController;
- if (ac->ignoreNextChar || ac->ignoreChar == char(i)) {
- ac->ignoreNextChar = false;
- } else {
- if (i < SDLK_DELETE) {
- const int len = (int)ac->userInput.length();
- ac->writingPos = std::max(0, std::min(len, ac->writingPos));
- char str[2] = { char(i), 0 };
- ac->userInput.insert(ac->writingPos, str);
- ac->writingPos++;
- }
- }
- }
- }
- }
- activeController->ignoreNextChar = false;
- break;
- }
- case SDL_KEYUP: {
- int i = event.key.keysym.sym;
-
- UpdateSDLKeys();
-
- if (activeController) {
- if (i <= SDLK_DELETE) {
- i = tolower(i);
- }
- else if (i == SDLK_RSHIFT) { i = SDLK_LSHIFT; }
- else if (i == SDLK_RCTRL) { i = SDLK_LCTRL; }
- else if (i == SDLK_RMETA) { i = SDLK_LMETA; }
- else if (i == SDLK_RALT) { i = SDLK_LALT; }
-
- if (keyBindings) {
- const int fakeMetaKey = keyBindings->GetFakeMetaKey();
- if (fakeMetaKey >= 0) {
- keys[SDLK_LMETA] |= keys[fakeMetaKey];
- }
- }
-
- activeController->KeyReleased(i);
- }
- break;
- }
- default:
- break;
- }
- }
- if (globalQuit)
- break;
-
- if (!Update())
- break;
- }
- ENTER_MIXED;
-
- // Shutdown
- Shutdown();
- return 0;
-}
-
-/**
- * Deallocates and shuts down game
- */
-void SpringApp::Shutdown()
-{
- if (pregame)
- delete pregame; //in case we exit during init
- if (game)
- delete game;
- if (gameSetup)
- delete gameSetup;
- delete font;
- CNamedTextures::Kill();
- GLContext::Free();
- ConfigHandler::Deallocate();
- UnloadExtensions();
- delete mouseInput;
- SDL_WM_GrabInput(SDL_GRAB_OFF);
- SDL_Quit();
- delete gs;
- delete gu;
- END_SYNCIFY;
-#ifdef USE_MMGR
- m_dumpMemoryReport();
-#endif
-}
+#include "StdAfx.h"
+#include "SpringApp.h"
+
+#include <signal.h>
+#include <SDL.h>
+#include <SDL_syswm.h>
+
+#include "Game/GameVersion.h"
+#include "Game/GameSetup.h"
+#include "Game/GameController.h"
+#include "Game/PreGame.h"
+#include "Game/Game.h"
+#include "Game/Team.h"
+#include "Game/UI/KeyBindings.h"
+#include "Lua/LuaGaia.h"
+#include "Lua/LuaRules.h"
+#include "Lua/LuaOpenGL.h"
+#include "Platform/BaseCmd.h"
+#include "Platform/ConfigHandler.h"
+#include "Platform/errorhandler.h"
+#include "Platform/FileSystem.h"
+#include "Rendering/glFont.h"
+#include "Rendering/GLContext.h"
+#include "Rendering/GL/myGL.h"
+#include "Rendering/VerticalSync.h"
+#include "Rendering/Textures/TAPalette.h"
+#include "Rendering/Textures/NamedTextures.h"
+#include "Rendering/Textures/TextureAtlas.h"
+#include "Sim/Projectiles/ExplosionGenerator.h"
+#include "LogOutput.h"
+#include "MouseInput.h"
+#include "bitops.h"
+#include "Sync/Syncify.h"
+
+#include "mmgr.h"
+
+#ifdef WIN32
+#ifdef __GNUC__
+ #include "Platform/Win/CrashHandler.h"
+#endif
+ #include "Platform/Win/win32.h"
+ #include <winreg.h>
+ #include <direct.h>
+ #include "Platform/Win/seh.h"
+#endif // WIN32
+
+using std::string;
+
+CGameController* activeController = 0;
+bool globalQuit = false;
+Uint8 *keys = 0;
+bool fullscreen = true;
+char *win_lpCmdLine = 0;
+
+/**
+ * @brief xres default
+ *
+ * Defines the default X resolution as 1024
+ */
+const int XRES_DEFAULT = 1024;
+
+/**
+ * @brief yres default
+ *
+ * Defines the default Y resolution as 768
+ */
+const int YRES_DEFAULT = 768;
+
+void SpringApp::SigAbrtHandler(int unused)
+{
+ // cause an exception if on windows
+ // TODO FIXME do a proper stacktrace dump here
+ #ifdef WIN32
+ *((int*)(0)) = 0;
+ #endif
+}
+
+/**
+ * Initializes SpringApp variables
+ */
+SpringApp::SpringApp ()
+{
+ cmdline = 0;
+ screenWidth = screenHeight = 0;
+ FSAA = false;
+
+ signal(SIGABRT, SigAbrtHandler);
+}
+
+/**
+ * Destroys SpringApp variables
+ */
+SpringApp::~SpringApp()
+{
+ if (cmdline) delete cmdline;
+ if (keys) delete[] keys;
+
+ creg::System::FreeClasses ();
+}
+
+#ifdef _CRASHRPT_H_
+/**
+ * @brief crash callback
+ * @return whether callback was successful
+ * @param crState current state
+ *
+ * Callback function executed when
+ * game crashes (win32 only)
+ */
+bool crashCallback(void* crState)
+{
+ logOutput.RemoveAllSubscribers();
+ logOutput.Print("Spring has crashed");
+
+ // Stop writing to infolog.txt
+ logOutput.End();
+
+ // FIXME needs to be updated for new netcode
+ //bool wasRecording = false;
+ //if (net->recordDemo) {
+ // delete net->recordDemo;
+ // wasRecording = true;
+ //}
+
+ AddFile("infolog.txt", "Spring information log");
+
+ //if (wasRecording)
+ // AddFile(net->demoName.c_str(), "Spring game demo");
+
+ SDL_Quit();
+
+ return true;
+}
+#endif
+
+/**
+ * @brief Initializes the SpringApp instance
+ * @return whether initialization was successful
+ */
+bool SpringApp::Initialize ()
+{
+ logOutput.SetMirrorToStdout(!!configHandler.GetInt("StdoutDebug",0));
+
+ // Initialize class system
+ creg::System::InitializeClasses ();
+
+ // Initialize crash reporting
+#ifdef _WIN32
+#if defined(_CRASHRPT_H_)
+ Install( (LPGETLOGFILE) crashCallback, "taspringcrash@clan-sy.com", "Spring Crashreport");
+ if (!GetInstance())
+ {
+ ErrorMessageBox("Error installing crash reporter", "CrashReport error:", MBF_OK);
+ return false;
+ }
+#elif defined(CRASHHANDLER_H)
+ CrashHandler::Install();
+#endif
+ InitializeSEH();
+#endif
+
+ ParseCmdLine();
+ FileSystemHandler::Initialize(true);
+
+ if (!InitWindow(("Spring " + std::string(VERSION_STRING)).c_str())) {
+ SDL_Quit();
+ return false;
+ }
+
+ mouseInput = IMouseInput::Get ();
+
+ // Global structures
+ ENTER_SYNCED;
+ gs=SAFE_NEW CGlobalSyncedStuff();
+ ENTER_UNSYNCED;
+ gu=SAFE_NEW CGlobalUnsyncedStuff();
+
+ if (cmdline->result("minimise")) {
+ gu->active = false;
+ SDL_WM_IconifyWindow();
+ }
+
+ // Enable auto quit?
+ int quit_time;
+ if (cmdline->result("quit", quit_time)) {
+ gu->autoQuit = true;
+ gu->quitTime = quit_time;
+ }
+
+ InitOpenGL();
+ palette.Init();
+
+ // Initialize keyboard
+ SDL_EnableUNICODE(1);
+ SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+ SDL_SetModState (KMOD_NONE);
+
+ keys = SAFE_NEW Uint8[SDLK_LAST];
+ memset (keys,0,sizeof(Uint8)*SDLK_LAST);
+
+ // Initialize font
+ const int charFirst = configHandler.GetInt("FontCharFirst", 32);
+ const int charLast = configHandler.GetInt("FontCharLast", 255);
+ std::string fontFile = configHandler.GetString("FontFile", "fonts/Luxi.ttf");
+
+ const float fontSize = 0.027f; // ~20 pixels at 1024x768
+ const float smallFontSize = 0.016f; // ~12 pixels at 1024x768
+
+ try {
+ font = CglFont::TryConstructFont(fontFile, charFirst, charLast, fontSize);
+ smallFont = CglFont::TryConstructFont(fontFile, charFirst, charLast, smallFontSize);
+ } catch(content_error&) {
+ // If the standard location fails, retry in fonts directory or vice versa.
+ if (fontFile.substr(0, 6) == "fonts/")
+ fontFile = fontFile.substr(6);
+ else
+ fontFile = "fonts/" + fontFile;
+ font = CglFont::TryConstructFont(fontFile, charFirst, charLast, fontSize);
+ smallFont = CglFont::TryConstructFont(fontFile, charFirst, charLast, smallFontSize);
+ }
+
+ // Initialize GLEW
+ LoadExtensions();
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ SDL_GL_SwapBuffers();
+
+ // Runtime compress textures?
+ if (GLEW_ARB_texture_compression) // we don't even need to check it, 'cos groundtextures must have that extension
+ gu->compressTextures = !!configHandler.GetInt("CompressTextures", 1);
+
+ // Initialize named texture handler
+ CNamedTextures::Init();
+
+ // Initialize Lua GL
+ LuaOpenGL::Init();
+
+ // Create CGameSetup and CPreGame objects
+ CreateGameSetup ();
+
+ return true;
+}
+
+/**
+ * @brief multisample test
+ * @return whether the multisampling test was successful
+ *
+ * Tests if a user has requested FSAA, if it's a valid
+ * FSAA mode, and if it's supported by the current GL context
+ */
+static bool MultisampleTest(void)
+{
+ if (!GL_ARB_multisample)
+ return false;
+ GLuint fsaa = configHandler.GetInt("FSAA",0);
+ if (!fsaa)
+ return false;
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,1);
+ GLuint fsaalevel = std::max(std::min(configHandler.GetInt("FSAALevel", 2), 8), 0);
+
+ make_even_number(fsaalevel);
+
+ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,fsaalevel);
+ return true;
+}
+
+/**
+ * @brief multisample verify
+ * @return whether verification passed
+ *
+ * Tests whether FSAA was actually enabled
+ */
+static bool MultisampleVerify(void)
+{
+ GLint buffers, samples;
+ glGetIntegerv(GL_SAMPLE_BUFFERS_ARB, &buffers);
+ glGetIntegerv(GL_SAMPLES_ARB, &samples);
+ if (buffers && samples) {
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ * @return whether window initialization succeeded
+ * @param title char* string with window title
+ *
+ * Initializes the game window
+ */
+bool SpringApp::InitWindow (const char* title)
+{
+ unsigned int sdlInitFlags = SDL_INIT_VIDEO | SDL_INIT_TIMER;
+#ifdef WIN32
+ // the crash reporter should be catching the errors
+ sdlInitFlags |= SDL_INIT_NOPARACHUTE;
+#endif
+ if ((SDL_Init(sdlInitFlags) == -1)) {
+ handleerror(NULL,"Could not initialize SDL.","ERROR",MBF_OK|MBF_EXCL);
+ return false;
+ }
+
+ // Sets window manager properties
+ SDL_WM_SetIcon(SDL_LoadBMP("spring.bmp"),NULL);
+ SDL_WM_SetCaption(title, title);
+
+ if (!SetSDLVideoMode ())
+ return false;
+
+ return true;
+}
+
+/**
+ * @return whether setting the video mode was successful
+ *
+ * Sets SDL video mode options/settings
+ */
+bool SpringApp::SetSDLVideoMode ()
+{
+ int sdlflags = SDL_OPENGL | SDL_RESIZABLE;
+
+ //conditionally_set_flag(sdlflags, SDL_FULLSCREEN, fullscreen);
+ sdlflags |= fullscreen ? SDL_FULLSCREEN : 0;
+
+ int bitsPerPixel = configHandler.GetInt("BitsPerPixel", 0);
+
+ if (bitsPerPixel == 32)
+ {
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); // enable alpha channel
+ }
+ else
+ {
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+ // no alpha in 16bit mode
+
+ if (bitsPerPixel != 16 && bitsPerPixel != 0)
+ bitsPerPixel = 0; // it should be either 0, 16, or 32
+ }
+
+#ifdef __APPLE__
+ const int defaultDepthSize = 32;
+#else
+ const int defaultDepthSize = 16;
+#endif
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, configHandler.GetInt("DepthBufferBits", defaultDepthSize));
+ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, configHandler.GetInt("StencilBufferBits", 1));
+
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ FSAA = MultisampleTest();
+
+ SDL_Surface *screen = SDL_SetVideoMode(screenWidth, screenHeight, bitsPerPixel, sdlflags);
+ if (!screen) {
+ char buf[1024];
+ SNPRINTF(buf, sizeof(buf), "Could not set video mode:\n%s", SDL_GetError());
+ handleerror(NULL, buf, "ERROR", MBF_OK|MBF_EXCL);
+ return false;
+ }
+
+#ifdef STREFLOP_H
+ // Something in SDL_SetVideoMode (OpenGL drivers?) messes with the FPU control word.
+ // Set single precision floating point math.
+ streflop_init<streflop::Simple>();
+#endif
+
+ if (FSAA) {
+ FSAA = MultisampleVerify();
+ }
+
+ // setup GL smoothing
+ const int defaultSmooth = 0; // FSAA ? 0 : 3; // until a few things get fixed
+ const int lineSmoothing = configHandler.GetInt("SmoothLines", defaultSmooth);
+ if (lineSmoothing > 0) {
+ GLenum hint = GL_FASTEST;
+ if (lineSmoothing >= 3) {
+ hint = GL_NICEST;
+ } else if (lineSmoothing >= 2) {
+ hint = GL_DONT_CARE;
+ }
+ glEnable(GL_LINE_SMOOTH);
+ glHint(GL_LINE_SMOOTH_HINT, hint);
+ }
+ const int pointSmoothing = configHandler.GetInt("SmoothPoints", defaultSmooth);
+ if (pointSmoothing > 0) {
+ GLenum hint = GL_FASTEST;
+ if (pointSmoothing >= 3) {
+ hint = GL_NICEST;
+ } else if (pointSmoothing >= 2) {
+ hint = GL_DONT_CARE;
+ }
+ glEnable(GL_POINT_SMOOTH);
+ glHint(GL_POINT_SMOOTH_HINT, hint);
+ }
+
+ // setup LOD bias factor
+ const float lodBias = std::max(std::min( configHandler.GetFloat("TextureLODBias", 0.0f) , 4.0f), -4.0f);
+ if (fabs(lodBias)>0.01f) {
+ glTexEnvf(GL_TEXTURE_FILTER_CONTROL,GL_TEXTURE_LOD_BIAS, lodBias );
+ }
+
+ // there must be a way to see if this is necessary, compare old/new context pointers?
+ if (!!configHandler.GetInt("FixAltTab", 0)) {
+ // free GL resources
+ GLContext::Free();
+
+ // initialize any GL resources that were lost
+ GLContext::Init();
+ }
+
+ // initialize the stencil
+ glClearStencil(0);
+ glClear(GL_STENCIL_BUFFER_BIT); SDL_GL_SwapBuffers();
+ glClear(GL_STENCIL_BUFFER_BIT); SDL_GL_SwapBuffers();
+
+ int bits;
+ SDL_GL_GetAttribute(SDL_GL_BUFFER_SIZE, &bits);
+ logOutput.Print("Video mode set to %i x %i / %i bit", screenWidth, screenHeight, bits );
+ VSync.Init();
+
+ return true;
+}
+
+
+// origin for our coordinates is the bottom left corner
+bool SpringApp::GetDisplayGeometry()
+{
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+
+ if (!SDL_GetWMInfo(&info)) {
+ return false;
+ }
+
+#ifdef __APPLE__
+ return false;
+#elif !defined(_WIN32)
+ info.info.x11.lock_func();
+ {
+ Display* display = info.info.x11.display;
+ Window window = info.info.x11.window;
+
+ XWindowAttributes attrs;
+ XGetWindowAttributes(display, window, &attrs);
+ const Screen* screen = attrs.screen;
+ gu->screenSizeX = WidthOfScreen(screen);
+ gu->screenSizeY = HeightOfScreen(screen);
+ gu->winSizeX = attrs.width;
+ gu->winSizeY = attrs.height;
+
+ Window tmp;
+ int xp, yp;
+ XTranslateCoordinates(display, window, attrs.root, 0, 0, &xp, &yp, &tmp);
+ gu->winPosX = xp;
+ gu->winPosY = gu->screenSizeY - gu->winSizeY - yp;
+ }
+ info.info.x11.unlock_func();
+#else
+ gu->screenSizeX = GetSystemMetrics(SM_CXFULLSCREEN);
+ gu->screenSizeY = GetSystemMetrics(SM_CYFULLSCREEN);
+
+ RECT rect;
+ if (!GetClientRect(info.window, &rect)) {
+ return false;
+ }
+
+ if((rect.right - rect.left)==0 || (rect.bottom - rect.top)==0)
+ return false;
+
+ gu->winSizeX = rect.right - rect.left;
+ gu->winSizeY = rect.bottom - rect.top;
+
+ // translate from client coords to screen coords
+ MapWindowPoints(info.window, HWND_DESKTOP, (LPPOINT)&rect, 2);
+ gu->winPosX = rect.left;
+ gu->winPosY = gu->screenSizeY - gu->winSizeY - rect.top;
+#endif // _WIN32
+ return true;
+}
+
+
+void SpringApp::SetupViewportGeometry()
+{
+ if (!GetDisplayGeometry()) {
+ gu->screenSizeX = screenWidth;
+ gu->screenSizeY = screenHeight;
+ gu->winSizeX = screenWidth;
+ gu->winSizeY = screenHeight;
+ gu->winPosX = 0;
+ gu->winPosY = 0;
+ }
+
+ gu->dualScreenMode = !!configHandler.GetInt("DualScreenMode", 0);
+ if (gu->dualScreenMode) {
+ gu->dualScreenMiniMapOnLeft =
+ !!configHandler.GetInt("DualScreenMiniMapOnLeft", 0);
+ } else {
+ gu->dualScreenMiniMapOnLeft = false;
+ }
+
+ if (!gu->dualScreenMode) {
+ gu->viewSizeX = gu->winSizeX;
+ gu->viewSizeY = gu->winSizeY;
+ gu->viewPosX = 0;
+ gu->viewPosY = 0;
+ }
+ else {
+ gu->viewSizeX = gu->winSizeX / 2;
+ gu->viewSizeY = gu->winSizeY;
+ if (gu->dualScreenMiniMapOnLeft) {
+ gu->viewPosX = gu->winSizeX / 2;
+ gu->viewPosY = 0;
+ } else {
+ gu->viewPosX = 0;
+ gu->viewPosY = 0;
+ }
+ }
+
+ gu->pixelX = 1.0f / (float)gu->viewSizeX;
+ gu->pixelY = 1.0f / (float)gu->viewSizeY;
+
+ // NOTE: gu->viewPosY is not currently used
+
+ gu->aspectRatio = (float)gu->viewSizeX / (float)gu->viewSizeY;
+}
+
+
+/**
+ * Initializes OpenGL
+ */
+void SpringApp::InitOpenGL ()
+{
+ SetupViewportGeometry();
+
+ glViewport(gu->viewPosX, gu->viewPosY, gu->viewSizeX, gu->viewSizeY);
+
+ gluPerspective(45.0f, (GLfloat)gu->viewSizeX / (GLfloat)gu->viewSizeY, 2.8f, MAX_VIEW_RANGE);
+
+ // Initialize some GL states
+ glShadeModel(GL_SMOOTH);
+ glClearDepth(1.0f);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
+}
+
+/**
+ * @return whether commandline parsing was successful
+ *
+ * Parse command line arguments
+ */
+void SpringApp::ParseCmdLine()
+{
+ cmdline->addoption('f', "fullscreen", OPTPARM_NONE, "", "Run in fullscreen mode");
+ cmdline->addoption('w', "window", OPTPARM_NONE, "", "Run in windowed mode");
+ cmdline->addoption('x', "xresolution", OPTPARM_INT, "", "Set X resolution");
+ cmdline->addoption('y', "yresolution", OPTPARM_INT, "", "Set Y resolution");
+ cmdline->addoption('m', "minimise", OPTPARM_NONE, "", "Start minimised");
+ cmdline->addoption('s', "server", OPTPARM_NONE, "", "Run as a server");
+ cmdline->addoption('c', "client", OPTPARM_NONE, "", "Run as a client");
+ cmdline->addoption('p', "projectiledump", OPTPARM_NONE, "", "Dump projectile class info in projectiles.txt");
+ cmdline->addoption('t', "textureatlas", OPTPARM_NONE, "", "Dump each finalized textureatlas in textureatlasN.tga");
+ cmdline->addoption('q', "quit", OPTPARM_INT, "T", "Quit immediately on game over or after T seconds");
+ cmdline->addoption('n', "name", OPTPARM_STRING, "", "Set your player name");
+ cmdline->parse();
+
+#ifdef _DEBUG
+ fullscreen = false;
+#else
+ fullscreen = configHandler.GetInt("Fullscreen", 1) != 0;
+#endif
+
+ // mutually exclusive options that cause spring to quit immediately
+ if (cmdline->result("help")) {
+ cmdline->usage("Spring",VERSION_STRING);
+ exit(0);
+ } else if (cmdline->result("version")) {
+ std::cout << "Spring " << VERSION_STRING << std::endl;
+ exit(0);
+ } else if (cmdline->result("projectiledump")) {
+ CCustomExplosionGenerator::OutputProjectileClassInfo();
+ exit(0);
+ }
+
+ // flags
+ if (cmdline->result("window")) {
+ fullscreen = false;
+ } else if (cmdline->result("fullscreen")) {
+ fullscreen = true;
+ }
+
+ if (cmdline->result("textureatlas")) {
+ CTextureAtlas::debug = true;
+ }
+
+ string name;
+ if (cmdline->result("name", name)) {
+ configHandler.SetString("name", name);
+ }
+
+
+ if (!cmdline->result("xresolution", screenWidth)) {
+ screenWidth = configHandler.GetInt("XResolution", XRES_DEFAULT);
+ } else {
+ screenWidth = std::max(screenWidth, 1);
+ }
+
+ if (!cmdline->result("yresolution", screenHeight)) {
+ screenHeight = configHandler.GetInt("YResolution", YRES_DEFAULT);
+ } else {
+ screenHeight = std::max(screenHeight, 1);
+ }
+
+}
+
+/**
+ * @param argc argument count
+ * @param argv array of argument strings
+ *
+ * Checks if a demo SDF file or a startscript has
+ * been specified on the command line
+ */
+void SpringApp::CheckCmdLineFile(int argc, char *argv[])
+{
+ // Check if the commandline parameter is specifying a demo file
+#ifdef _WIN32
+ // find the correct dir
+ char exe[128];
+ GetModuleFileName(0, exe, sizeof(exe));
+ int a,s = strlen(exe);
+ for (a=s-1;a>0;a--)
+ // Running in gdb causes the last dir separator to be a forward slash.
+ if (exe[a] == '\\' || exe[a] == '/') break;
+ if (a > 0) {
+ string path(exe, exe+a);
+ if (path.at(0) == '"')
+ path.append(1,'"');
+ _chdir(path.c_str());
+ }
+
+ // If there are any options, they will start before the demo file name.
+
+ if (win_lpCmdLine == 0)
+ logOutput.Print("ERROR");
+ string cmdLineStr = win_lpCmdLine;
+ string::size_type offset = 0;
+ //Simply assumes that any argument coming after a argument starting with /q is a variable to /q.
+ for(int i=1; i < argc && (argv[i][0] == '/' || (argv[i-1][0] == '/' && (argv[i-1][1] == 'q' || argv[i-1][1] == 'a'))); i++){
+ offset += strlen(argv[i]);
+ offset = cmdLineStr.find_first_not_of(' ', offset);
+ if(offset == string::npos)
+ break;
+ }
+
+ string command;
+ if(offset != string::npos)
+ command = cmdLineStr.substr(offset);
+
+
+ if (!command.empty()) {
+ if (command[0] == '"' && *command.rbegin() == '"' && command.length() > 2)
+ command = command.substr(1, command.length()-2);
+ if (command.rfind("sdf") == command.size()-3) {
+ demofile = command;
+ logOutput << "Using demofile " << demofile.c_str() << "\n";
+ } else if (command.rfind("ssf") == command.size()-3) {
+ savefile = command;
+ logOutput << "Using savefile " << savefile.c_str() << "\n";
+ } else {
+ startscript = command;
+ logOutput << "Using script " << startscript.c_str() << "\n";
+ }
+ }
+#else
+ // is there a reason for not using this in windows?
+ for (int i = 1; i < argc; i++)
+ if (argv[i][0] != '-')
+ {
+ string command(argv[i]);
+ int idx = command.rfind("sdf");
+ if (idx == command.size()-3) {
+ demofile = command;
+ logOutput << "Using demofile " << demofile.c_str() << "\n";
+ } else if (command.rfind("ssf") == command.size()-3) {
+ savefile = command;
+ logOutput << "Using savefile " << savefile.c_str() << "\n";
+ } else {
+ startscript = command;
+ logOutput << "Using script " << startscript.c_str() << "\n";
+ }
+ }
+#endif
+}
+
+/**
+ * Initializes instance of GameSetup
+ */
+void SpringApp::CreateGameSetup()
+{
+ ENTER_SYNCED;
+
+ if (!startscript.empty()) {
+ gameSetup = SAFE_NEW CGameSetup();
+ if (!gameSetup->Init(startscript)) {
+ delete gameSetup;
+ gameSetup = 0;
+ }
+ }
+
+ if (!gameSetup && demofile.empty()) {
+ gs->noHelperAIs = !!configHandler.GetInt("NoHelperAIs", 0);
+ const string luaGaiaStr = configHandler.GetString("LuaGaia", "1");
+ const string luaRulesStr = configHandler.GetString("LuaRules", "1");
+ gs->useLuaGaia = CLuaGaia::SetConfigString(luaGaiaStr);
+ gs->useLuaRules = CLuaRules::SetConfigString(luaRulesStr);
+ if (gs->useLuaGaia) {
+ gs->gaiaTeamID = gs->activeTeams;
+ gs->gaiaAllyTeamID = gs->activeAllyTeams;
+ gs->activeTeams++;
+ gs->activeAllyTeams++;
+ CTeam* team = gs->Team(gs->gaiaTeamID);
+ team->color[0] = 255;
+ team->color[1] = 255;
+ team->color[2] = 255;
+ team->color[3] = 255;
+ team->gaia = true;
+ gs->SetAllyTeam(gs->gaiaTeamID, gs->gaiaAllyTeamID);
+ }
+ }
+
+ ENTER_MIXED;
+
+ bool server = true;
+
+ if (!demofile.empty()) {
+ server = false;
+ }
+ else if (gameSetup) {
+ // first real player is demo host
+ server = (gameSetup->myPlayerNum == gameSetup->numDemoPlayers) && !cmdline->result("client");
+ }
+ else {
+ server = !cmdline->result("client") || cmdline->result("server");
+ }
+
+#ifdef SYNCDEBUG
+ // initialize sync debugger as soon as we know whether we will be server
+ CSyncDebugger::GetInstance()->Initialize(server);
+#endif
+
+ if (!demofile.empty()) {
+ pregame = SAFE_NEW CPreGame(false, demofile, "");
+ } else {
+ pregame = SAFE_NEW CPreGame(server, "", savefile);
+ }
+}
+
+
+/**
+ * @return return code of activecontroller draw function
+ *
+ * Draw function repeatedly called, it calls all the
+ * other draw functions
+ */
+int SpringApp::Update ()
+{
+ if (FSAA)
+ glEnable(GL_MULTISAMPLE_ARB);
+
+ mouseInput->Update();
+
+ int ret = 1;
+ if (activeController) {
+ if (!activeController->Update()) {
+ ret = 0;
+ } else {
+ ret = activeController->Draw();
+ }
+ }
+
+ VSync.Delay();
+ SDL_GL_SwapBuffers();
+
+ if (FSAA)
+ glDisable(GL_MULTISAMPLE_ARB);
+
+ return ret;
+}
+
+/**
+ * Tests SDL keystates and sets values
+ * in key array
+ */
+void SpringApp::UpdateSDLKeys ()
+{
+ int numkeys;
+ Uint8 *state;
+ state = SDL_GetKeyState(&numkeys);
+ memcpy(keys, state, sizeof(Uint8) * numkeys);
+
+ const SDLMod mods = SDL_GetModState();
+ keys[SDLK_LALT] = (mods & KMOD_ALT) ? 1 : 0;
+ keys[SDLK_LCTRL] = (mods & KMOD_CTRL) ? 1 : 0;
+ keys[SDLK_LMETA] = (mods & KMOD_META) ? 1 : 0;
+ keys[SDLK_LSHIFT] = (mods & KMOD_SHIFT) ? 1 : 0;
+}
+
+/**
+ * @param argc argument count
+ * @param argv array of argument strings
+ *
+ * Executes the application
+ * (contains main game loop)
+ */
+int SpringApp::Run (int argc, char *argv[])
+{
+ INIT_SYNCIFY;
+ CheckCmdLineFile (argc, argv);
+ cmdline = BaseCmd::initialize(argc,argv);
+/*
+ logOutput.Print ("Testing error catching");
+ try {
+ int *i_=0;
+ *i_=1;
+ logOutput.Print ("Error catching doesn't work!");
+ } catch(...) {
+ logOutput.Print ("Error catching works!");
+ }
+*/
+ if (!Initialize ())
+ return -1;
+
+#ifdef WIN32
+ SDL_EventState (SDL_SYSWMEVENT, SDL_ENABLE);
+#endif
+
+ SDL_Event event;
+ bool done = false;
+
+ while (!done) {
+ ENTER_UNSYNCED;
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_VIDEORESIZE: {
+ screenWidth = event.resize.w;
+ screenHeight = event.resize.h;
+#ifndef WIN32
+ // HACK We don't want to break resizing on windows (again?),
+ // so someone should test this very well before enabling it.
+ SetSDLVideoMode();
+#endif
+ InitOpenGL();
+ activeController->ResizeEvent();
+ break;
+ }
+ case SDL_VIDEOEXPOSE: {
+ // re-initialize the stencil
+ glClearStencil(0);
+ glClear(GL_STENCIL_BUFFER_BIT); SDL_GL_SwapBuffers();
+ glClear(GL_STENCIL_BUFFER_BIT); SDL_GL_SwapBuffers();
+ SetupViewportGeometry();
+ break;
+ }
+ case SDL_QUIT: {
+ done = true;
+ break;
+ }
+ case SDL_ACTIVEEVENT: {
+ if (event.active.state & SDL_APPACTIVE) {
+ gu->active = !!event.active.gain;
+ }
+ break;
+ }
+ case SDL_MOUSEMOTION:
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ case SDL_SYSWMEVENT: {
+ mouseInput->HandleSDLMouseEvent (event);
+ break;
+ }
+ case SDL_KEYDOWN: {
+ int i = event.key.keysym.sym;
+
+ const bool isRepeat = !!keys[i];
+
+ UpdateSDLKeys ();
+
+ if (activeController) {
+ if (i <= SDLK_DELETE) {
+ i = tolower(i);
+ }
+ else if (i == SDLK_RSHIFT) { i = SDLK_LSHIFT; }
+ else if (i == SDLK_RCTRL) { i = SDLK_LCTRL; }
+ else if (i == SDLK_RMETA) { i = SDLK_LMETA; }
+ else if (i == SDLK_RALT) { i = SDLK_LALT; }
+
+ if (keyBindings) {
+ const int fakeMetaKey = keyBindings->GetFakeMetaKey();
+ if (fakeMetaKey >= 0) {
+ keys[SDLK_LMETA] |= keys[fakeMetaKey];
+ }
+ }
+
+ activeController->KeyPressed(i, isRepeat);
+
+ if (activeController->userWriting){
+ // use unicode for printed characters
+ i = event.key.keysym.unicode;
+ if ((i >= SDLK_SPACE) && (i <= SDLK_DELETE)) {
+ CGameController* ac = activeController;
+ if (ac->ignoreNextChar || ac->ignoreChar == char(i)) {
+ ac->ignoreNextChar = false;
+ } else {
+ if (i < SDLK_DELETE) {
+ const int len = (int)ac->userInput.length();
+ ac->writingPos = std::max(0, std::min(len, ac->writingPos));
+ char str[2] = { char(i), 0 };
+ ac->userInput.insert(ac->writingPos, str);
+ ac->writingPos++;
+ }
+ }
+ }
+ }
+ }
+ activeController->ignoreNextChar = false;
+ break;
+ }
+ case SDL_KEYUP: {
+ int i = event.key.keysym.sym;
+
+ UpdateSDLKeys();
+
+ if (activeController) {
+ if (i <= SDLK_DELETE) {
+ i = tolower(i);
+ }
+ else if (i == SDLK_RSHIFT) { i = SDLK_LSHIFT; }
+ else if (i == SDLK_RCTRL) { i = SDLK_LCTRL; }
+ else if (i == SDLK_RMETA) { i = SDLK_LMETA; }
+ else if (i == SDLK_RALT) { i = SDLK_LALT; }
+
+ if (keyBindings) {
+ const int fakeMetaKey = keyBindings->GetFakeMetaKey();
+ if (fakeMetaKey >= 0) {
+ keys[SDLK_LMETA] |= keys[fakeMetaKey];
+ }
+ }
+
+ activeController->KeyReleased(i);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (globalQuit)
+ break;
+
+ if (!Update())
+ break;
+ }
+ ENTER_MIXED;
+
+ // Shutdown
+ Shutdown();
+ return 0;
+}
+
+/**
+ * Deallocates and shuts down game
+ */
+void SpringApp::Shutdown()
+{
+ if (pregame)
+ delete pregame; //in case we exit during init
+ if (game)
+ delete game;
+ if (gameSetup)
+ delete gameSetup;
+ delete font;
+ CNamedTextures::Kill();
+ GLContext::Free();
+ ConfigHandler::Deallocate();
+ UnloadExtensions();
+ delete mouseInput;
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
+ SDL_Quit();
+ delete gs;
+ delete gu;
+ END_SYNCIFY;
+#ifdef USE_MMGR
+ m_dumpMemoryReport();
+#endif
+}
-
ui.patch (12,472 bytes) 2008-05-10 16:29
Index: Documentation/cmds.txt
===================================================================
--- Documentation/cmds.txt (revision 5850)
+++ Documentation/cmds.txt (working copy)
@@ -80,7 +80,7 @@
pause
shadows [<0|1> [mapsize]]
-water [0|1|2|3]
+water [0|1|2|3|4]
vsync [-1|0|1|2|...] -- -1 will use default setting in windows,
-- numbers higher then 1 will result in
-- rendering every N frames.
@@ -145,6 +145,7 @@
cross <size> -- locked mouse cross size
volume <float> -- 0.0 to 1.0
+unitreplyvolume <float> -- 0.0 to 1.0
toggleoverview
showhealthbars
@@ -188,6 +189,7 @@
screenshot ["png"]
grabinput
+hardwarecursor [0|1]
bind
unbind
@@ -222,6 +224,7 @@
minimap <"fullproxy"> [0|1]
minimap <"icons"> [0|1]
minimap <"drawcommands"> [0|1]
+minimap <"drawprojectiles"> [0|1]
minimap <"simplecolors"> [0|1]
minimap <"min" | "minimize"> [0|1]
minimap <"max" | "maximize"> [0|1]
Index: rts/Game/Game.cpp
===================================================================
--- rts/Game/Game.cpp (revision 5850)
+++ rts/Game/Game.cpp (working copy)
@@ -193,6 +193,7 @@
CR_MEMBER(soundEnabled),
CR_MEMBER(gameSoundVolume),
+ CR_MEMBER(unitReplyVolume),
// CR_MEMBER(script),
CR_RESERVED(64),
@@ -283,9 +284,10 @@
ENTER_UNSYNCED;
sound = CSound::GetSoundSystem();
gameSoundVolume = configHandler.GetInt("SoundVolume", 60) * 0.01f;
+ unitReplyVolume = configHandler.GetInt("UnitReplyVolume", configHandler.GetInt("UnitReplySoundVolume", 80) ) * 0.01f;
soundEnabled = true;
sound->SetVolume(gameSoundVolume);
- sound->SetUnitReplyVolume(configHandler.GetInt ("UnitReplySoundVolume", 80) * 0.01f);
+ sound->SetUnitReplyVolume(unitReplyVolume);
camera = SAFE_NEW CCamera();
cam2 = SAFE_NEW CCamera();
@@ -496,6 +498,8 @@
net->SendStartPlaying(0);
lastCpuUsageTime = gu->gameTime + 10;
+
+ mouse->ShowMouse();
}
@@ -906,14 +910,14 @@
else if (cmd == "water") {
delete water;
- static char rmodes[4][32] = {"basic", "reflective", "dynamic", "reflective&refractive"};
+ static char rmodes[5][32] = {"basic", "reflective", "dynamic", "reflective&refractive", "bumpmapped"};
int next = 0;
if (!action.extra.empty()) {
- next = std::max(0, atoi(action.extra.c_str()) % 4);
+ next = std::max(0, atoi(action.extra.c_str()) % 5);
} else {
const int current = configHandler.GetInt("ReflectiveWater", 1);
- next = (std::max(0, current) + 1) % 4;
+ next = (std::max(0, current) + 1) % 5;
}
configHandler.SetInt("ReflectiveWater", next);
logOutput.Print("Set water rendering mode to %i (%s)", next, rmodes[next]);
@@ -1206,6 +1210,16 @@
configHandler.SetInt("SoundVolume", (int)(gameSoundVolume * 100.0f));
}
}
+ else if (cmd == "unitreplyvolume") {
+ char* endPtr;
+ const char* startPtr = action.extra.c_str();
+ float volume = (float)strtod(startPtr, &endPtr);
+ if (endPtr != startPtr) {
+ unitReplyVolume = std::max(0.0f, std::min(1.0f, volume));
+ sound->SetUnitReplyVolume(unitReplyVolume);
+ configHandler.SetInt("UnitReplyVolume",(int)(unitReplyVolume * 100.0f));
+ }
+ }
else if (cmd == "savegame"){
if (filesystem.CreateDirectory("Saves")) {
CLoadSaveHandler ls;
@@ -1292,6 +1306,15 @@
hideInterface = !!atoi(action.extra.c_str());
}
}
+ else if (cmd == "hardwarecursor") {
+ if (action.extra.empty()) {
+ mouse->hardwareCursor = !mouse->hardwareCursor;
+ } else {
+ mouse->hardwareCursor = !!atoi(action.extra.c_str());
+ }
+ mouse->UpdateHwCursor();
+ configHandler.SetInt("HardwareCursor", (int)mouse->hardwareCursor);
+ }
else if (cmd == "increaseviewradius") {
gd->IncreaseDetail();
}
@@ -1315,8 +1338,12 @@
logOutput << "Cloud density " << 1/sky->cloudDensity << "\n";
}
+ // Break up the if/else chain to workaround MSVC compiler limit
+ // "fatal error C1061: compiler limit : blocks nested too deeply"
+ else notfound1=true;
+ if (notfound1)
- else if (cmd == "speedup") {
+ if (cmd == "speedup") {
float speed = gs->userSpeedFactor;
if (speed < 1) {
speed /= 0.8f;
@@ -1351,11 +1378,7 @@
}
#endif
- // Break up the if/else chain to workaround MSVC compiler limit
- // "fatal error C1061: compiler limit : blocks nested too deeply"
- else notfound1=true;
- if (notfound1)
- if (cmd == "showshadowmap") {
+ else if (cmd == "showshadowmap") {
shadowHandler->showShadowMap = !shadowHandler->showShadowMap;
}
else if (cmd == "showstandard") {
@@ -1753,9 +1776,11 @@
}
else if (cmd == "wiremap") {
if (action.extra.empty()) {
- gd->wireframe = !gd->wireframe;
+ gd->wireframe = !gd->wireframe;
+ sky->wireframe = gd->wireframe;
} else {
- gd->wireframe = !atoi(action.extra.c_str());
+ gd->wireframe = !atoi(action.extra.c_str());
+ sky->wireframe = gd->wireframe;
}
}
else if (cmd == "setgamma") {
@@ -2384,7 +2409,7 @@
SCOPED_TIMER("Draw world");
CBaseGroundDrawer* gd = readmap->GetGroundDrawer();
-
+
if (drawSky) {
sky->Draw();
}
@@ -2420,6 +2445,7 @@
water->Draw();
}
}
+
unitDrawer->DrawCloakedUnits();
ph->Draw(false);
Index: rts/Game/Game.h
===================================================================
--- rts/Game/Game.h (revision 5850)
+++ rts/Game/Game.h (working copy)
@@ -97,6 +97,7 @@
bool soundEnabled;
float gameSoundVolume;
+ float unitReplyVolume;
CScript* script;
Index: rts/Game/UI/MiniMap.cpp
===================================================================
--- rts/Game/UI/MiniMap.cpp (revision 5850)
+++ rts/Game/UI/MiniMap.cpp (working copy)
@@ -115,6 +115,8 @@
drawCommands = std::max(0, configHandler.GetInt("MiniMapDrawCommands", 1));
+ drawProjectiles = !!configHandler.GetInt("MiniMapDrawProjectiles", 1);
+
simpleColors = !!configHandler.GetInt("SimpleMiniMapColors", 0);
myColor[0] = (unsigned char)(0.2f * 255);
@@ -352,6 +354,14 @@
drawCommands = (drawCommands > 0) ? 0 : 1;
}
}
+ else if (command == "drawprojectiles") {
+ if (words.size() >= 2) {
+ drawProjectiles = !!atoi(words[1].c_str());
+
+ } else {
+ drawProjectiles = !drawProjectiles;
+ }
+ }
else if (command == "simplecolors") {
if (words.size() >= 2) {
simpleColors = !!atoi(words[1].c_str());
@@ -1060,57 +1070,59 @@
// draw the projectiles
glRotatef(-90.0f, +1.0f, 0.0f, 0.0f); // real 'world' coordinates
- Projectile_List::iterator psi;
- for(psi = ph->ps.begin(); psi != ph->ps.end(); ++psi) {
- CProjectile* p = *psi;
+ if (drawProjectiles) {
+ Projectile_List::iterator psi;
+ for(psi = ph->ps.begin(); psi != ph->ps.end(); ++psi) {
+ CProjectile* p = *psi;
- if ((p->owner && (p->owner->allyteam == gu->myAllyTeam)) ||
- gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) {
+ if ((p->owner && (p->owner->allyteam == gu->myAllyTeam)) ||
+ gu->spectatingFullView || loshandler->InLos(p, gu->myAllyTeam)) {
- if (dynamic_cast<CGeoThermSmokeProjectile*>(p)) {
- } else if (dynamic_cast<CGfxProjectile*>(p)) {//Nano-piece
- glBegin(GL_POINTS);
- glColor4f(0,1,0,0.1);
- glVertexf3(p->pos);
- glEnd();
- } else if (dynamic_cast<CBeamLaserProjectile*>(p)) {
- glBegin(GL_LINES);
- glColor4f(((CBeamLaserProjectile*)p)->kocolstart[0]/255.0,((CBeamLaserProjectile*)p)->kocolstart[1]/255.0,((CBeamLaserProjectile*)p)->kocolstart[2]/255.0,1);
- glVertexf3(((CBeamLaserProjectile*)p)->startPos);
- glVertexf3(((CBeamLaserProjectile*)p)->endPos);
- glEnd();
- } else if (dynamic_cast<CLargeBeamLaserProjectile*>(p)) {
- glBegin(GL_LINES);
- glColor4f(((CLargeBeamLaserProjectile*)p)->kocolstart[0]/255.0,((CLargeBeamLaserProjectile*)p)->kocolstart[1]/255.0,((CLargeBeamLaserProjectile*)p)->kocolstart[2]/255.0,1);
- glVertexf3(((CLargeBeamLaserProjectile*)p)->startPos);
- glVertexf3(((CLargeBeamLaserProjectile*)p)->endPos);
- glEnd();
- } else if (dynamic_cast<CLightingProjectile*>(p)) {
- glBegin(GL_LINES);
- glColor4f(((CLightingProjectile*)p)->color[0],((CLightingProjectile*)p)->color[1],((CLightingProjectile*)p)->color[2],1);
- glVertexf3(((CLightingProjectile*)p)->pos);
- glVertexf3(((CLightingProjectile*)p)->endPos);
- glEnd();
- } else if (dynamic_cast<CPieceProjectile*>(p)) {
- glBegin(GL_POINTS);
- glColor4f(1,0,0,1);
- glVertexf3(p->pos);
- glEnd();
- } else if (dynamic_cast<CWreckProjectile*>(p)) {
- glBegin(GL_POINTS);
- glColor4f(1,0,0,0.5);
- glVertexf3(p->pos);
- glEnd();
- } else if (dynamic_cast<CWeaponProjectile*>(p)) {
- glBegin(GL_POINTS);
- glColor4f(1,1,0,1);
- glVertexf3(p->pos);
- glEnd();
- } else {
- glBegin(GL_POINTS);
- glColor4f(1,1,1,0.1/*0.0002f*(width+height)*/);
- glVertexf3(p->pos);
- glEnd();
+ if (dynamic_cast<CGeoThermSmokeProjectile*>(p)) {
+ } else if (dynamic_cast<CGfxProjectile*>(p)) {//Nano-piece
+ glBegin(GL_POINTS);
+ glColor4f(0,1,0,0.1);
+ glVertexf3(p->pos);
+ glEnd();
+ } else if (dynamic_cast<CBeamLaserProjectile*>(p)) {
+ glBegin(GL_LINES);
+ glColor4f(((CBeamLaserProjectile*)p)->kocolstart[0]/255.0,((CBeamLaserProjectile*)p)->kocolstart[1]/255.0,((CBeamLaserProjectile*)p)->kocolstart[2]/255.0,1);
+ glVertexf3(((CBeamLaserProjectile*)p)->startPos);
+ glVertexf3(((CBeamLaserProjectile*)p)->endPos);
+ glEnd();
+ } else if (dynamic_cast<CLargeBeamLaserProjectile*>(p)) {
+ glBegin(GL_LINES);
+ glColor4f(((CLargeBeamLaserProjectile*)p)->kocolstart[0]/255.0,((CLargeBeamLaserProjectile*)p)->kocolstart[1]/255.0,((CLargeBeamLaserProjectile*)p)->kocolstart[2]/255.0,1);
+ glVertexf3(((CLargeBeamLaserProjectile*)p)->startPos);
+ glVertexf3(((CLargeBeamLaserProjectile*)p)->endPos);
+ glEnd();
+ } else if (dynamic_cast<CLightingProjectile*>(p)) {
+ glBegin(GL_LINES);
+ glColor4f(((CLightingProjectile*)p)->color[0],((CLightingProjectile*)p)->color[1],((CLightingProjectile*)p)->color[2],1);
+ glVertexf3(((CLightingProjectile*)p)->pos);
+ glVertexf3(((CLightingProjectile*)p)->endPos);
+ glEnd();
+ } else if (dynamic_cast<CPieceProjectile*>(p)) {
+ glBegin(GL_POINTS);
+ glColor4f(1,0,0,1);
+ glVertexf3(p->pos);
+ glEnd();
+ } else if (dynamic_cast<CWreckProjectile*>(p)) {
+ glBegin(GL_POINTS);
+ glColor4f(1,0,0,0.5);
+ glVertexf3(p->pos);
+ glEnd();
+ } else if (dynamic_cast<CWeaponProjectile*>(p)) {
+ glBegin(GL_POINTS);
+ glColor4f(1,1,0,1);
+ glVertexf3(p->pos);
+ glEnd();
+ } else {
+ glBegin(GL_POINTS);
+ glColor4f(1,1,1,0.1/*0.0002f*(width+height)*/);
+ glVertexf3(p->pos);
+ glEnd();
+ }
}
}
}
@@ -1120,7 +1132,7 @@
// NOTE: this needlessly adds to the CursorIcons list, but at least
// they are not drawn (because the input receivers are drawn
// after the command queues)
- LuaUnsyncedCtrl::DrawUnitCommandQueues();
+ LuaUnsyncedCtrl::DrawUnitCommandQueues();
if ((drawCommands > 0) && guihandler->GetQueueKeystate()) {
selectedUnits.DrawCommands();
}
Index: rts/Game/UI/MiniMap.h
===================================================================
--- rts/Game/UI/MiniMap.h (revision 5850)
+++ rts/Game/UI/MiniMap.h (working copy)
@@ -122,6 +122,7 @@
int lastWindowSizeX;
int lastWindowSizeY;
+ bool drawProjectiles;
bool useIcons;
int drawCommands;
float cursorScale;
Index: rts/Game/WordCompletion.cpp
===================================================================
--- rts/Game/WordCompletion.cpp (revision 5850)
+++ rts/Game/WordCompletion.cpp (working copy)
@@ -30,12 +30,14 @@
// local commands
words["/advshading "] = sl;
+ words["/hardwarecursor "] = sl;
words["/clock"] = sl;
words["/cmdcolors "] = sl;
words["/ctrlpanel "] = sl;
words["/echo "] = sl;
words["/font "] = sl;
words["/gameinfo"] = sl;
+ words["/grounddecals "] = sl;
words["/info "] = sl;
words["/luaui "] = sl;
words["/maxparticles "] = sl;
@@ -58,12 +60,15 @@
words["/keydebug"] = sl;
words["/fakemeta "] = sl;
words["/volume "] = sl;
+ words["/unitreplyvolume "] = sl;
words["/vsync "] = sl;
+ words["/wiremap "] = sl;
// minimap sub-commands
WordProperties mm(false, false, true);
words["fullproxy "] = mm;
words["drawcommands "] = mm;
+ words["drawprojectiles "] = mm;
words["icons "] = mm;
words["unitexp "] = mm;
words["unitsize "] = mm;
ui.patch (12,472 bytes) 2008-05-10 16:29 
-
speedups.patch (15,652 bytes) 2008-05-10 16:29
Index: rts/Rendering/GL/VertexArray.cpp
===================================================================
--- rts/Rendering/GL/VertexArray.cpp (revision 5850)
+++ rts/Rendering/GL/VertexArray.cpp (working copy)
@@ -6,6 +6,7 @@
#include "VertexArray.h"
#include "myGL.h"
#include "mmgr.h"
+#include <GL/glew.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
@@ -34,7 +35,7 @@
bool CVertexArray::IsReady()
{
- return true;
+ return true;
}
void CVertexArray::EndStrip()
@@ -45,20 +46,11 @@
stripArray[stripIndex++]=drawIndex;
}
-void CVertexArray::AddVertex0(const float3& pos)
-{
- if(drawIndex>drawArraySize-10)
- EnlargeDrawArray();
-
- drawArray[drawIndex++]=pos.x;
- drawArray[drawIndex++]=pos.y;
- drawArray[drawIndex++]=pos.z;
-}
-
void CVertexArray::DrawArray0(int drawType,int stride)
{
if(stripIndex==0 || stripArray[stripIndex-1]!=drawIndex)
EndStrip();
+
glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
glEnableClientState(GL_VERTEX_ARRAY);
int oldIndex=0;
@@ -66,89 +58,54 @@
glDrawArrays(drawType,oldIndex*4/stride,stripArray[a]*4/stride-oldIndex*4/stride);
oldIndex=stripArray[a];
}
- glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
}
-void CVertexArray::AddVertexC(const float3& pos,unsigned char* color)
-{
- if(drawIndex>drawArraySize-10)
- EnlargeDrawArray();
-
- drawArray[drawIndex++]=pos.x;
- drawArray[drawIndex++]=pos.y;
- drawArray[drawIndex++]=pos.z;
- drawArray[drawIndex++]=*((float*)(color));
-}
-
void CVertexArray::DrawArrayC(int drawType,int stride)
{
if(stripIndex==0 || stripArray[stripIndex-1]!=drawIndex)
EndStrip();
- glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
- glColorPointer(4,GL_UNSIGNED_BYTE,stride,&drawArray[3]);
+
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
+ glColorPointer(4,GL_UNSIGNED_BYTE,stride,&drawArray[3]);
int oldIndex=0;
for(int a=0;a<stripIndex;a++){
glDrawArrays(drawType,oldIndex*4/stride,stripArray[a]*4/stride-oldIndex*4/stride);
oldIndex=stripArray[a];
}
- glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
-void CVertexArray::AddVertexT(const float3& pos,float tx,float ty)
-{
- if(drawIndex>drawArraySize-10)
- EnlargeDrawArray();
-
- drawArray[drawIndex++]=pos.x;
- drawArray[drawIndex++]=pos.y;
- drawArray[drawIndex++]=pos.z;
- drawArray[drawIndex++]=tx;
- drawArray[drawIndex++]=ty;
-}
-
void CVertexArray::DrawArrayT(int drawType,int stride)
{
if(stripIndex==0 || stripArray[stripIndex-1]!=drawIndex)
EndStrip();
- glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
- glTexCoordPointer(2,GL_FLOAT,stride,&drawArray[3]);
+
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
+ glTexCoordPointer(2,GL_FLOAT,stride,&drawArray[3]);
int oldIndex=0;
for(int a=0;a<stripIndex;a++){
glDrawArrays(drawType,oldIndex*4/stride,stripArray[a]*4/stride-oldIndex*4/stride);
oldIndex=stripArray[a];
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
}
-void CVertexArray::AddVertexT2(const float3& pos,float tx,float ty,float t2x,float t2y)
-{
- if(drawIndex>drawArraySize-10)
- EnlargeDrawArray();
-
- drawArray[drawIndex++]=pos.x;
- drawArray[drawIndex++]=pos.y;
- drawArray[drawIndex++]=pos.z;
- drawArray[drawIndex++]=tx;
- drawArray[drawIndex++]=ty;
- drawArray[drawIndex++]=t2x;
- drawArray[drawIndex++]=t2y;
-}
-
void CVertexArray::DrawArrayT2(int drawType,int stride)
{
if(stripIndex==0 || stripArray[stripIndex-1]!=drawIndex)
EndStrip();
- glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
- glTexCoordPointer(2,GL_FLOAT,stride,&drawArray[3]);
+
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
-
+ glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
+ glTexCoordPointer(2,GL_FLOAT,stride,&drawArray[3]);
glClientActiveTextureARB(GL_TEXTURE1_ARB);
glTexCoordPointer(2,GL_FLOAT,stride,&drawArray[5]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -164,76 +121,48 @@
glClientActiveTextureARB(GL_TEXTURE0_ARB);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
}
-void CVertexArray::AddVertexTN(const float3& pos,float tx,float ty, const float3& norm)
-{
- if(drawIndex>drawArraySize-10)
- EnlargeDrawArray();
-
- drawArray[drawIndex++]=pos.x;
- drawArray[drawIndex++]=pos.y;
- drawArray[drawIndex++]=pos.z;
- drawArray[drawIndex++]=tx;
- drawArray[drawIndex++]=ty;
- drawArray[drawIndex++]=norm.x;
- drawArray[drawIndex++]=norm.y;
- drawArray[drawIndex++]=norm.z;
-}
-
void CVertexArray::DrawArrayTN(int drawType, int stride)
{
if(stripIndex==0 || stripArray[stripIndex-1]!=drawIndex)
EndStrip();
- glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
- glTexCoordPointer(2,GL_FLOAT,stride,&drawArray[3]);
- glNormalPointer(GL_FLOAT,stride,&drawArray[5]);
+
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
-
+ glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
+ glTexCoordPointer(2,GL_FLOAT,stride,&drawArray[3]);
+ glNormalPointer(GL_FLOAT,stride,&drawArray[5]);
int oldIndex=0;
for(int a=0;a<stripIndex;a++){
glDrawArrays(drawType,oldIndex*4/stride,stripArray[a]*4/stride-oldIndex*4/stride);
oldIndex=stripArray[a];
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
-void CVertexArray::AddVertexTC(const float3& pos,float tx,float ty,unsigned char* col)
-{
- if(drawIndex>drawArraySize-10)
- EnlargeDrawArray();
-
- drawArray[drawIndex++]=pos.x;
- drawArray[drawIndex++]=pos.y;
- drawArray[drawIndex++]=pos.z;
- drawArray[drawIndex++]=tx;
- drawArray[drawIndex++]=ty;
- drawArray[drawIndex++]=*((float*)(col));
-}
-
void CVertexArray::DrawArrayTC(int drawType, int stride)
{
if(stripIndex==0 || stripArray[stripIndex-1]!=drawIndex)
EndStrip();
- glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
- glTexCoordPointer(2,GL_FLOAT,stride,&drawArray[3]);
- glColorPointer(4,GL_UNSIGNED_BYTE,stride,&drawArray[5]);
+
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
-
+ glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
+ glTexCoordPointer(2,GL_FLOAT,stride,&drawArray[3]);
+ glColorPointer(4,GL_UNSIGNED_BYTE,stride,&drawArray[5]);
int oldIndex=0;
for(int a=0;a<stripIndex;a++){
glDrawArrays(drawType,oldIndex*4/stride,stripArray[a]*4/stride-oldIndex*4/stride);
oldIndex=stripArray[a];
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
Index: rts/Rendering/GL/VertexArray.h
===================================================================
--- rts/Rendering/GL/VertexArray.h (revision 5850)
+++ rts/Rendering/GL/VertexArray.h (working copy)
@@ -4,30 +4,32 @@
//
//////////////////////////////////////////////////////////////////////
-class CVertexArray
+#include "myGL.h"
+
+class CVertexArray
{
public:
CVertexArray();
~CVertexArray();
void Initialize();
+ bool IsReady();
- void AddVertexTC(const float3 &pos,float tx,float ty,unsigned char* color);
+ inline void AddVertexTC(const float3 &pos,float tx,float ty,unsigned char* color);
void DrawArrayTC(int drawType,int stride=24);
- void AddVertexTN(const float3 &pos,float tx,float ty,const float3& norm);
+ inline void AddVertexTN(const float3 &pos,float tx,float ty,const float3& norm);
void DrawArrayTN(int drawType,int stride=32);
- void AddVertexT2(const float3& pos,float t1x,float t1y,float t2x,float t2y);
+ inline void AddVertexT2(const float3& pos,float t1x,float t1y,float t2x,float t2y);
void DrawArrayT2(int drawType,int stride=28);
- void AddVertexT(const float3& pos,float tx,float ty);
+ inline void AddVertexT(const float3& pos,float tx,float ty);
void DrawArrayT(int drawType,int stride=20);
- void AddVertex0(const float3& pos);
+ inline void AddVertex0(const float3& pos);
void DrawArray0(int drawType,int stride=12);
- void AddVertexC(const float3& pos,unsigned char* color);
+ inline void AddVertexC(const float3& pos,unsigned char* color);
void DrawArrayC(int drawType,int stride=16);
void EnlargeStripArray();
void EnlargeDrawArray();
void EndStrip();
- bool IsReady();
float* drawArray;
int drawArraySize;
@@ -38,4 +40,83 @@
int stripIndex;
};
+/***************************************************************************************************/
+/***************************************************************************************************/
+
+inline void CVertexArray::AddVertexTC(const float3 &pos,float tx,float ty,unsigned char* color)
+{
+ if(drawIndex>drawArraySize-10)
+ EnlargeDrawArray();
+
+ drawArray[drawIndex++]=pos.x;
+ drawArray[drawIndex++]=pos.y;
+ drawArray[drawIndex++]=pos.z;
+ drawArray[drawIndex++]=tx;
+ drawArray[drawIndex++]=ty;
+ drawArray[drawIndex++]=*((float*)(color));
+}
+
+inline void CVertexArray::AddVertexTN(const float3 &pos,float tx,float ty,const float3& norm)
+{
+ if(drawIndex>drawArraySize-10)
+ EnlargeDrawArray();
+
+ drawArray[drawIndex++]=pos.x;
+ drawArray[drawIndex++]=pos.y;
+ drawArray[drawIndex++]=pos.z;
+ drawArray[drawIndex++]=tx;
+ drawArray[drawIndex++]=ty;
+ drawArray[drawIndex++]=norm.x;
+ drawArray[drawIndex++]=norm.y;
+ drawArray[drawIndex++]=norm.z;
+}
+
+inline void CVertexArray::AddVertexT2(const float3& pos,float t1x,float t1y,float t2x,float t2y)
+{
+ if(drawIndex>drawArraySize-10)
+ EnlargeDrawArray();
+
+ drawArray[drawIndex++]=pos.x;
+ drawArray[drawIndex++]=pos.y;
+ drawArray[drawIndex++]=pos.z;
+ drawArray[drawIndex++]=t1x;
+ drawArray[drawIndex++]=t1y;
+ drawArray[drawIndex++]=t2x;
+ drawArray[drawIndex++]=t2y;
+}
+
+inline void CVertexArray::AddVertexT(const float3& pos,float tx,float ty)
+{
+ if(drawIndex>drawArraySize-10)
+ EnlargeDrawArray();
+
+ drawArray[drawIndex++]=pos.x;
+ drawArray[drawIndex++]=pos.y;
+ drawArray[drawIndex++]=pos.z;
+ drawArray[drawIndex++]=tx;
+ drawArray[drawIndex++]=ty;
+}
+
+inline void CVertexArray::AddVertex0(const float3& pos)
+{
+ if(drawIndex>drawArraySize-10)
+ EnlargeDrawArray();
+
+ drawArray[drawIndex++]=pos.x;
+ drawArray[drawIndex++]=pos.y;
+ drawArray[drawIndex++]=pos.z;
+}
+
+inline void CVertexArray::AddVertexC(const float3& pos,unsigned char* color)
+{
+ if(drawIndex>drawArraySize-10)
+ EnlargeDrawArray();
+
+ drawArray[drawIndex++]=pos.x;
+ drawArray[drawIndex++]=pos.y;
+ drawArray[drawIndex++]=pos.z;
+ drawArray[drawIndex++]=*((float*)(color));
+}
+
+
#endif /* VERTEXARRAY_H */
Index: rts/System/Matrix44f.cpp
===================================================================
--- rts/System/Matrix44f.cpp (revision 5850)
+++ rts/System/Matrix44f.cpp (working copy)
@@ -8,11 +8,6 @@
CR_REG_METADATA(CMatrix44f, CR_MEMBER(m));
-/*
-float globalArf=15;
-extern void arfurf();
-extern void TestDenormal(float f);
-*/
CMatrix44f::CMatrix44f(void)
{
LoadIdentity();
@@ -28,6 +23,15 @@
}
+CMatrix44f::CMatrix44f(const CMatrix44f& n)
+{
+ m[0] = n[0]; m[1] = n[1]; m[2] = n[2]; m[3] = n[3];
+ m[4] = n[4]; m[5] = n[5]; m[6] = n[6]; m[7] = n[7];
+ m[8] = n[8]; m[9] = n[9]; m[10] = n[10]; m[11] = n[11];
+ m[12] = n[12]; m[13] = n[13]; m[14] = n[14]; m[15] = n[15];
+}
+
+
CMatrix44f::~CMatrix44f(void)
{
}
@@ -48,6 +52,7 @@
void CMatrix44f::RotateX(float rad)
{
+/*
const float sr = sin(rad);
const float cr = cos(rad);
@@ -58,11 +63,31 @@
rm[6] = -sr;
*this=Mul(rm);
+*/
+ const float sr = sin(rad);
+ const float cr = cos(rad);
+
+ float a=m[4];
+ m[4] = cr*a - sr*m[8];
+ m[8] = sr*a + cr*m[8];
+
+ a=m[5];
+ m[5] = cr*a - sr*m[9];
+ m[9] = sr*a + cr*m[9];
+
+ a=m[6];
+ m[6] = cr*a - sr*m[10];
+ m[10] = sr*a + cr*m[10];
+
+ a=m[7];
+ m[7] = cr*a - sr*m[11];
+ m[11] = sr*a + cr*m[11];
}
void CMatrix44f::RotateY(float rad)
{
+/*
const float sr = sin(rad);
const float cr = cos(rad);
@@ -73,11 +98,31 @@
rm[8] = -sr;
*this = Mul(rm);
+*/
+ const float sr = sin(rad);
+ const float cr = cos(rad);
+
+ float a=m[0];
+ m[0] = cr*a + sr*m[8];
+ m[8] = -sr*a + cr*m[8];
+
+ a=m[1];
+ m[1] = cr*a + sr*m[9];
+ m[9] = -sr*a + cr*m[9];
+
+ a=m[2];
+ m[2] = cr*a + sr*m[10];
+ m[10] = -sr*a + cr*m[10];
+
+ a=m[3];
+ m[3] = cr*a + sr*m[11];
+ m[11] = -sr*a + cr*m[11];
}
void CMatrix44f::RotateZ(float rad)
{
+/*
const float sr = sin(rad);
const float cr = cos(rad);
@@ -88,11 +133,31 @@
rm[1] = -sr;
*this = Mul(rm);
+*/
+ const float sr = sin(rad);
+ const float cr = cos(rad);
+
+ float a=m[0];
+ m[0] = cr*a - sr*m[4];
+ m[4] = sr*a + cr*m[4];
+
+ a=m[1];
+ m[1] = cr*a - sr*m[5];
+ m[5] = sr*a + cr*m[5];
+
+ a=m[2];
+ m[2] = cr*a - sr*m[6];
+ m[6] = sr*a + cr*m[6];
+
+ a=m[3];
+ m[3] = cr*a - sr*m[7];
+ m[7] = sr*a + cr*m[7];
}
void CMatrix44f::Translate(float x, float y, float z)
{
+/*
CMatrix44f tm;
tm[12] = x;
@@ -100,11 +165,18 @@
tm[14] = z;
*this = Mul(tm);
+*/
+
+ m[12] += x*m[0] + y*m[4] + z*m[8];
+ m[13] += x*m[1] + y*m[5] + z*m[9];
+ m[14] += x*m[2] + y*m[6] + z*m[10];
+ m[15] += x*m[3] + y*m[7] + z*m[11];
}
void CMatrix44f::Translate(const float3& pos)
{
+/*
CMatrix44f tm;
tm[12] = pos.x;
@@ -112,6 +184,15 @@
tm[14] = pos.z;
*this = Mul(tm);
+*/
+
+ const float x=pos.x;
+ const float y=pos.y;
+ const float z=pos.z;
+ m[12] += x*m[0] + y*m[4] + z*m[8];
+ m[13] += x*m[1] + y*m[5] + z*m[9];
+ m[14] += x*m[2] + y*m[6] + z*m[10];
+ m[15] += x*m[3] + y*m[7] + z*m[11];
}
@@ -148,24 +229,10 @@
float3 CMatrix44f::Mul(const float3& vect) const
{
-/* float3 res;
-
- for (int x = 0; x < 3; ++x) {
- res[x] = 0;
- for (int y = 0; y < 3; ++y) {
- res[x] += vect[y] * m[x * 4 + y];
- }
- }
-
- return res;
-/*/ const float v0(vect[0]), v1(vect[1]), v2(vect[2]);
- //return float3( v0*m[0] + v1*m[1] + v2*m[2] + m[3],
- // v0*m[4] + v1*m[5] + v2*m[6] + m[7],
- // v0*m[8] + v1*m[9] + v2*m[10] + m[11]);/**/
-
+ const float v0(vect[0]), v1(vect[1]), v2(vect[2]);
return float3( v0*m[0] + v1*m[4] + v2*m[8] + m[12],
- v0*m[1] + v1*m[5] + v2*m[9] + m[13],
- v0*m[2] + v1*m[6] + v2*m[10] + m[14]);/**/
+ v0*m[1] + v1*m[5] + v2*m[9] + m[13],
+ v0*m[2] + v1*m[6] + v2*m[10] + m[14]);
}
@@ -236,13 +303,8 @@
// m.Mul(m.Invert()) is identity
CMatrix44f CMatrix44f::Invert() const
{
- CMatrix44f mInv;
+ CMatrix44f mInv(*this);
- // copy m
- mInv[0] = m[0]; mInv[4] = m[4]; mInv[ 8] = m[ 8]; mInv[12] = m[12];
- mInv[1] = m[1]; mInv[5] = m[5]; mInv[ 9] = m[ 9]; mInv[13] = m[13];
- mInv[2] = m[2]; mInv[6] = m[6]; mInv[10] = m[10]; mInv[14] = m[14];
-
// transpose the rotation
mInv[1] = m[4]; mInv[4] = m[1];
mInv[2] = m[8]; mInv[8] = m[2];
Index: rts/System/Matrix44f.h
===================================================================
--- rts/System/Matrix44f.h (revision 5850)
+++ rts/System/Matrix44f.h (working copy)
@@ -10,6 +10,7 @@
CMatrix44f(void);
CMatrix44f(const float3& pos, const float3& x, const float3& y, const float3& z);
+ CMatrix44f(const CMatrix44f& n);
~CMatrix44f(void);
void LoadIdentity();
-
bumpwater.patch (23,466 bytes) 2008-05-10 16:30
Index: installer/builddata/bitmaps/README.txt
===================================================================
--- installer/builddata/bitmaps/README.txt (revision 5850)
+++ installer/builddata/bitmaps/README.txt (working copy)
@@ -65,3 +65,5 @@
tracks/ComTrack.bmp SJ
tracks/StdTank.bmp SJ
wake.tga Yeha
+waterbump.png jK
+caustics/* jK (with GPL app: http://www.lysator.liu.se/~kand/caustics/)
Index: rts/Lua/LuaConstGame.cpp
===================================================================
--- rts/Lua/LuaConstGame.cpp (revision 5850)
+++ rts/Lua/LuaConstGame.cpp (working copy)
@@ -85,8 +85,14 @@
LuaPushNamedColor(L, "waterBaseColor", mapInfo->water.baseColor);
LuaPushNamedColor(L, "waterMinColor", mapInfo->water.minColor);
LuaPushNamedColor(L, "waterSurfaceColor", mapInfo->water.surfaceColor);
+ LuaPushNamedNumber(L, "waterSurfaceAlpha", mapInfo->water.surfaceAlpha);
+ LuaPushNamedColor(L, "waterSpecularColor", mapInfo->water.specularColor);
+ LuaPushNamedNumber(L, "waterSpecularFactor", mapInfo->water.specularFactor);
LuaPushNamedColor(L, "waterPlaneColor", mapInfo->water.planeColor);
LuaPushNamedColor(L, "fogColor", fogColor);
+ LuaPushNamedColor(L, "groundAmbientColor", mapInfo->light.groundAmbientColor);
+ LuaPushNamedColor(L, "groundSpecularColor", mapInfo->light.groundSpecularColor);
+ LuaPushNamedColor(L, "groundSunColor", mapInfo->light.groundSunColor);
LuaPushNamedString(L, "modName", modInfo.humanName);
LuaPushNamedString(L, "modShortName", modInfo.shortName);
Index: rts/Map/MapInfo.cpp
===================================================================
--- rts/Map/MapInfo.cpp (revision 5850)
+++ rts/Map/MapInfo.cpp (working copy)
@@ -139,17 +139,46 @@
hasWaterPlane = !tmp.empty();
water.planeColor = mapDefParser->GetFloat3(float3(0.0f, 0.4f, 0.0f), "MAP\\WATER\\WaterPlaneColor");
+ mapDefParser->GetDef(water.fresnelMin,"0.2","MAP\\WATER\\FresnelMin");
+ mapDefParser->GetDef(water.fresnelMax,"0.3","MAP\\WATER\\FresnelMax");
+ mapDefParser->GetDef(water.fresnelPower,"4.0","MAP\\WATER\\FresnelPower");
+
+ mapDefParser->GetDef(water.specularFactor,"20.0","MAP\\WATER\\WaterSpecularFactor");
+
+ water.specularColor = mapDefParser->GetFloat3(light.groundSunColor,"MAP\\WATER\\WaterSpecularColor");
water.surfaceColor = mapDefParser->GetFloat3(float3(0.75f, 0.8f, 0.85f), "MAP\\WATER\\WaterSurfaceColor");
+ mapDefParser->GetDef(water.surfaceAlpha,"0.55","MAP\\WATER\\WaterSurfaceAlpha");
water.absorb = mapDefParser->GetFloat3(float3(0, 0, 0), "MAP\\WATER\\WaterAbsorb");
water.baseColor = mapDefParser->GetFloat3(float3(0, 0, 0), "MAP\\WATER\\WaterBaseColor");
water.minColor = mapDefParser->GetFloat3(float3(0, 0, 0), "MAP\\WATER\\WaterMinColor");
+
mapDefParser->GetDef(water.texture, "", "MAP\\WATER\\WaterTexture");
+ mapDefParser->GetDef(water.foamTexture, "", "MAP\\WATER\\WaterFoamTexture");
+ mapDefParser->GetDef(water.normalTexture, "", "MAP\\WATER\\WaterNormalTexture");
//default water is ocean.jpg in bitmaps, map specific water textures is saved in the map dir
if(water.texture.empty())
water.texture = "bitmaps/" + resources->SGetValueDef("ocean.jpg", "resources\\graphics\\maps\\watertex");
else
water.texture = "maps/" + water.texture;
+
+
+ if(water.foamTexture.empty())
+ water.foamTexture = "bitmaps/"+resources->SGetValueDef("foam.jpg","resources\\graphics\\maps\\waterfoamtex");
+ else
+ water.foamTexture = "maps/" + water.foamTexture;
+
+ if(water.normalTexture.empty())
+ water.normalTexture = "bitmaps/"+resources->SGetValueDef("waterbump.png","resources\\graphics\\maps\\waternormaltex");
+ else
+ water.normalTexture = "maps/" + water.normalTexture;
+
+ char num[10];
+ for (int i = 0; i < 32; i++) {
+ sprintf(num, "%02i", i);
+ water.causticTextures[i] = std::string("bitmaps/") + resources->SGetValueDef(std::string("caustics/caustic")+num+".jpg",
+ std::string("resources\\graphics\\caustics\\caustic")+num);
+ }
}
Index: rts/Map/MapInfo.h
===================================================================
--- rts/Map/MapInfo.h (revision 5850)
+++ rts/Map/MapInfo.h (working copy)
@@ -106,8 +106,17 @@
float3 baseColor;
float3 minColor;
float3 surfaceColor;
+ float surfaceAlpha;
float3 planeColor;
+ float3 specularColor;
+ float specularFactor;
+ float fresnelMin;
+ float fresnelMax;
+ float fresnelPower;
std::string texture;
+ std::string foamTexture;
+ std::string normalTexture;
+ std::string causticTextures[32];
} water;
bool hasWaterPlane; ///< true if "MAP\WATER\WaterPlaneColor" is set
Index: rts/Rendering/Env/BaseWater.cpp
===================================================================
--- rts/Rendering/Env/BaseWater.cpp (revision 5850)
+++ rts/Rendering/Env/BaseWater.cpp (working copy)
@@ -2,6 +2,7 @@
#include "BaseWater.h"
#include "BasicWater.h"
#include "AdvWater.h"
+#include "BumpWater.h"
#include "Rendering/GL/myGL.h"
#include "Platform/ConfigHandler.h"
#include "LogOutput.h"
@@ -42,6 +43,20 @@
return water;
}
}
+
+ if(configValue==4 && GLEW_ARB_shading_language_100) {
+ try {
+ water = SAFE_NEW CBumpWater;
+ } catch (content_error& e) {
+ delete water;
+ water = NULL;
+ logOutput.Print("Loading Bumpmapped Water failed");
+ logOutput.Print("Error: %s", e.what());
+ }
+ if (water) {
+ return water;
+ }
+ }
if(configValue==3 && GLEW_ARB_fragment_program && GLEW_ARB_texture_rectangle){
try {
Index: rts/Rendering/Env/BumpWater.cpp
===================================================================
--- rts/Rendering/Env/BumpWater.cpp (revision 0)
+++ rts/Rendering/Env/BumpWater.cpp (revision 0)
@@ -0,0 +1,468 @@
+/**
+ * @file BumpWater.cpp
+ * @brief extended bumpmapping water shader
+ * @author jK
+ *
+ * Copyright (C) 2008. Licensed under the terms of the
+ * GNU GPL, v2 or later.
+ */
+
+#include "StdAfx.h"
+#include "bitops.h"
+#include "FileSystem/FileHandler.h"
+#include "BumpWater.h"
+#include "Game/Game.h"
+#include "Rendering/GL/myGL.h"
+#include "Rendering/Textures/Bitmap.h"
+#include "Game/Camera.h"
+#include "Map/MapInfo.h"
+#include "Map/ReadMap.h"
+#include "LogOutput.h"
+#include "Map/BaseGroundDrawer.h"
+#include "BaseSky.h"
+#include "Rendering/UnitModels/UnitDrawer.h"
+#include "Sim/Projectiles/ProjectileHandler.h"
+#include "Sim/Features/FeatureHandler.h"
+#include "Lua/LuaCallInHandler.h"
+#include "System/Platform/ConfigHandler.h"
+#include <boost/format.hpp>
+
+using std::string;
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+extern GLfloat FogLand[];
+
+
+void PrintLog(GLuint obj)
+{
+ int infologLength = 0;
+ int maxLength;
+
+ if(glIsShader(obj))
+ glGetShaderiv(obj,GL_INFO_LOG_LENGTH,&maxLength);
+ else
+ glGetProgramiv(obj,GL_INFO_LOG_LENGTH,&maxLength);
+
+ char infoLog[maxLength];
+
+ if (glIsShader(obj))
+ glGetShaderInfoLog(obj, maxLength, &infologLength, infoLog);
+ else
+ glGetProgramInfoLog(obj, maxLength, &infologLength, infoLog);
+
+ if (infologLength > 0)
+ throw content_error(string("BumpWater shader error: "+string(infoLog,infologLength)));
+}
+
+
+void PrintFboError(GLenum error)
+{
+ switch(error) {
+ case GL_FRAMEBUFFER_COMPLETE_EXT:
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
+ logOutput.Print("BumpWater-FBO: missing a required image/buffer attachment!");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
+ logOutput.Print("BumpWater-FBO: has no images/buffers attached!");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
+ logOutput.Print("BumpWater-FBO: has mismatched image/buffer dimensions!");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
+ logOutput.Print("BumpWater-FBO: colorbuffer attachments have different types!");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
+ logOutput.Print("BumpWater-FBO: trying to draw to non-attached color buffer!");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
+ logOutput.Print("BumpWater-FBO: trying to read from a non-attached color buffer!");
+ break;
+ case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+ logOutput.Print("BumpWater-FBO: format is not supported by current graphics card/driver!");
+ break;
+ default:
+ logOutput.Print("BumpWater-FBO: *UNKNOWN ERROR*");
+ break;
+ }
+}
+
+string LoadShaderSource(const string& file)
+{
+ CFileHandler fh(file);
+ if (!fh.FileExists())
+ throw content_error("Can't load shader " + file);
+
+ string text;
+ text.resize(fh.FileSize());
+ //char* cstr = SAFE_NEW char[fh.FileSize()+1];
+
+ fh.Read(&text[0], text.length());
+ //fh.Read(cstr,fh.FileSize());
+ //cstr[fh.FileSize()] = 0;
+
+ return text;
+}
+
+void GLSLDefineConstf4(string& str, const string& name, const float3& v, const float& alpha)
+{
+ str += boost::str(boost::format(string("#define ")+name+" vec4(%1$.12f,%2$.12f,%3$.12f,%4$.12f)\n") % (v.x) % (v.y) % (v.z) % (alpha));
+}
+
+void GLSLDefineConstf3(string& str, const string& name, const float3& v)
+{
+ str += boost::str(boost::format(string("#define ")+name+" vec3(%1$.12f,%2$.12f,%3$.12f)\n") % (v.x) % (v.y) % (v.z));
+}
+
+void GLSLDefineConstf2(string& str, const string& name, const float& x, const float& y)
+{
+ str += boost::str(boost::format(string("#define ")+name+" vec2(%1$.12f,%2$.12f)\n") % x % y);
+}
+
+void GLSLDefineConstf1(string& str, const string& name, const float& x)
+{
+ str += boost::str(boost::format(string("#define ")+name+" %1$.12f\n") % x);
+}
+
+GLuint LoadTexture(const string& filename)
+{
+ GLuint texID;
+ CBitmap bm;
+ if (!bm.Load(filename))
+ throw content_error("Could not load texture from file "+filename);
+
+ glGenTextures(1, &texID);
+ glBindTexture(GL_TEXTURE_2D, texID);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 3.0f);
+ glBuildMipmaps(GL_TEXTURE_2D, GLEW_ARB_texture_compression?GL_COMPRESSED_RGB_ARB:GL_RGB8, bm.xsize, bm.ysize, GL_RGBA, GL_UNSIGNED_BYTE, bm.mem);
+ return texID;
+}
+
+CBumpWater::CBumpWater()
+{
+ reflTexSize = next_power_of_2(configHandler.GetInt("BumpWaterTexSizeReflection", 256));
+ reflection = !!configHandler.GetInt("BumpWaterReflection", 1);
+ refraction = configHandler.GetInt("BumpWaterRefraction", 1); //0:=off, 1:=screencopy, 2:=own rendering cycle
+ waves = !!configHandler.GetInt("BumpBeachWaves", 1);
+
+ if (!GLEW_EXT_framebuffer_object) {
+ reflection = false;
+ }
+
+ if (refraction>0) {
+ // CREATE REFRACTION TEXTURE
+ glGenTextures(1, &refractTexture);
+ //if(GLEW_ARB_texture_non_power_of_two || GLEW_EXT_texture_non_power_of_two)
+ // target = GL_TEXTURE_2D;
+ //else //if(GLEW_ARB_texture_rectangle || GLEW_EXT_texture_rectangle)
+ target = GL_TEXTURE_RECTANGLE_ARB;
+ glBindTexture(target, refractTexture);
+ glTexParameteri(target,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
+ glTexParameteri(target,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
+ if (GLEW_EXT_texture_edge_clamp) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ } else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ }
+ if(target == GL_TEXTURE_RECTANGLE_ARB) {
+ refrSizeX = gu->viewSizeX;
+ refrSizeY = gu->viewSizeY;
+ } else{
+ refrSizeX = next_power_of_2(gu->viewSizeX);
+ refrSizeY = next_power_of_2(gu->viewSizeY);
+ }
+ glTexImage2D(target, 0, GL_RGB8, refrSizeX, refrSizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
+ }
+
+ if (reflection) {
+ // CREATE REFLECTION TEXTURE
+ glGenTextures(1, &reflectTexture);
+ glBindTexture(GL_TEXTURE_2D, reflectTexture);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+ if (GLEW_EXT_texture_edge_clamp) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ } else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ }
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, reflTexSize, reflTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ // CREATE DEPTH RBO FOR REFLECTION FBO
+ glGenRenderbuffersEXT(1, &rbo);
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, reflTexSize, reflTexSize);
+
+ // CREATE REFLECTION FBO AND BIND TEXTURE&RBO
+ glGenFramebuffersEXT(1,&fbo);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, reflectTexture, 0);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo);
+ GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ PrintFboError(status);
+ //logOutput.Print("BumpWater: FBO not ready");
+ }
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
+
+
+ foamTexture = LoadTexture( mapInfo->water.foamTexture );
+ normalTexture = LoadTexture( mapInfo->water.normalTexture );
+ for (int i = 0; i < 32; i++) {
+ caustTextures[i] = LoadTexture( mapInfo->water.causticTextures[i] );
+ }
+
+ //heightTexture = readmap->GetShadingTexture();
+ /*
+
+ */
+
+ /* DEFINE SOME RUNTIME CONSTANTS (I don't use Uniforms for that, 'cos the glsl compiler can't optimize those!) */
+ string definitions;
+ if (reflection) definitions += "#define use_reflection\n";
+ if (refraction>0) definitions += "#define use_refraction\n\n";
+ GLSLDefineConstf4(definitions, "SurfaceColor", mapInfo->water.surfaceColor*0.4, mapInfo->water.surfaceAlpha );
+ GLSLDefineConstf3(definitions, "SpecularColor", mapInfo->water.specularColor );
+ GLSLDefineConstf1(definitions, "SpecularFactor", mapInfo->water.specularFactor);
+ GLSLDefineConstf3(definitions, "SunDir", mapInfo->light.sunDir );
+ GLSLDefineConstf3(definitions, "MapMid", float3(readmap->width*SQUARE_SIZE*0.5f,0.0f,readmap->height*SQUARE_SIZE*0.5f) );
+ GLSLDefineConstf2(definitions, "ScreenInverse", -1.0f/gu->viewSizeX, 1.0f/gu->viewSizeY );
+ GLSLDefineConstf2(definitions, "ViewPos", gu->viewPosX,gu->viewPosY );
+ GLSLDefineConstf1(definitions, "FresnelMin", mapInfo->water.fresnelMin);
+ GLSLDefineConstf1(definitions, "FresnelMax", mapInfo->water.fresnelMax);
+ GLSLDefineConstf1(definitions, "FresnelPower", mapInfo->water.fresnelPower);
+
+ /* LOAD SHADERS */
+ string vsSource = LoadShaderSource("shaders/bumpWaterVS.glsl");
+ string fsSource = LoadShaderSource("shaders/bumpWaterFS.glsl");
+
+ vector<GLint> lengths(2);
+ vector<const GLchar*> strings(2);
+ lengths[0]=definitions.length();
+ strings[0]=definitions.c_str();
+
+ waterVP = glCreateShader(GL_VERTEX_SHADER);
+ lengths[1]=vsSource.length();
+ strings[1]=vsSource.c_str();
+ glShaderSource(waterVP, strings.size(), &strings.front(), &lengths.front());
+ glCompileShader(waterVP);
+ PrintLog(waterVP);
+
+ waterFP = glCreateShader(GL_FRAGMENT_SHADER);
+ lengths[1]= fsSource.length();
+ strings[1] = fsSource.c_str();
+ glShaderSource(waterFP, strings.size(), &strings.front(), &lengths.front());
+ glCompileShader(waterFP);
+ PrintLog(waterFP);
+
+ //delete vsSource; delete fsSource;
+
+ waterShader = glCreateProgram();
+ glAttachShader(waterShader, waterVP);
+ glAttachShader(waterShader, waterFP);
+ glLinkProgram(waterShader);
+ PrintLog(waterShader);
+
+ /* BIND TEXTURE UNIFORMS */
+ glUseProgram(waterShader);
+ eyePosLoc = glGetUniformLocation(waterShader, "eyePos");
+ frameLoc = glGetUniformLocation(waterShader, "frame");
+ normalmapLoc = glGetUniformLocation(waterShader, "normalmap");
+ heightmapLoc = glGetUniformLocation(waterShader, "heightmap");
+ causticLoc = glGetUniformLocation(waterShader, "caustic");
+ foamLoc = glGetUniformLocation(waterShader, "foam");
+ reflectionLoc = glGetUniformLocation(waterShader, "reflection");
+ refractionLoc = glGetUniformLocation(waterShader, "refraction");
+
+ glUniform1i(normalmapLoc, 0);
+ glUniform1i(heightmapLoc, 1);
+ glUniform1i(causticLoc, 2);
+ glUniform1i(foamLoc, 3);
+ glUniform1i(reflectionLoc, 4);
+ glUniform1i(refractionLoc, 5);
+ glUseProgram(0);
+}
+
+CBumpWater::~CBumpWater()
+{
+ if (reflection) {
+ glDeleteTextures(1, &reflectTexture);
+ glDeleteRenderbuffersEXT(1, &rbo);
+ glDeleteFramebuffersEXT(1, &fbo);
+ }
+ if (refraction>0)
+ glDeleteTextures(1, &refractTexture);
+
+ glDeleteTextures(1, &foamTexture);
+ glDeleteTextures(32, caustTextures);
+ glDeleteTextures(1, &normalTexture);
+
+ glDeleteShader(waterVP);
+ glDeleteShader(waterFP);
+ glDeleteProgram(waterShader);
+}
+
+void CBumpWater::Draw()
+{
+ if(readmap->minheight>10)
+ return;
+
+ if (refraction == 1) {
+ // _SCREENCOPY_ REFRACT TEXTURE
+ glBindTexture(target, refractTexture);
+ glEnable(target);
+ glCopyTexSubImage2D(target, 0, 0, 0, gu->viewPosX, 0, gu->viewSizeX, gu->viewSizeY);
+ glDisable(target);
+ }
+
+ glDisable(GL_ALPHA_TEST);
+ if (refraction>0)
+ glDisable(GL_BLEND);
+ if (refraction<2)
+ glDepthMask(0);
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, readmap->GetShadingTexture());
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, caustTextures[gs->frameNum%32]);
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(GL_TEXTURE_2D, foamTexture);
+ glActiveTexture(GL_TEXTURE4);
+ glBindTexture(GL_TEXTURE_2D, reflectTexture);
+ glActiveTexture(GL_TEXTURE5);
+ glBindTexture(target, refractTexture);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, normalTexture);
+
+ glUseProgram(waterShader);
+ glUniform1f(frameLoc,gs->frameNum/15000.0f);
+ glUniformf3(eyePosLoc,camera->pos);
+
+ glBegin(GL_QUADS);
+ glTexCoord4f(0.0f,0.0f,0.0f,0.0f);
+ glVertex3i(0,0,0);
+ glTexCoord4f(0.0f,1.0f,0.0f,(float)gs->mapy/gs->pwr2mapy);
+ glVertex3i(0,0,readmap->height*SQUARE_SIZE);
+ glTexCoord4f(1.0f,1.0f,(float)gs->mapx/gs->pwr2mapx,(float)gs->mapy/gs->pwr2mapy);
+ glVertex3i(readmap->width*SQUARE_SIZE,0,readmap->height*SQUARE_SIZE);
+ glTexCoord4f(1.0f,0.0f,(float)gs->mapx/gs->pwr2mapx,0.0f);
+ glVertex3i(readmap->width*SQUARE_SIZE,0,0);
+ glEnd();
+
+ glUseProgram(0);
+
+ if (refraction<2)
+ glDepthMask(1);
+}
+
+void CBumpWater::UpdateWater(CGame* game)
+{
+ if (readmap->minheight > 10 || mapInfo->map.voidWater)
+ return;
+
+ if (refraction>1) DrawRefraction(game);
+ if (reflection) DrawReflection(game);
+}
+
+void CBumpWater::DrawRefraction(CGame* game)
+{
+ // _RENDER_ REFRACTION TEXTURE
+ drawRefraction=true;
+ camera->Update(false);
+ glViewport(0,0,refrSizeX,refrSizeY);
+
+ glClearColor(FogLand[0],FogLand[1],FogLand[2],1);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ float3 oldsun=unitDrawer->unitSunColor;
+ float3 oldambient=unitDrawer->unitAmbientColor;
+
+ unitDrawer->unitSunColor*=float3(0.5f,0.7f,0.9f);
+ unitDrawer->unitAmbientColor*=float3(0.6f,0.8f,1.0f);
+
+ game->SetDrawMode(CGame::refractionDraw);
+
+ glEnable(GL_CLIP_PLANE2);
+ double plane[4]={0,-1,0,2};
+ glClipPlane(GL_CLIP_PLANE2 ,plane);
+ drawReflection=true;
+
+ readmap->GetGroundDrawer()->Draw();
+ unitDrawer->Draw(false,true);
+ featureHandler->Draw();
+ drawReflection=false;
+ ph->Draw(false,true);
+ luaCallIns.DrawWorldRefraction();
+
+ glDisable(GL_CLIP_PLANE2);
+ game->SetDrawMode(CGame::normalDraw);
+ drawRefraction=false;
+
+ glBindTexture(target, refractTexture);
+ glEnable(target);
+ glCopyTexSubImage2D(target,0,0,0,0,0,refrSizeX,refrSizeY);
+ glDisable(target);
+
+ glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
+ glClearColor(FogLand[0],FogLand[1],FogLand[2],1);
+
+ unitDrawer->unitSunColor=oldsun;
+ unitDrawer->unitAmbientColor=oldambient;
+}
+
+void CBumpWater::DrawReflection(CGame* game)
+{
+ // CREATE REFLECTION TEXTURE
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
+
+ CCamera *realCam = camera;
+ camera = new CCamera(*realCam);
+ camera->up.x=0;
+ camera->up.y=1;
+ camera->up.z=0;
+ camera->forward.y*=-1;
+ camera->pos.y*=-1;
+ camera->Update(false);
+
+ glViewport(0,0,reflTexSize,reflTexSize);
+
+ glClearColor(0.2f,0.4f,0.2f,1);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ game->SetDrawMode(CGame::reflectionDraw);
+
+ sky->Draw();
+
+ glEnable(GL_CLIP_PLANE2);
+ double plane[4]={0,1,0,0}; // make angle dependent?
+ glClipPlane(GL_CLIP_PLANE2 ,plane);
+ drawReflection=true;
+
+ readmap->GetGroundDrawer()->Draw(true);
+ unitDrawer->Draw(true);
+ featureHandler->Draw();
+ ph->Draw(true);
+ luaCallIns.DrawWorldReflection();
+
+ game->SetDrawMode(CGame::normalDraw);
+ drawReflection=false;
+ glDisable(GL_CLIP_PLANE2);
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
+ glClearColor(FogLand[0],FogLand[1],FogLand[2],1);
+
+ delete camera;
+ camera = realCam;
+ camera->Update(false);
+}
Index: rts/Rendering/Env/BumpWater.h
===================================================================
--- rts/Rendering/Env/BumpWater.h (revision 0)
+++ rts/Rendering/Env/BumpWater.h (revision 0)
@@ -0,0 +1,68 @@
+// BumpWater.h: interface for the CBumpWater class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef __BUMP_WATER_H__
+#define __BUMP_WATER_H__
+
+#include "Rendering/GL/myGL.h"
+#include "BaseWater.h"
+
+class CBumpWater : public CBaseWater
+{
+public:
+ void UpdateWater(CGame* game);
+ void DrawReflection(CGame* game);
+ void DrawRefraction(CGame* game);
+ void Draw();
+ CBumpWater();
+ virtual ~CBumpWater();
+ virtual int GetID() const { return 4; }
+
+ // user options
+ bool reflection;
+ char refraction; //0:=off, 1:=screencopy, 2:=own rendering cycle
+ int reflTexSize;
+ bool waves;
+
+ // map options
+ float3 surfaceColor;
+ float3 specularColor;
+
+ int refrSizeX;
+ int refrSizeY;
+
+ unsigned int target; // of the refract texture
+ GLuint refractTexture;
+ GLuint reflectTexture;
+ GLuint rbo;
+ GLuint fbo;
+
+ GLuint foamTexture;
+ GLuint normalTexture;
+ GLuint caustTextures[32];
+ GLuint* heightTexture;
+
+ GLuint waterFP;
+ GLuint waterVP;
+ GLuint waterShader;
+
+ GLuint midPosLoc;
+ GLuint eyePosLoc;
+ GLuint lightDirLoc;
+ GLuint fresnelMinLoc;
+ GLuint fresnelMaxLoc;
+ GLuint fresnelPowerLoc;
+ GLuint frameLoc;
+ GLuint screenInverseLoc;
+ GLuint viewPosLoc;
+ GLuint normalmapLoc;
+ GLuint heightmapLoc;
+ GLuint causticLoc;
+ GLuint foamLoc;
+ GLuint reflectionLoc;
+ GLuint refractionLoc;
+};
+
+#endif // __BUMP_WATER_H__
+
-
bumpwater.zip (252,411 bytes) 2008-05-10 16:42
|
---|