Author Topic: c++ PMS parser  (Read 6440 times)

0 Members and 1 Guest are viewing this topic.

Offline mar77a

  • Global Moderator
  • Veteran
  • *****
  • Posts: 1295
  • mad
    • random stuffs
c++ PMS parser
« on: December 14, 2007, 03:31:37 pm »
Here's the header:

Code: [Select]
#include <iostream>
#include <vector>
#include <string>

// Typedefs
typedef          char    CHAR ;
typedef unsigned __int8  UBYTE ;
typedef          UBYTE   ubyte ;
typedef unsigned __int16 WORD ;
typedef          WORD    word ;
typedef unsigned __int16 USHORT ;
typedef          USHORT  ushort ;
typedef          short   SHORT ;
typedef unsigned __int32 DWORD ;
typedef          DWORD   dword ;
typedef          long    LONG ;
typedef unsigned __int32 ULONG ;
typedef          ULONG   ulong ;
typedef signed   __int64 QUAD ;
typedef          QUAD    quad ;
typedef unsigned __int64 UQUAD ;
typedef          UQUAD   uquad ;
typedef          float   FLOAT ;
typedef          double  DOUBLE ;

//prims
template<class T>
T read_bin(std::istream& is)
{
    T tmp;
    is.read( reinterpret_cast<char*>( &tmp ), sizeof( T ) );
    return tmp;
}

std::string read_string( std::istream& is, int full_length )
{
    int length = read_bin<CHAR>( is );
    std::vector<CHAR> tmp( full_length );
    is.read( &tmp[0], tmp.size() );
    return std::string( tmp.begin(), tmp.begin() + length );
}

// Basic aux structures
typedef enum TF {
F = 0,
T
} BOOL_PMS;

typedef enum POLYTYPE {
ptNORMAL = 0,
ptONLY_BULLETS_COLLIDE,
ptONLY_PLAYERS_COLLIDE,
ptNO_COLLIDE,
ptICE,
ptDEADLY,
ptBLOODY_DEADLY,
ptHURTS,
ptREGENERATES,
ptLAVA
} PMS_POLYTYPE;

typedef enum DRAWBEHIND {
dbBEHIND_ALL = 0,
dbBEHIND_MAP,
dbBEHIND_NONE
} PMS_DRAWBEHIND;

typedef enum SPECIALACTIONS {
saNONE = 0,
saSTOP_AND_CAMP,
saWAIT_1_SECOND,
saWAIT_5_SECONDS,
saWAIT_10_SECONDS,
saWAIT_15_SECONDS,
saWAIT_20_SECONDS
} PMS_SPECIALACTIONS;

typedef enum WEATHERTYPE {
wtNONE = 0,
wtRAIN,
wtSANDSTORM,
wtSNOW
} PMS_WEATHERTYPE;

typedef enum STEPSTYPE {
stHARD_GROUND = 0,
stSOFT_GROUND,
stNONE
} PMS_STEPSTYPE;

typedef enum SPAWNTEAM {
stGENERAL = 0,
stALPHA,
stBRAVO,
stCHARLIE,
stDELTA,
stALPHA_FLAG,
stBRAVO_FLAG,
stGRENADES,
stMEDKITS,
stCLUSTERS,
stVEST,
stFLAMER,
stBERSERKER,
stPREDATOR,
stYELLOW_FLAG,
stRAMBO_BOW,
stSTAT_GUN
} PMS_SPAWNTEAM;

typedef struct tagPMS_VECTOR {
FLOAT x;
FLOAT y;
FLOAT z;
} PMS_VECTOR;

typedef struct tagPMS_COLOR {
UBYTE blue;
UBYTE green;
UBYTE red;
UBYTE alpha;
} PMS_COLOR;

// more stuff

typedef struct tagPMS_VERTEX {
FLOAT x;
FLOAT y;
FLOAT z;
FLOAT rhw;
PMS_COLOR color;
FLOAT tu;
FLOAT tv;
} PMS_VERTEX;

typedef struct tagPMS_POLYGON {
PMS_VERTEX vertex[3];
PMS_VECTOR perpendicular[3];
PMS_POLYTYPE polyType;
} PMS_POLYGON;

typedef struct tagPMS_SECTOR {
WORD polyCount;
std::vector<WORD> polys;
} PMS_SECTOR;

typedef struct tagPMS_PROP {
BOOL_PMS active;
UBYTE filler1;
WORD style;
LONG width;
LONG height;
FLOAT x;
FLOAT y;
FLOAT rotation;
FLOAT scaleX;
FLOAT scaleY;
UBYTE alpha;
UBYTE filler2[3];
PMS_COLOR color;
PMS_DRAWBEHIND level;
UBYTE filler3[3];
} PMS_PROP;

typedef struct tagDOSTIME {
WORD second  : 5; 
WORD minute : 6;   
WORD hour    : 5;   
} DOSTIME;

typedef struct tagDOSDATE {
WORD day  : 5; 
WORD month : 4;   
WORD year    : 7;   
} DOSDATE;

typedef struct tagPMS_TIMESTAMP {
DOSTIME time;
DOSDATE date;
} PMS_TIMESTAMP;

typedef struct tagPMS_SCENERY {
UBYTE nameLen;
std::string name;
PMS_TIMESTAMP timestamp;
} PMS_SCENERY;

typedef struct tagPMS_COLLIDER {
BOOL_PMS active;
UBYTE filler[3];
FLOAT x;
FLOAT y;
FLOAT radius;
} PMS_COLLIDER;

typedef struct tagPMS_SPAWNPOINT {
BOOL_PMS active;
UBYTE filler[3];
LONG x;
LONG y;
PMS_SPAWNTEAM team;
} PMS_SPAWNPOINT;

typedef struct tagPMS_WAYPOINT {
BOOL_PMS active;
UBYTE filler1[3];
LONG id;
LONG x;
LONG y;
BOOL_PMS left;
BOOL_PMS right;
BOOL_PMS up;
BOOL_PMS down;
BOOL_PMS jet;
UBYTE path;
PMS_SPECIALACTIONS specialAction;
UBYTE c2;
UBYTE c3;
UBYTE filler2[3];
LONG numConnections;
LONG connections[20];
} PMS_WAYPOINT;

// Pms structure

struct pms
{
    LONG version;
    std::string name;
    std::string texture;
    // these aren't in the map data, but rather calculated on the fly
    FLOAT leftoffs;
    FLOAT rightoffs;
    FLOAT topoffs;
    FLOAT bottomoffs;
    // end
    PMS_COLOR bgColorTop;
    PMS_COLOR bgColorBottom;
    LONG jetAmount;
    UBYTE grenades;
UBYTE medikits;
PMS_WEATHERTYPE weather;
PMS_STEPSTYPE steps;
LONG randID;
    LONG polygonCount;
    std::vector<PMS_POLYGON> polygon;
    LONG sectorDivisions;
    LONG numSectors;
    std::vector<PMS_SECTOR> sector;
LONG propCount;
std::vector<PMS_PROP> prop;
LONG sceneryCount;
std::vector<PMS_SCENERY> scenery;
LONG colliderCount;
std::vector<PMS_COLLIDER> collider;
LONG spawnpointCount;
std::vector<PMS_SPAWNPOINT> spawnpoint;
LONG waypointCount;
std::vector<PMS_WAYPOINT> waypoint;
};

// Reader

std::istream& operator>>( std::istream& is, pms& p )
{
    p.version = read_bin<int>( is );
    p.name = read_string( is, 38 );
    p.texture = read_string( is, 24 );
    p.bgColorTop = read_bin<PMS_COLOR>( is );
    p.bgColorBottom = read_bin<PMS_COLOR>( is );
    p.jetAmount = read_bin<LONG>( is );
    p.grenades = read_bin<UBYTE>( is );
    p.medikits = read_bin<UBYTE>( is );
    p.weather = PMS_WEATHERTYPE(read_bin<UBYTE>( is ));
    p.steps = PMS_STEPSTYPE(read_bin<UBYTE>( is ));
    p.randID = read_bin<LONG>( is );
    p.polygonCount = read_bin<LONG>( is );
    for(int i = 0;i<p.polygonCount;i++)
{
PMS_POLYGON temp; // cheap solution
temp.vertex[0] = read_bin<PMS_VERTEX>( is );
temp.vertex[1] = read_bin<PMS_VERTEX>( is );
temp.vertex[2] = read_bin<PMS_VERTEX>( is );
// calculate stuff
for(int m = 0;m < 3;m++){
if(temp.vertex[m].x > p.rightoffs)
p.rightoffs = temp.vertex[m].x;
if(temp.vertex[m].x < p.leftoffs)
p.leftoffs = temp.vertex[m].x;
// remember teh y axis is inverted
if(temp.vertex[m].y > p.bottomoffs)
p.bottomoffs = temp.vertex[m].y;
if(temp.vertex[m].y < p.topoffs)
p.topoffs = temp.vertex[m].y;
}
temp.perpendicular[0] = read_bin<PMS_VECTOR>( is );
temp.perpendicular[1] = read_bin<PMS_VECTOR>( is );
temp.perpendicular[2] = read_bin<PMS_VECTOR>( is );
temp.polyType = PMS_POLYTYPE(read_bin<UBYTE>( is ));
p.polygon.push_back(temp);
}
p.sectorDivisions = read_bin<LONG>( is );
p.numSectors = read_bin<LONG>( is );
for(int i = 0;i< ((p.numSectors*2)+1)*((p.numSectors*2)+1);i++){
PMS_SECTOR temp;
temp.polyCount = read_bin<WORD>( is );
for(int m = 0;m<temp.polyCount;m++){
temp.polys.push_back(read_bin<WORD>( is ));
}
p.sector.push_back(temp);
}
p.propCount = read_bin<LONG>( is );
for(int i = 0;i < p.propCount;i++){
PMS_PROP temp;
temp.active = BOOL_PMS(read_bin<UBYTE>( is ));
temp.filler1 = read_bin<UBYTE>( is );
temp.style = read_bin<WORD>( is );
temp.width = read_bin<LONG>( is );
temp.height = read_bin<LONG>( is );
temp.x = read_bin<FLOAT>( is );
temp.y = read_bin<FLOAT>( is );
temp.rotation = read_bin<FLOAT>( is );
temp.scaleX = read_bin<FLOAT>( is );
temp.scaleY = read_bin<FLOAT>( is );
temp.alpha = read_bin<UBYTE>( is );
temp.filler2[0] = read_bin<UBYTE>( is );
temp.filler2[1] = read_bin<UBYTE>( is );
temp.filler2[2] = read_bin<UBYTE>( is );
temp.color = read_bin<PMS_COLOR>( is );
temp.level = PMS_DRAWBEHIND(read_bin<UBYTE>( is ));
temp.filler3[0] = read_bin<UBYTE>( is );
temp.filler3[1] = read_bin<UBYTE>( is );
temp.filler3[2] = read_bin<UBYTE>( is );
p.prop.push_back(temp);
}
p.sceneryCount = read_bin<LONG>( is );
for(int i = 0;i < p.sceneryCount;i++){
PMS_SCENERY temp;
temp.name = read_string(is, 50);
temp.timestamp = read_bin<PMS_TIMESTAMP>( is );
p.scenery.push_back(temp);
}
p.colliderCount = read_bin<LONG>( is );
for(int i = 0;i < p.colliderCount;i++){
PMS_COLLIDER temp;
temp.active = BOOL_PMS(read_bin<UBYTE>( is ));
temp.filler[0] = read_bin<UBYTE>( is );
temp.filler[1] = read_bin<UBYTE>( is );
temp.filler[2] = read_bin<UBYTE>( is );
temp.x = read_bin<FLOAT>( is );
temp.y = read_bin<FLOAT>( is );
temp.radius = read_bin<FLOAT>( is );
p.collider.push_back(temp);
}
p.spawnpointCount = read_bin<LONG>( is );
for(int i = 0;i < p.spawnpointCount;i++){
  PMS_SPAWNPOINT temp;
  temp.active = BOOL_PMS(read_bin<UBYTE>( is ));
  temp.filler[0] = read_bin<UBYTE>( is );
  temp.filler[1] = read_bin<UBYTE>( is );
  temp.filler[2] = read_bin<UBYTE>( is );
  temp.x = read_bin<LONG>( is );
  temp.y = read_bin<LONG>( is );
  temp.team = PMS_SPAWNTEAM(read_bin<ULONG>( is ));
  p.spawnpoint.push_back(temp);
}
p.waypointCount = read_bin<LONG>( is );
for(int i = 0;i < p.waypointCount;i++){
PMS_WAYPOINT temp;
temp.active = BOOL_PMS(read_bin<UBYTE>( is ));
temp.filler1[0] = read_bin<UBYTE>( is );
temp.filler1[1] = read_bin<UBYTE>( is );
temp.filler1[2] = read_bin<UBYTE>( is );
temp.id = read_bin<LONG>( is );
temp.x = read_bin<LONG>( is );
temp.y = read_bin<LONG>( is );
temp.left = BOOL_PMS(read_bin<UBYTE>( is ));
temp.right = BOOL_PMS(read_bin<UBYTE>( is ));
temp.up = BOOL_PMS(read_bin<UBYTE>( is ));
temp.down = BOOL_PMS(read_bin<UBYTE>( is ));
temp.jet = BOOL_PMS(read_bin<UBYTE>( is ));
temp.path = read_bin<UBYTE>( is );
temp.specialAction = PMS_SPECIALACTIONS(read_bin<UBYTE>( is ));
temp.c2 = read_bin<UBYTE>( is );
temp.c3 = read_bin<UBYTE>( is );
temp.filler2[0] = read_bin<UBYTE>( is );
temp.filler2[1] = read_bin<UBYTE>( is );
temp.filler2[2] = read_bin<UBYTE>( is );
temp.numConnections = read_bin<LONG>( is );
for(int c=0;c<20;c++){
temp.connections[c] = read_bin<LONG>( is );
}
p.waypoint.push_back(temp);
}
    return is;
}

Here's a silly OpenGL implementation which is far from useful:

Code: [Select]
#include <gl\gl.h>
#include <gl\glut.h>
#include <math.h>
// this is the header posted above
#include "mapc.h"
using namespace std;

// prototypes for callback funcs
void init(void);
void display(void);
void keyboard(unsigned char, int, int);
// other
void glColor4fb(float,float,float,float);

// global variables is the way with
// this gay callbacks...what a shame
pms *pmap;
float sfactor = 1.0;
float my = 0;
float mx = 0;
int screen_w = 500;
int screen_h = 500;

int main (int argc, char *argv[])
{
if(argc != 2){
return 0;
}
  // init glut/opengl
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(screen_w, screen_h);
glutInitWindowPosition(-1, -1);
// texture stuff
glEnable(GL_BLEND);
// open the map in question
ifstream mapf(argv[1],ios::binary);
pms map;
// read it and stuff
pmap = &map;
mapf >> map;
mapf.close();
  // it's some kind of magic
glutCreateWindow(pmap->name.c_str());
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutKeyboardFunc(keyboard);

glutMainLoop();
return 0;
}

void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluOrtho2D(-3000.0, 3000.0, -3000.0, 3000.0);
}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
// draw the bg
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
// this is once again reverted ...poor coding probably!
glColor4fb(pmap->bgColorBottom.red,pmap->bgColorBottom.green,pmap->bgColorBottom.blue,pmap->bgColorBottom.alpha);
glVertex2f(pmap->leftoffs, pmap->topoffs);
glVertex2f(pmap->rightoffs, pmap->topoffs);
glColor4fb(pmap->bgColorTop.red,pmap->bgColorTop.green,pmap->bgColorTop.blue,pmap->bgColorTop.alpha);
glVertex2f(pmap->rightoffs, pmap->bottomoffs);
glVertex2f(pmap->leftoffs, pmap->bottomoffs);
glEnd();
glColor3f(0.0, 0.0, 1.0);

// texture stuff was allocated on init and on map read
glBegin(GL_TRIANGLES);
for(int i = 0;i<pmap->polygonCount;i++){
for(int m = 0;m < 3;m++){
//color
glColor4fb(pmap->polygon[i].vertex[m].color.red,pmap->polygon[i].vertex[m].color.green,pmap->polygon[i].vertex[m].color.blue,pmap->polygon[i].vertex[m].color.alpha);
// texture

// position: the y axis is reversed in the map coords
glVertex3f(pmap->polygon[i].vertex[m].x,-1.0*pmap->polygon[i].vertex[m].y,0.0);
}
}
glEnd();
glScalef(sfactor,sfactor,sfactor);
glTranslatef(mx,my,0.0);
sfactor = 1.0;
mx = 0; my = 0;
glutSwapBuffers();
glFlush();
}

// converts from 0-255 notation to opengl's [0,1]
void glColor4fb(float r ,float g ,float b,float a)
{
glColor4f(r/255.0,g/255.0,b/255,a/255.0);
}

void keyboard(unsigned char key, int x, int y) {
switch(key){
case 'q':
sfactor = 1.1;
break;
case 'e':
sfactor = 0.9;
break;
case 'w':
my = -10.0;
break;
case 's':
my = 10.0;
break;
case 'a':
mx = 10.0;
break;
case 'd':
mx = -10.0;
break;
}
// re paint
glutPostRedisplay();
}

Thanks to ChrisGBK for the map file structure in http://devs.soldat.pl/Map . Feel free to do whatever you want with it.

Also, these files were compiled using mingw32 (from dev-cpp) under windows98se. The compiler params should include '-lglut32 -lglu32 -lopengl32 -lgdi32' if you want to build everything properly.
« Last Edit: December 14, 2007, 03:40:14 pm by mar77a »

Offline FliesLikeABrick

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 6144
    • Ultimate 13 Soldat
Re: c++ PMS parser
« Reply #1 on: December 14, 2007, 04:51:07 pm »
has this been added to the wiki somewhere?

Offline urraka

  • Soldat Developer
  • Flagrunner
  • ******
  • Posts: 703
Re: c++ PMS parser
« Reply #2 on: December 16, 2007, 10:34:26 pm »
So i took mar77a's code and continued the OpenGL implementation. It renders quiete well the maps, but still have some details to fix. It makes use of FreeImage library to load the image files (textures and sceneries).

So here this is what's done so far:
mapc.h - I think i modified a couple of things there.
test.cpp - Here all the OpenGL implementation.

Screeshots:

This is one thing that I don't know how to fix yet (the scenery border)


To show off the good looking :p



If anyone knows about OpenGL and knows how to get rid of those borders, any help would be appreciated.
« Last Edit: May 10, 2016, 04:53:12 am by jrgp »
urraka

Offline chrisgbk

  • Inactive Staff
  • Veteran
  • *****
  • Posts: 1739
Re: c++ PMS parser
« Reply #3 on: December 17, 2007, 12:45:00 am »
Well, I'm glad to see the psuedo-C structures I wrote for Hex Workshop are being found useful finally, which is the whole reason I put them on the wiki in the first place.

Wish I could help with the OpenGL stuff a bit, but it's particularily frustrating that you can't get the official up to date OpenGL Reference Manual or Porgramming Guide(Blue book and Red book respectively) without paying for it. Sure, you can find tutorials all over, and they do have old versions online, but you can't find an up to date definitive source for everything. One of a few things I like about Microsoft and DirectX, all the information is freely available and searchable, complete with many tutorials.

I had attempted to try making a Kylix version of a map editor at one point in time, and the biggest issue I had was finding information on how to actually do something (since under Kylix, you don't have all the nice wrappers people have written around OpenGL). That, and the poor support for OpenGL under Kylix in the first place.

That Calypso map looks just beautiful.

Offline rfreak

  • Soldier
  • **
  • Posts: 152
Re: c++ PMS parser
« Reply #4 on: January 09, 2008, 10:00:50 pm »
someone as information on freeimage.h? because I don't have it.
R the coolest game ever

Offline chrisgbk

  • Inactive Staff
  • Veteran
  • *****
  • Posts: 1739
Re: c++ PMS parser
« Reply #5 on: January 10, 2008, 01:39:22 am »
someone as information on freeimage.h? because I don't have it.

http://freeimage.sourceforge.net/

Offline MR X

  • Soldier
  • **
  • Posts: 148
  • Soldat Rulezz and must be played forever
Re: c++ PMS parser
« Reply #6 on: February 17, 2008, 05:01:52 pm »
Oh man thats nice. tough i cant work with c++. it would be nice if you could create the same for LUA. then i would create more software like crazy.
Soldat Rulezz and must be played forever

Offline ElephantHunter

  • Retired Administrator
  • Camper
  • *****
  • Posts: 431
  • Third President
    • - home of the admins -
Re: c++ PMS parser
« Reply #7 on: February 25, 2008, 02:06:03 pm »
With a few tweaks I was able to compile/run PerroAZUL's code on my Eee under xUbuntu. Apparently g++ didn't recognize most of the numeric typedefs, so I changed those (_int16 -> short, _int32 -> long, _int64 -> long long.) Also the slashes were all backward (including the #includes.) Tell me if there's a better way of fixing this. I just did what I needed to for everything to work.

This is what I used to compile
g++ main.cpp -lglut -lGLU -lGL -lfreeimage

PerroAZUL, I compared the same maps on XP and Ubuntu. Under Ubuntu they don't appear. Maybe this is a bug in the FreeImage library?
Everything you have done in life is measured by the DASH on your gravestone.
Stop wasting time.
Make your dash count.

Offline urraka

  • Soldat Developer
  • Flagrunner
  • ******
  • Posts: 703
Re: c++ PMS parser
« Reply #8 on: February 25, 2008, 03:08:00 pm »
I don't think it's a bug in FreeImage because I found this problem in many forums discussing about OpenGL. Maybe it has something to do with the OpenGL version. Did you use the same in both systems?
urraka

Offline FliesLikeABrick

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 6144
    • Ultimate 13 Soldat
Re: c++ PMS parser
« Reply #9 on: February 25, 2008, 03:41:12 pm »
Slightly off-toopic... don't forward-slashes work in MS IDEs for include paths?  This way you're writing more portable code right off the bat...

Offline mar77a

  • Global Moderator
  • Veteran
  • *****
  • Posts: 1295
  • mad
    • random stuffs
Re: c++ PMS parser
« Reply #10 on: February 25, 2008, 04:26:35 pm »

Offline chrisgbk

  • Inactive Staff
  • Veteran
  • *****
  • Posts: 1739
Re: c++ PMS parser
« Reply #11 on: February 25, 2008, 09:11:33 pm »
Things not appearing/rendering properly is usually a result of making assumptions of what the hardware is capable of. ie: older hardware can't handle non-square non-power-of-2 textures (anything that's not ... 32x32, 64x64, 128x128 ...) and attempting to use it will at best cause a well written driver to fallback to software workaround, a somewhat OK driver to render incorrectly (see: SIS chipset rendering soldat's graphics partially; the driver finds the smallest power of 2 of the width or height, whichever is SMALLEST, causing the allocated texture to be smaller and cut off partially), or just not work altogether, probably returning on error on some of the rendering calls. Worst case is it crashes.
« Last Edit: February 27, 2008, 04:16:06 am by chrisgbk »

Offline ElephantHunter

  • Retired Administrator
  • Camper
  • *****
  • Posts: 431
  • Third President
    • - home of the admins -
Re: c++ PMS parser
« Reply #12 on: February 27, 2008, 02:02:23 am »
OK. I made a few more changes. Namely switching from glut to SDL and adding cross-platform compatibility. Glut just doesn't have the functionality we'd need to do anything useful with this app. Using SDL I was able to add mouse dragging and scrolling.

mapc.cpp - Main file
mapc.h - Header

Here's the list of parameters I used to compile it using dev-cpp under Windows (Project -> Project Options -> Parameters)
-lmingw32
-lSDLmain
-mwindows
-lSDL
-lglu32
-lopengl32
-lwinmm
-lgdi32
-lfreeimage

And using g++ under linux:
g++ main.cpp -lSDLmain -lSDL -lGLU -lGL -lfreeimage

Under Ubuntu you need all the development files for SDL and OpenGL.

Edit: I discovered the lines were caused by the textures bleeding onto the other side, like they are wrapping despite GL_CLAMP being set. Scenery that is transparent along the opposite border doesn't have this issue.
« Last Edit: February 27, 2008, 02:11:36 am by ElephantHunter »
Everything you have done in life is measured by the DASH on your gravestone.
Stop wasting time.
Make your dash count.

Offline chrisgbk

  • Inactive Staff
  • Veteran
  • *****
  • Posts: 1739
Re: c++ PMS parser
« Reply #13 on: February 27, 2008, 04:56:39 am »
Edit: I discovered the lines were caused by the textures bleeding onto the other side, like they are wrapping despite GL_CLAMP being set. Scenery that is transparent along the opposite border doesn't have this issue.

That's somewhat strange; GL_CLAMP is supposed to have this behaviour:

Source Texture:


GL_CLAMP; rendered on a large surface(larger than the texture in question):



Note the smearing of the upper row of pixels and the right row of pixels.

Maybe it's an unintended side-effect of using 3D texture coordinates (glTexCoord3f) instead of 2D texture coordinates(glTexCoord2f) while in 2D texturing mode?¬  I'm a bit rusty with how this is handled in OpenGL.

Why not do all drawing in strictly 2D? I can't see a use for using 3D coordinates for a 2D application, esp. as Soldat itself doesn't use the values. (Coordinates in OpenGL are always 4D, with X, Y, Z and W components, using the 2D functions simply supplies default values of 0.0 and 1.0 for Z and W respectively, and makes for neater code)

Any reason not to do the drawing as follows?

Code: [Select]
glBegin(GL_QUADS);
   glColor4fb(pmap->prop[i].color.red,
¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†   ¬†¬†pmap->prop[i].color.green,
  ¬† pmap->prop[i].color.blue
¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†   pmap->prop[i].alpha);
   glTexCoord2f(0.0, 0.0); glVertex2f(0.0, 0.0);
   glTexCoord2f(0.0, 1.0); glVertex2f(0.0, pmap->prop[i].height);
   glTexCoord2f(1.0, 1.0); glVertex2f(pmap->prop[i].width, pmap->prop[i].height);
   glTexCoord2f(1.0, 0.0); glVertex2f(pmap->prop[i].width, 0.0);
glEnd();


I'm going to have to get a working install of Ubuntu up and running and get the compiler all setup one of these days.
« Last Edit: February 27, 2008, 05:10:02 am by chrisgbk »

Offline ramirez

  • Retired Soldat Developer
  • Camper
  • ******
  • Posts: 394
    • Soldat Central
Re: c++ PMS parser
« Reply #14 on: March 06, 2008, 07:28:19 pm »
The "line problem" is probably due to interpolation not being handled correctly by the driver. I've seen this problem before, even with GL_CLAMP set, when interpolating texture coordinates (i.e. using GL_LINEAR instead of GL_NEAREST) it'll wrap the coordinates around. Do you have up-to-date drivers?

Offline Frenchie

  • Camper
  • ***
  • Posts: 358
  • SoldatHQ
Re: c++ PMS parser
« Reply #15 on: March 22, 2008, 03:32:22 am »
hey fellas, I've been away for quite a while but I'm back for now.
I've been reading these forums and this topic seems real interesting.

Soo I tried compiling Mar77a code edits by Elephant Hunter under Ubuntu and got it working somewhat. (I think it's a worse or same result as Elephant Hunter)
Cause Im not up with C++, I'm stumped

Added screenshot of test, 1 with no sceneries or texture (it renders well) the other with both enabled (and the level is messed up..)

Perro could you tell me what version OpenGL and Freeimage you running?

And  could someone tell me how I could edit the map renderer so the image size is not static and is about 20 pixels out from the furthest polygon on each side?

Thanks alot :)
Soldat Lobby Avec Players -New Release! - Updated AGAIN!