#include <v_lib.h>

#define		T_WIDTH		512

u32_t		texture[T_WIDTH * T_WIDTH];

#ifdef	_MSC_VER

/*
 * Faster about 1.1 times :(
 */
void __inline rgba_texel(u32_t x, u32_t y,u8_t r,u8_t g,u8_t b,u8_t a)
{
	__asm {
		mov ebx, y
		shl ebx, 9 /* WARNING: for width == 512 */
		add ebx, x
		mov ah,  b
		mov al,  a
		bswap eax
		mov ah, g
		mov al, r
		mov dword ptr [texture + ebx * 4], eax
	}
}

#else

#define rgba_make(r,g,b,a)		mmioFOURCC(r,g,b,a)
#define	rgba_texel(x,y,r,g,b,a)	(texture[y * T_WIDTH + x] = rgba_make(r,g,b,a))

#endif

GLuint quad;
int frames=0;

void draw_scene()
{
	/*
	int i,j;
	for(i=20;i<492;i++)
	{
		for(j=20;j<364;j++)
			rgba_texel(i,j,c,c,0,0);
	}
	*/
	int i;
	u8_t c = (u8_t)((rand() % 64) + 256 - 64);
	for(i=20;i<364;i++)
		memFill(texture + i * 512 + 20,c,(512-40) * 4);
		
	glClear(GL_COLOR_BUFFER_BIT);
	glTexSubImage2D(GL_TEXTURE_2D,0,0,0,512,384,GL_RGBA,GL_UNSIGNED_BYTE,texture);
	glCallList(quad);
	frames++;
}

vhandle_t c;

void V_CALL wt(void *param)
{
	vboolean *done = (vboolean*)param;
	c = condCreate(true);
	while(!*done)
	{
		condTimedWait(c,1000);
		printf("FPS: %d\n",frames);
		frames=0;
	}
	condDestroy(c);
	threadExit(0);
}
		
int main()
{
	int i,j;
	vhandle_t w;
	vboolean done=false;
	input_record_t r;

    logStartConsoleLog();
    logUpperLevel(LOG_TRACE);

	for(i=0;i<512;i++)
		for(j=0;j<384;j++)
			rgba_texel(i,j,0,0,200,255);
	for(i=10;i<502;i++)
		for(j=10;j<374;j++)
			rgba_texel(i,j,0,200,0,255);
	
/*	vglCreateWindow("temp",0,0,512,384); */
	vglCreateFullscreenWindow("glTexSubImage2D() test",0,0,0,0);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-1,1,-1,1,-1,1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
    
    glTexImage2D(GL_TEXTURE_2D,0,4,T_WIDTH,T_WIDTH,0,GL_RGBA,GL_UNSIGNED_BYTE,texture);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
    
	quad=glGenLists(1);
	glNewList(quad,GL_COMPILE);
		glColor4f(1,1,1,1);
		glBegin(GL_QUADS);
			glTexCoord2f(1,0);
			glVertex2f(1,1);
			glTexCoord2f(0,0);
			glVertex2f(-1,1);
			glTexCoord2f(0,0.75);
			glVertex2f(-1,-1);
			glTexCoord2f(1,0.75);
			glVertex2f(1,-1);
		glEnd();
	glEndList();

	glEnable(GL_TEXTURE_2D);
	
	w=threadCreate(wt,&done);
	
	do
	{
		while(!vglPending())
		{
			draw_scene();
			vglSwapBuffers();
		}
		vglNextEvent(&r);
	} while(r.event!=ev_key_down || r.first_code!=key_escape);

	/* Catch watcher */
	done=true;
	condPulse(c);
	threadJoin(w,NULL);

	vglDestroyWindow(vglGetCurrentWindow());
    memPrintStats();
    return 0;
}
