[Solved] Compiler bug was in fact optimizier bug.
[Solved] Compiler bug was in fact optimizier bug.
I'm writing a 3d engine(Open source) but I've run into a problem.
Whenever I use glMultMatrixf to multiply the entities position/rotation matrix ti doesn't work. The camera sits at 0,0,0, and so does the entity.
I confirmed it was this by adding a glTranslate3f(0,0,-40) into my rendering code, which resulted in the entity being drawn 40 units into the distance as it should have been with glMultMatrixf
So just wondering, has anyone else run into problems with glMultMatrixf? or should I be looking elsewhere?
Whenever I use glMultMatrixf to multiply the entities position/rotation matrix ti doesn't work. The camera sits at 0,0,0, and so does the entity.
I confirmed it was this by adding a glTranslate3f(0,0,-40) into my rendering code, which resulted in the entity being drawn 40 units into the distance as it should have been with glMultMatrixf
So just wondering, has anyone else run into problems with glMultMatrixf? or should I be looking elsewhere?
Last edited by Kojima on Mon Jul 10, 2006 3:14 am, edited 2 times in total.
I tracked the problem down, there seems to be a serious bug with virtual methods in the C++ compiler.
My code presently now works. If I had one more virtual method/deconstructor though, it no longer works. The 3d mesh is visible for half a second and then is gone. I remove the virtual keyword and like magic it works.
And this is on a function that is *not* called, so it's not because it's changing which function is being called due to the virtual method (There are no overloads, they're inherited from the base class)
I can provide code to demonstrate the bug if the writers of the compiler back end wish to take a look.
My code presently now works. If I had one more virtual method/deconstructor though, it no longer works. The 3d mesh is visible for half a second and then is gone. I remove the virtual keyword and like magic it works.
And this is on a function that is *not* called, so it's not because it's changing which function is being called due to the virtual method (There are no overloads, they're inherited from the base class)
I can provide code to demonstrate the bug if the writers of the compiler back end wish to take a look.
Wouldn't alignment only be an issue when sending data to psp system calls and render calls?
If so, the only candidate is my matrix class, I don't align the data.
The rest is only accessed by my own code in C++, not asm. Or does the mips have further restrictions not typically found on pc concerning alignment?
If so, the only candidate is my matrix class, I don't align the data.
The rest is only accessed by my own code in C++, not asm. Or does the mips have further restrictions not typically found on pc concerning alignment?
Most likely it's a bug in your code. I have dozens of classes with 0-6 virtual methods in each class, and I've _never_ had any problem with g++. And this is not some toy engine - it does substantial 3D code with blended skeleton 3d character animation, bezier curves, hardware lighting, transparent 2D animated gui and networking. Anyways, I should be releasing a alpha sometime in the next two weeks.
I agree that is something in my code, but it's not a simple coding bug.
My code is more likely ehibiting a bug that has not be found in the psp sdk yet.
I mean, how else could an *empty* function being called make the graphics disappear after one frame?
the function does nothing. not a single line of code is touched, it returns immediately, with a hard 'return'
I've aligned all my structures to 16/32/64 bit, no difference.
I even used a new replacement,
to align my classes, but again it makes no difference.
If I remove the call to the function, it works. I don't have to remove the function it's self, so it's not likely to be it's inclusion causing something else to go out of alignment.
Tbh I have no idea what could be causing it.
Here's the source, I've only been working on it for a day or two so it's not some uber advanced engine yet, but it has meshes/surfaces/camers etc.
I'd appreciate it if you take a look and see if you get the same problems. it requires no external media.
If you scroll down to main, you'll see a function called Move being called. Remove this line and it works perfectly. If you check the camera class for move, you'll see it has but one line. "return" and nothing else.
Here's the makefile
My code is more likely ehibiting a bug that has not be found in the psp sdk yet.
I mean, how else could an *empty* function being called make the graphics disappear after one frame?
the function does nothing. not a single line of code is touched, it returns immediately, with a hard 'return'
I've aligned all my structures to 16/32/64 bit, no difference.
I even used a new replacement,
Code: Select all
#define new(x) memalign(64, sizeof(x) );
If I remove the call to the function, it works. I don't have to remove the function it's self, so it's not likely to be it's inclusion causing something else to go out of alignment.
Tbh I have no idea what could be causing it.
Here's the source, I've only been working on it for a day or two so it's not some uber advanced engine yet, but it has meshes/surfaces/camers etc.
I'd appreciate it if you take a look and see if you get the same problems. it requires no external media.
If you scroll down to main, you'll see a function called Move being called. Remove this line and it works perfectly. If you check the camera class for move, you'll see it has but one line. "return" and nothing else.
Code: Select all
#include <stdlib.h> // needed in order to have "exit" function @@@
#include <stdio.h>
#include <GL/glut.h> // Header File For The GLUT Library
#include <GL/gl.h> // Header File For The OpenGL32 Library
#include <GL/glu.h> // Header File For The GLu32 Library
//#include <unistd.h> // Header File for sleeping. @@@
#include <pspctrl.h>
#include <pspdebug.h>
#include <math.h>
int window;
const float RAD_TO_DEG = 57.2957795130823208767981548141052;
template <class T>
class ListNode
{
public:
T &get()
{
return object;
};
void set(T &object)
{
this->object = object;
};
ListNode<T> *getNext()
{
return nextNode;
};
void setNext(ListNode<T> *nextNode)
{
this->nextNode = nextNode;
};
private:
T object;
ListNode<T> *nextNode;
};
template <class T>
class List
{
public:
// Constructor
List()
{
headNode = new ListNode<T>;
headNode->setNext(NULL);
currentNode = NULL;
size = 0;
};
// Destructor
~List()
{
ListNode<T> *pointerToDelete, *pointer = headNode;
while (pointer != NULL)
{
pointerToDelete = pointer;
pointer = pointer->getNext();
delete pointerToDelete;
}
};
T &get()
{
if (currentNode == NULL)
start();
return currentNode->get()
;
};
void add(T addObject)
{
ListNode<T> *newNode = new ListNode<T>;
newNode->set(addObject)
;
newNode->setNext(headNode->getNext());
headNode->setNext(newNode);
size++;
};
void remove()
{
lastCurrentNode->setNext(currentNode->getNext());
delete currentNode;
currentNode = lastCurrentNode;
size--;
};
void start()
{
lastCurrentNode = headNode;
currentNode = headNode;
};
bool next()
{
// If the currentNode now points at nothing, we've reached the end
if (currentNode == NULL)
return false;
// Update the last node and current node
lastCurrentNode = currentNode;
currentNode = currentNode->getNext();
// If currentNode points at nothing or there is nothing added, we can immediately return false
if (currentNode == NULL || size == 0)
return false;
else
return true;
};
int getSize()
{
return size;
};
private:
int size;
ListNode<T> *headNode;
ListNode<T> *currentNode, *lastCurrentNode;
};
/* Image type - contains height, width, and data */
struct Image {
unsigned long sizeX;
unsigned long sizeY;
char *data;
};
typedef struct Image Image;
// quick and dirty bitmap loader...for 24 bit bitmaps with 1 plane only.
// See http://www.dcs.ed.ac.uk/~mxr/gfx/2d/BMP.txt for more info.
int ImageLoad(char *filename, Image *image) {
FILE *file;
unsigned long size; // size of the image in bytes.
unsigned long i; // standard counter.
unsigned short int planes; // number of planes in image (must be 1)
unsigned short int bpp; // number of bits per pixel (must be 24)
char temp; // temporary color storage for bgr-rgb conversion.
// make sure the file is there.
if ((file = fopen(filename, "rb"))==NULL)
{
printf("File Not Found : %s\n",filename);
return 0;
}
// seek through the bmp header, up to the width/height:
fseek(file, 18, SEEK_CUR);
// read the width
if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
printf("Error reading width from %s.\n", filename);
return 0;
}
printf("Width of %s: %lu\n", filename, image->sizeX);
// read the height
if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
printf("Error reading height from %s.\n", filename);
return 0;
}
printf("Height of %s: %lu\n", filename, image->sizeY);
// calculate the size (assuming 24 bits or 3 bytes per pixel).
size = image->sizeX * image->sizeY * 3;
// read the planes
if ((fread(&planes, 2, 1, file)) != 1) {
printf("Error reading planes from %s.\n", filename);
return 0;
}
if (planes != 1) {
printf("Planes from %s is not 1: %u\n", filename, planes);
return 0;
}
// read the bpp
if ((i = fread(&bpp, 2, 1, file)) != 1) {
printf("Error reading bpp from %s.\n", filename);
return 0;
}
if (bpp != 24) {
printf("Bpp from %s is not 24: %u\n", filename, bpp);
return 0;
}
// seek past the rest of the bitmap header.
fseek(file, 24, SEEK_CUR);
// read the data.
image->data = (char *) malloc(size);
if (image->data == NULL) {
printf("Error allocating memory for color-corrected image data");
return 0;
}
if ((i = fread(image->data, size, 1, file)) != 1) {
printf("Error reading image data from %s.\n", filename);
return 0;
}
for (i=0;i<size;i+=3) { // reverse all of the colors. (bgr -> rgb)
temp = image->data[i];
image->data[i] = image->data[i+2];
image->data[i+2] = temp;
}
// we're done.
return 1;
}
class Display
{
public:
Display(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowSize(480, 272); // @@@
glutInitWindowPosition(0, 0);
_win = glutCreateWindow("Raptor Engine - Main Window");
_w = 480;
_h = 272;
InitGl();
Draw2D();
}
void InitGl()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // Reset The Projection Matrix
gluPerspective(45.0f,(float)_w/(float)_h,0.1f,100.0f); // Calculate The Aspect Ratio Of The Window
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
}
void Draw2D()
{
glViewport( 0,0,480,272 );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 480.0, 0.0, 272.0, -2.0, 2.0 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
}
int _w,_h;
int _win;
};
class Texture
{
public:
Texture(char *file)
{
Image *image1;
image1 = (Image *) malloc(sizeof(Image));
if (image1 == NULL) {
printf("Error:Unable to allocate memory for texture.\n");
exit(0);
}
if (!ImageLoad(file, image1)) {
printf("Error:Unable to load image.\n");
exit(0);
}
glGenTextures(1, &_gltex);
glBindTexture(GL_TEXTURE_2D, _gltex); // 2d texture (x and y size)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image1->data);
glBindTexture(GL_TEXTURE_2D,0);
}
void Bind()
{
glBindTexture(GL_TEXTURE_2D,_gltex);
}
void Unbind()
{
glBindTexture(GL_TEXTURE_2D,0);
}
GLuint _gltex;
};
class Material
{
public:
Material()
{
_r=_g=_b=_a=1;
}
void AddTexture(Texture *tex)
{
_texs.add( tex );
}
void Bind( int stage = 0 )
{
glColor4f( _r,_g,_b,_a );
_texs.start();
while( _texs.next()==true )
{
if(stage == 0)
{
Texture *tex = _texs.get();
tex->Bind();
}
stage--;
}
}
void Unbind( int stage )
{
_texs.start();
while( _texs.next()==true )
{
if(stage == 0)
{
Texture *tex = _texs.get();
tex->Unbind();
}
stage--;
}
}
float _r,_g,_b,_a;
List<Texture *>_texs;
};
const float PI = 3.14159265;
inline float DegToRad(float ang)
{
return ang*180.0f/PI;
}
inline float RadToDeg(float rad)
{
return rad * 180.0f / PI;
}
class Matrix
{
public:
void LoadIdentity()
{
grid[0][0]=1.0;
grid[1][0]=0.0;
grid[2][0]=0.0;
grid[3][0]=0.0;
grid[0][1]=0.0;
grid[1][1]=1.0;
grid[2][1]=0.0;
grid[3][1]=0.0;
grid[0][2]=0.0;
grid[1][2]=0.0;
grid[2][2]=1.0;
grid[3][2]=0.0;
grid[0][3]=0.0;
grid[1][3]=0.0;
grid[2][3]=0.0;
grid[3][3]=1.0;
}
/*
*/
void Multiply(Matrix *mat)
{
Matrix *new_mat=new Matrix;
float sum=0;
int row=0;
int col=0;
for(row=0;row<4;row++)
{
for(col=0;col<4;col++)
{
for(int r=0;r<4;r++)
{
float a=grid[r][col];
float b=mat->grid[row][r];
float c=a*b;
sum=sum+c;
}
new_mat->grid[row][col]=sum;
sum=0;
}
}
for(row=0;row<4;row++)
{
for(col=0;col<4;col++)
{
grid[row][col]=new_mat->grid[row][col];
}
}
delete new_mat;
}
Matrix * Copy()
{
Matrix *mat = new Matrix;
mat->grid[0][0]=grid[0][0];
mat->grid[1][0]=grid[1][0];
mat->grid[2][0]=grid[2][0];
mat->grid[3][0]=grid[3][0];
mat->grid[0][1]=grid[0][1];
mat->grid[1][1]=grid[1][1];
mat->grid[2][1]=grid[2][1];
mat->grid[3][1]=grid[3][1];
mat->grid[0][2]=grid[0][2];
mat->grid[1][2]=grid[1][2];
mat->grid[2][2]=grid[2][2];
mat->grid[3][2]=grid[3][2];
mat->grid[0][3]=grid[0][3];
mat->grid[1][3]=grid[1][3];
mat->grid[2][3]=grid[2][3];
mat->grid[3][3]=grid[3][3];
return mat;
}
void Overwrite(Matrix *mat)
{
grid[0][0]=mat->grid[0][0];
grid[1][0]=mat->grid[1][0];
grid[2][0]=mat->grid[2][0];
grid[3][0]=mat->grid[3][0];
grid[0][1]=mat->grid[0][1];
grid[1][1]=mat->grid[1][1];
grid[2][1]=mat->grid[2][1];
grid[3][1]=mat->grid[3][1];
grid[0][2]=mat->grid[0][2];
grid[1][2]=mat->grid[1][2];
grid[2][2]=mat->grid[2][2];
grid[3][2]=mat->grid[3][2];
grid[0][3]=mat->grid[0][3];
grid[1][3]=mat->grid[1][3];
grid[2][3]=mat->grid[2][3];
grid[3][3]=mat->grid[3][3];
}
void Translate(float x,float y,float z)
{
Matrix *mat=new Matrix;
mat->grid[0][0]=1;
mat->grid[1][0]=0;
mat->grid[2][0]=0;
mat->grid[3][0]=x;
mat->grid[0][1]=0;
mat->grid[1][1]=1;
mat->grid[2][1]=0;
mat->grid[3][1]=y;
mat->grid[0][2]=0;
mat->grid[1][2]=0;
mat->grid[2][2]=1;
mat->grid[3][2]=z;
mat->grid[0][3]=0;
mat->grid[1][3]=0;
mat->grid[2][3]=0;
mat->grid[3][3]=1;
Multiply(mat);
}
void Rotate( float ax,float ay,float az )
{
RotateYaw( ay );
RotatePitch( ax );
RotateRoll( az );
}
void RotatePYR( float ax,float ay,float az)
{
RotatePitch( ax );
RotateYaw( ay );
RotateRoll( az );
}
void RotateI( float ax,float ay,float az )
{
RotatePitch( az );
RotateRoll( az );
RotateYaw( ay );
}
void RotateRPY( float ax,float ay,float az )
{
RotateRoll( az );
RotatePitch( ax );
RotateYaw( ay );
}
void RotateYaw( float ang )
{
Matrix *mat=new Matrix;
//ang = DegToRad( ang );
mat->grid[0][0]=cos(ang);
mat->grid[1][0]=0;
mat->grid[2][0]=sin(ang);
mat->grid[3][0]=0;
mat->grid[0][1]=0;
mat->grid[1][1]=1;
mat->grid[2][1]=0;
mat->grid[3][1]=0;
mat->grid[0][2]=-sin(ang);
mat->grid[1][2]=0;
mat->grid[2][2]=cos(ang);
mat->grid[3][2]=0;
mat->grid[0][3]=0;
mat->grid[1][3]=0;
mat->grid[2][3]=0;
mat->grid[3][3]=1;
Multiply(mat);
delete mat;
}
void RotateRoll( float ang )
{
Matrix *mat=new Matrix;
//ang = DegToRad( ang );
mat->grid[0][0]=cos(ang);
mat->grid[1][0]=-sin(ang);
mat->grid[2][0]=0;
mat->grid[3][0]=0;
mat->grid[0][1]=sin(ang);
mat->grid[1][1]=cos(ang);
mat->grid[2][1]=0;
mat->grid[3][1]=0;
mat->grid[0][2]=0;
mat->grid[1][2]=0;
mat->grid[2][2]=1;
mat->grid[3][2]=0;
mat->grid[0][3]=0;
mat->grid[1][3]=0;
mat->grid[2][3]=0;
mat->grid[3][3]=1;
Multiply(mat);
delete mat;
}
void RotatePitch( float ang )
{
Matrix *mat=new Matrix;
//ang = DegToRad( ang );
mat->grid[0][0]=1;
mat->grid[1][0]=0;
mat->grid[2][0]=0;
mat->grid[3][0]=0;
mat->grid[0][1]=0;
mat->grid[1][1]=cos(ang);
mat->grid[2][1]=-sin(ang);
mat->grid[3][1]=0;
mat->grid[0][2]=0;
mat->grid[1][2]=sin(ang);
mat->grid[2][2]=cos(ang);
mat->grid[3][2]=0;
mat->grid[0][3]=0;
mat->grid[1][3]=0;
mat->grid[2][3]=0;
mat->grid[3][3]=1;
Multiply(mat);
delete mat;
}
float grid[4][4] __attribute__((aligned(16)));
};
#define true 1
#define false 0
const int Typ_Ent = 1;
const int Typ_Piv = 2;
const int Typ_Bas = 3;
const int Typ_Lgt = 4;
class Base
{
public:
Base()
{
_sx=1;
_sy=1;
_sz=1;
_parent = NULL;
_px=0;
_py=0;
_pz=0;
_qw=0;
_qx=0;
_qy=0;
_qz=0;
_hidden = false;
_order = 0;
_mat = new Matrix;
}
Base( Base *parent )
{
_sx=1;
_sy=1;
_sz=1;
_parent = NULL;
_px=0;
_py=0;
_pz=0;
_qw=0;
_qx=0;
_qy=0;
_qz=0;
_hidden = false;
_order = 0;
_mat = new Matrix;
}
List<Base *>_childs;
Base *_parent;
Matrix *_mat;
float _px,_py,_pz;
float _sx,_sy,_sz;
float _rx,_ry,_rz;
float _qw,_qx,_qy,_qz;
int _order;
int _hidden;
const char *_name;
const char *_type;
float _ed;
float _pit,_yaw;
void PointAt( float tx,float ty,float tz,float roll=0 )
{
// printf("Reached Function\n");
float x=tx;
float y=ty;
float z=tz;
float xdiff=XPos(true)-x;
float ydiff=YPos(true)-y;
float zdiff=ZPos(true)-z;
float dist22=sqrt((xdiff*xdiff)+(zdiff*zdiff));
float pitch= atan2(ydiff,dist22);// *RAD_TO_DEG;
float yaw= atan2(xdiff,-zdiff);// *RAD_TO_DEG;
//printf("Reached Print\n");
//printf(" Pit:%d Yaw:%d \n",(int)pitch,(int)yaw);
_pit = pitch;
_yaw = yaw;
Rotate( pitch,yaw,roll,true );
}
void Position( float x,float y,float z,int global = false )
{
_px=x;
_py=y;
_pz=-z;
if( (global==1) && (!(_parent==NULL)) )
{
_px=_px-_parent->XPos(true);
_py=_py-_parent->YPos(true);
_pz=_pz+_parent->ZPos(true);
float ax=Pitch(true);
float ay=Yaw(true);
float az=Roll(true);
Matrix *new_mat=new Matrix;
new_mat->LoadIdentity();
new_mat->Rotate(-ax,-ay,-az);
new_mat->Translate(_px,_py,_pz);
_px=new_mat->grid[3][0];
_py=new_mat->grid[3][1];
_pz=new_mat->grid[3][2];
delete new_mat;
}
if( !(_parent==NULL) )
{
_mat->Overwrite(_parent->_mat);
UpdateMat();
}
if( _parent==NULL )
{
UpdateMat(true);
}
UpdateChildren(this);
}
void Rotate( float pitch,float yaw,float roll,int global = false)
{
_rx=-pitch;
_ry=yaw;
_rz=roll;
if( (global==true) && (!(_parent==NULL )) )
{
_rx=_rx-_parent->Pitch(true);
_ry=_ry-_parent->Yaw(true);
_rz=_rz-_parent->Roll(true);
}
if( !(_parent==NULL) )
{
_mat->Overwrite(_parent->_mat);
UpdateMat();
}
if( _parent==NULL )
{
UpdateMat(true);
}
UpdateChildren(this);
}
float XPos(int global)
{
if( global == false )
return _px;
return _mat->grid[3][0];
}
float YPos(int global)
{
if( global == false )
return _py;
return _mat->grid[3][1];
}
float ZPos(int global)
{
if(global == false)
return -_pz;
return -_mat->grid[3][2];
}
float Roll(int global=false)
{
if(global == false)
{
return _rz;
}
float a=_mat->grid[0][1];
float b=_mat->grid[1][1];
if( fabs(a)<0.01 ) a=0;
if( fabs(b)<0.01 ) b=0;
return RadToDeg( atan2(a,b) );
}
float Yaw(int global=false)
{
if(global == false)
{
return _ry;
}
float a=_mat->grid[2][0];
float b=_mat->grid[2][2];
if( fabs(a)<0.01 ) a=0;
if( fabs(b)<0.01 ) b=0;
return RadToDeg( atan2(a,b) );
}
float Pitch(int global=false)
{
if(global == false)
{
return -_rx;
}
float ang = atan2( _mat->grid[2][1],sqrt( _mat->grid[2][0]*_mat->grid[2][0]+_mat->grid[2][2]*_mat->grid[2][2] ) );
ang = RadToDeg( ang );
if(fabs(ang)<0.01) ang=0;
return ang;
}
void UpdateChildren(Base *from)
{
_childs.start();
while( _childs.next()==true )
{
Base *ent = _childs.get();
ent->_mat->Overwrite( from->_mat );
ent->UpdateMat();
UpdateChildren( ent );
}
}
void UpdateMat(int loadid = false)
{
if(loadid==true) _mat->LoadIdentity();
_mat->Translate(_px,_py,_pz);
_mat->RotateYaw(_ry);
_mat->RotatePitch(_rx);
_mat->RotateRoll(_rz);
//_mat.Scale(sx,sy,sz)
}
};
List<Base *>entlist;
// Todo:Add some dynamic sizing so you can safelty build undefined meshes.
class Surface
{
public:
Surface(int verts,int tris)
{
_verts = (float *)malloc( verts*3*4 );
_tris = (int *)malloc( tris*3*4 );
_vertm = verts;
_trim = tris;
_vertc=_tric=0;
}
int AddVertex( float x,float y,float z )
{
_verts[ _vertc*3 ] = x;
_verts[ _vertc*3+1 ] = y;
_verts[ _vertc*3+2 ] = z;
_vertc++;
return _vertc-1;
}
int AddTriangle( int v0,int v1,int v2 )
{
_tris[ _tric*3 ] = v0;
_tris[ _tric*3+1 ] = v1;
_tris[ _tric*3+2 ] = v2;
_tric++;
return _tric-1;
}
float VertexX( int index )
{
return _verts[ index * 3 ];
}
float VertexY( int index )
{
return _verts[ index * 3 + 1 ] ;
}
float VertexZ( int index )
{
return _verts[ index * 3 + 2 ] ;
}
int TriVertex( int tri,int vertex )
{
return _tris[ tri*3+vertex ];
}
void Render()
{
glColor3f(1,1,1);
glBegin(GL_TRIANGLES);
for(int j=0;j<_tric;j++)
{
for(int k=0;k<3;k++)
{
glVertex3f( VertexX( TriVertex( j,k ) ),VertexY( TriVertex( j,k ) ),VertexZ( TriVertex(j,k) ) );
}
}
glEnd();
}
int _vertc,_tric;
int _vertm,_trim;
float *_verts;
int *_tris;
};
class Entity : public Base
{
public:
Entity(Base * parent)
{
_parent = parent;
}
void AddSurface( Surface *in)
{
_surf.add( in );
}
void ClearSurfaces()
{
_surf.start();
while( _surf.next()==true );
{
_surf.remove();
}
_surf.start();
}
void Render()
{
_surf.start();
while( _surf.next()==true )
{
Surface *surf = _surf.get();
surf->Render();
}
}
void Cycle()
{
if( _hidden == true )
return ;
glDisable(GL_TEXTURE_2D);
_surf.start();
while( _surf.next()==true )
{
Surface *surf = _surf.get();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
surf->Render();
glPopMatrix();
}
}
List<Surface *>_surf;
int _surfc;
int _pickable;
};
Matrix * MatInverse( Matrix *mat )
{
Matrix * new_mat=new Matrix;
float tx=0;
float ty=0;
float tz=0;
new_mat->grid[0][0] = mat->grid[0][0];
new_mat->grid[1][0] = mat->grid[0][1];
new_mat->grid[2][0] = mat->grid[0][2];
new_mat->grid[0][1] = mat->grid[1][0];
new_mat->grid[1][1] = mat->grid[1][1];
new_mat->grid[2][1] = mat->grid[1][2];
new_mat->grid[0][2] = mat->grid[2][0];
new_mat->grid[1][2] = mat->grid[2][1];
new_mat->grid[2][2] = mat->grid[2][2];
new_mat->grid[0][3] = 0;
new_mat->grid[1][3] = 0;
new_mat->grid[2][3] = 0;
new_mat->grid[3][3] = 1;
tx = mat->grid[3][0];
ty = mat->grid[3][1];
tz = mat->grid[3][2];
new_mat->grid[3][0] = -( (mat->grid[0][0] * tx) + (mat->grid[0][1] * ty) + (mat->grid[0][2] * tz) );
new_mat->grid[3][1 3; = -( (mat->grid[1][0] * tx) + (mat->grid[1][1] * ty) + (mat->grid[1][2] * tz) );
new_mat->grid[3][2] = -( (mat->grid[2][0] * tx) + (mat->grid[2][1] * ty) + (mat->grid[2][2] * tz) );
return new_mat;
}
class Camera : public Base
{
public:
float _viewx,_viewy,_vwidth,_vheight;
float _clsr,_clsg,_clsb;
float _zDepth,_z2Depth;
float _zoom;
Camera()
{
_viewx=0;
_viewy=0;
_vwidth=480;
_vheight=272;
_clsr=0;
_clsg=0;
_clsb=0;
_zDepth=0.1;
_z2Depth = 1000;
_zoom = 1;
}
Camera(Base *parent)
{
_viewx=0;
_viewy=0;
_vwidth=480;
_vheight=272;
_clsr=0;
_clsg=0;
_clsb=0;
_zDepth=0.1;
_z2Depth = 1000;
_zoom = 1;
_parent = parent;
}
void Move(float x,float y,float z)
{
return;
float mx=x;
float my=y;
float mz=-z;
Matrix *new_mat=new Matrix;
new_mat->LoadIdentity();
new_mat->Rotate(_rx,_ry,_rz);
new_mat->Translate(mx,my,mz);
mx=new_mat->grid[3][0];
my=new_mat->grid[3][1];
mz=new_mat->grid[3][2];
_px=_px+mx;
_py=_py+my;
_pz=_pz+mz;
if( !(_parent==NULL) )
{
_mat->Overwrite(_parent->_mat);
UpdateMat();
}
if( _parent==NULL )
{
UpdateMat(true);
}
UpdateChildren(this);
delete new_mat;
}
void Draw3D()
{
SetViewPort3D();
glShadeModel(GL_SMOOTH);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
}
void SetViewPort3D()
{
glViewport(_viewx,_viewy, _vwidth, _vheight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float aspect = ((float)_vwidth /(float)_vheight);
gluPerspective( RadToDeg( atan( (1.0/(_zoom*aspect))))*2.0,aspect,_zDepth,_z2Depth);
glMatrixMode(GL_MODELVIEW);
}
void Viewport( int x,int y,int w,int h)
{
_viewx = x;
_viewy = 272 - h-y;
_vwidth = w;
_vheight = h;
}
void Zoom(float zoom)
{
_zoom = zoom;
}
void ClsColor(float r,float g,float b)
{
_clsr = r;
_clsg = g;
_clsb = b;
}
void Range(float z1,float z2)
{
_zDepth = z1;
_z2Depth = z2;
}
void Cycle()
{
glDepthMask( GL_TRUE );
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
Draw3D();
Matrix *new_mat = MatInverse( _mat );
glLoadMatrixf( (GLfloat *)new_mat->grid );
delete new_mat;
}
};
class EngineFactory
{
public:
Entity * ProduceEntity(Base *parent=NULL)
{
Entity *out = new Entity(parent);
if( !(out->_parent==NULL))
{
out->_mat->Overwrite( out->_parent->_mat );
out->UpdateMat();
}
else
{
out->UpdateMat(true);
}
return out;
}
Camera * ProduceCamera(Base *parent=NULL)
{
Camera *out = new Camera(parent);
if( !(out->_parent==NULL))
{
out->_mat->Overwrite(out->_parent->_mat);
out->UpdateMat();
}else
{
out->UpdateMat(true);
}
return out;
}
};
class RenderEngine
{
public:
void RenderScene()
{
if(_ActiveCam==NULL) return;
_ActiveCam->Cycle();
entlist.start();
while( entlist.next()==true )
{
//glTranslatef(0,0,-40);
Entity *ent =(Entity *)entlist.get();
ent->Cycle();
}
}
Camera *_ActiveCam;
};
RenderEngine *Renderer;
EngineFactory *Factory;
void InitRaptor()
{
Factory = new EngineFactory;
Renderer = new RenderEngine;
}
class Prefab
{
public:
Entity * CreateCube(float size,Base *parent = NULL)
{
Entity *out = Factory->ProduceEntity(parent);
Surface *surf = new Surface(8,12);
size = size / 2.0;
int v0,v1,v2,v3,v4,v5,v6,v7,v8;
v0 = surf->AddVertex( -size,-size,-size );
v1 = surf->AddVertex( size,-size,-size );
v2 = surf->AddVertex( size,size,-size );
v3 = surf->AddVertex( -size,size,-size );
v4 = surf->AddVertex( -size,-size,size );
v5 = surf->AddVertex( size,-size,size );
v6 = surf->AddVertex( size,size,size );
v7 = surf->AddVertex( -size,size,size );
surf->AddTriangle( v0,v1,v2 );
surf->AddTriangle( v2,v3,v0 );
surf->AddTriangle( v4,v5,v6 );
surf->AddTriangle( v6,v7,v4 );
surf->AddTriangle( v0,v4,v3 );
surf->AddTriangle( v4,v7,v3 );
surf->AddTriangle( v1,v5,v2 );
surf->AddTriangle( v5,v6,v2 );
surf->AddTriangle( v0,v1,v4 );
surf->AddTriangle( v1,v5,v4 );
surf->AddTriangle( v3,v2,v7 );
surf->AddTriangle( v2,v6,v7 );
out->AddSurface( surf );
entlist.add( (Base *)out );
return out;
}
};
/*
For all 2d drawing operations.
*/
class Pen
{
public:
Pen()
{
_r=1;
_g=1;
_b=1;
_a=1;
_tex = NULL;
}
void Bind()
{
//Todo:Make a note of current color value.(If possible with PspGL??)
glColor4f( _r,_g,_b,_a );
if(!(_tex==NULL))
{
_tex->Bind();
}
}
void Unbind()
{
//Todo:Return color to previous value.
if(!(_tex==NULL))
{
_tex->Unbind();
}
}
void SetColor( float r,float g,float b,float a)
{
_r=r;
_g=g;
_b=b;
_a=a;
}
void Setcolor( float r,float g,float b )
{
_r=r;
_g=g;
_b=b;
_a=1; //Or leave it at it's present color?
}
void Rect( float x,float y,float w,float h )
{
glBegin(GL_QUADS);
glTexCoord2f( 0,1 );
glVertex2f( x,272-y );
glTexCoord2f( 1,1 );
glVertex2f( x+w,272-y );
glTexCoord2f( 1,0 );
glVertex2f( x+w,272-y-h );
glTexCoord2f( 0,0 );
glVertex2f( x,272-y-h );
glEnd();
}
void Line( float x1,float y1,float x2,float y2 )
{
glBegin(GL_LINES);
glVertex2f( x1,y1 );
glVertex2f( x2,y2 );
glEnd();
}
void RectHollow( float x1,float y1,float w,float h )
{
glBegin(GL_LINES);
glVertex2f( x1,y1 );
glVertex2f( x1+w,y1 );
glVertex2f( x1+w,y1 );
glVertex2f( x1+w,y1+h );
glVertex2f( x1+w,y1+h );
glVertex2f( x1,y1+h );
glVertex2f( x1,y1 );
glVertex2f( x1,y1+h );
}
void SetTexture(Texture *tex)
{
_tex = tex;
}
Texture *_tex;
float _r,_g,_b,_a;
};
class Joypad
{
public:
Joypad()
{
sceCtrlSetSamplingCycle(0);
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
}
void Update()
{
_select = _square = _circle = _cross = _ltrigger = _rtrigger = _start = _left = _right = _up = _down = 0;
sceCtrlReadBufferPositive(&pad, 1);
float xi,yi;
xi = (float)pad.Lx / 255.0f;
yi = (float)pad.Ly / 255.0f;
_x = (xi-0.5f)*2.0f;
_y =-( (yi-0.5f)*2.0f);
if( fabs(_x)<0.2 ) _x=0;
if( fabs(_y)<0.2 ) _y=0;
if (pad.Buttons != 0){
if (pad.Buttons & PSP_CTRL_SQUARE){
_square = 1;
}
if (pad.Buttons & PSP_CTRL_TRIANGLE){
_triangle = 1;
}
if (pad.Buttons & PSP_CTRL_CIRCLE){
_circle = 1;
}
if (pad.Buttons & PSP_CTRL_CROSS){
_cross = 1;
}
if (pad.Buttons & PSP_CTRL_UP){
_up = 1;
}
if (pad.Buttons & PSP_CTRL_DOWN){
_down = 1;
}
if (pad.Buttons & PSP_CTRL_LEFT){
_left = 1;
}
if (pad.Buttons & PSP_CTRL_RIGHT){
_right = 1;
}
if (pad.Buttons & PSP_CTRL_START){
_start = 1;
}
if (pad.Buttons & PSP_CTRL_SELECT){
_select = 1;
}
if (pad.Buttons & PSP_CTRL_LTRIGGER){
_ltrigger = 1;
}
if (pad.Buttons & PSP_CTRL_RTRIGGER){
_rtrigger = 1;
}
}
}
int _cross,_square,_triangle,_circle;
int _left,_right,_up,_down;
int _ltrigger,_rtrigger;
int _select,_start;
float _x,_y;
SceCtrlData pad;
};
class Cursor
{
public:
Cursor(Texture *tex)
{
_size = 32;
_tex = tex;
_style = new Pen();
_style->SetTexture( _tex );
_x = 480/2.0f;
_y = 272/2.0f;
}
void Move( float x,float y)
{
_x+=x;
_y+=y;
if(_x<0)_x=0;
if(_y<0)_y=0;
if(_x>480)_x=480;
if(_y>272)_y=272;
}
void Render()
{
_style->Bind();
_style->Rect(_x,_y,_size,_size );
_style->Unbind();
}
void SetSize(float size)
{
_size = size;
}
Pen *_style;
float _x,_y;
float _size;
Texture *_tex;
};
class Gui
{
public:
Gui( Cursor *cursor,Joypad *joy )
{
_cur = cursor;
_joy = joy;
}
void Update()
{
_cur->Move( _joy->_x,_joy->_y );
}
void Render()
{
_cur->Render();
}
Cursor *_cur;
Joypad *_joy;
};
#define printf pspDebugScreenPrintf
void AddTest()
{
int num1=5;
int num2=10;
int out=0;
int to = 5;
float r17,r16;
r16=0;
r17=0;
for(int i=0;i<to;i++)
{
float res = num1*num2;
r16 = res;
r17 = r16+r17;
}
printf("C Res:%f",r17);
num1 =5;
num2 = 10;
out = 0;
to = 5;
asm __volatile__ ("\n\
ori $5,$0,0\n\
ori $17,$0,0\n\
loop:\n\
mul %1,%2\n\
mflo $16\n\
addu $19,$16,$17\n\
move $17,$19\n\
addiu $5,$5,1\n\
bne $5,%3,loop\n\
nop\n\
move %0,$17\n\
":"=r"(out):"r"(num1),"r"(num2),"r"(to));
printf("Asm Result:%d \n",out);
}
class c1
{
public:
void test()
{
printf("Test 1 called \n");
}
};
class c2 : c1
{
public:
void test()
{
printf("Test 2 called.\n");
}
};
#define new(x) memalign(64, sizeof(x) );
int main(int argc, char **argv)
{
// pspDebugScreenInit();
InitRaptor();
Display *sys = new Display(argc,argv);
Joypad *joy = new Joypad;
Prefab *prefab = new Prefab;
Camera *vcam = Factory->ProduceCamera();
Entity *box = prefab->CreateCube( 10 );
vcam->Position(0,20,-40);
Renderer->_ActiveCam = vcam;
box->Position(0,0,0);
box->Rotate(0,0,0);
vcam->PointAt(0,0,0);
float bx,by;
bx=0;
by=0;
float cp=0,cy=0;
while(1)
{
//vcam->Rotate( vcam->Pitch(),vcam->Yaw(),vcam->Roll() );
joy->Update();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
vcam->Move(0,0,0);
cy+=0.1;
if(cy>360)cy=0;
//mgui->Update();
//mgui->Render();
Renderer->RenderScene();
glutSwapBuffers();
}
return (0);
}
Code: Select all
TARGET = lesson2
OBJS = main.o
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
PSPBIN = $(PSPSDK)/../bin
CFLAGS += -I$(PSPSDK)/../include -fsingle-precision-constant -g -Wall -O2
LIBS += -lGLU -lglut -lGLU -lGL -lm -lc -lpsputility -lpspdebug -lpspge -lpspdisplay -lpspctrl -lpspsdk -lpspvfpu -lpsplibc -lpspuser -lpspkernel -lpsprtc -lpsppower -lstdc++
LDFLAGS += -DMODULE_NAME="lesson2" psp-setup.c
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = LESSON2
# PSP_EBOOT_ICON = hero.png
# PSP_EBOOT_PIC1 = bg.png
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
Ah, closing to understanding it. In cleanign up the code for this post I removed the supposedly redundent code beyond the return call that would never be reached.
Doing so actually fixes the problem. The box no longer disappears.
But putting it back in (as I now have, check above) results in a broken app again, despite the fact the code *should* never be executed as the function returns immediately.
So, alignment issue I'm just not well trained enough in psp to grasp yet?
Doing so actually fixes the problem. The box no longer disappears.
But putting it back in (as I now have, check above) results in a broken app again, despite the fact the code *should* never be executed as the function returns immediately.
So, alignment issue I'm just not well trained enough in psp to grasp yet?
I can't see anything obviously wrong with the code. Try compiling without -O2 to see if it makes a difference (you currenlty add it in twice - and there might be a bug in the optimizer). Other then that, it's looks ok. I also wouldn't redefine .
Code: Select all
new
The compiler isn't THAT buggy. If you're having bugs that disappear when turning off optimizing in such a simple program, it's far more likely that you have some kind of broken edge case or alignment bug in your code, than you actually running into a real compiler bug.
I recommend trying to get the thing working with -O2. Believe me, you will want the speed if you keep adding features to the program, the optimizer makes a big difference.
I recommend trying to get the thing working with -O2. Believe me, you will want the speed if you keep adding features to the program, the optimizer makes a big difference.
http://www.dtek.chalmers.se/~tronic/PSPTexTool.zip Free texture converter for PSP with source. More to come.