view render.c @ 20:ebc55ce699ec

Rotate the other way around: z, y, x - more useful to us
author Josef "Jeff" Sipek <jeffpc@optonline.net>
date Sat, 03 Dec 2005 00:35:58 -0500
parents 4722afb8751c
children 9a34b00c0659
line wrap: on
line source

// System & parser
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>

//  OpenGL
#include "GL/glut.h"

#define BUF_SIZE	1024
#define TIMER_PERIOD	10

#define PIPE_IN		"/tmp/3de.in"
#define PIPE_OUT	"/tmp/3de.out"

int infd;
int outfd;
char *buf, *ptr;

int frames;
struct timespec start;

void display(void);

float cam_x;
float cam_y;
float cam_z;
float cam_ax;
float cam_ay;
float cam_az;

int valid_digit_char(char c)
{
	if (((c >= '0') && (c <= '9')) || (c == '-') || (c == '+') || (c == '.'))
		return 1;
	return 0;
}

char* update_ptr(char* buf)
{
	int i;
	int on_num;

	for(i=0, on_num=0; i<6; buf++) {
		if (!valid_digit_char(*buf) && on_num) {
			on_num = 0;
			i++;
		} else if (valid_digit_char(*buf) && !on_num)
			on_num = 1;
	}

	return buf;
}

void draw_poly(char* buf)
{
	float c1, c2, c3, f1, f2, f3;

	buf += 5;

	glPushMatrix();
	glRotatef(cam_ax, 1.0, 0.0, 0.0);
	glRotatef(cam_ay, 0.0, 1.0, 0.0);
	glRotatef(cam_az, 0.0, 0.0, 1.0);
	glTranslatef(cam_x, cam_y, cam_z);

	glBegin(GL_POLYGON);
	while(1) {
		if (sscanf(buf, "%f %f %f %f %f %f", &c1, &c2, &c3, &f1, &f2, &f3) != 6)
			break;
		glColor3f(c1, c2, c3);
		glVertex3f(f1, f2, f3);
		buf = update_ptr(buf);
	}
	glEnd();

	glPopMatrix();
}

void rot_cam(char* buf)
{
	float x,y,z;

	buf += 7;

	if (sscanf(buf, "%f %f %f", &x, &y, &z) != 3)
		return;

	cam_ax += x;
	cam_ay += y;
	cam_az += z;
}

void trans_cam(char* buf)
{
	float x,y,z;

	buf += 9;

	if (sscanf(buf, "%f %f %f", &x, &y, &z) != 3)
		return;

	cam_x += x;
	cam_y += y;
	cam_z += z;
}

void __key(int c, int x, int y)
{
	printf("key pressed: %c, mouse at (%d,%d)\n", c, x, y);

	switch(c) {
		case GLUT_KEY_LEFT+256:
			write(outfd, "left", 4);
			break;
		case GLUT_KEY_RIGHT+256:
			write(outfd, "right", 5);
			break;
		case GLUT_KEY_UP+256:
			write(outfd, "up", 2);
			break;
		case GLUT_KEY_DOWN+256:
			write(outfd, "down", 4);
			break;
		case ' ':
			write(outfd, "space", 5);
			break;
		default:
			write(outfd, &c, 1);
			break;
	}
	write(outfd, "\n", 1);
}

void key(unsigned char c, int x, int y)
{
	__key((int)c, x, y);
}

void special(int k, int x, int y)
{
	__key(k+256, x, y);
}

void timer(int val)
{
	glutPostRedisplay();
	glutTimerFunc(TIMER_PERIOD, timer, 0);
}

void display(void)
{
	ssize_t r;

	do {
		if ((ptr) >= (buf + BUF_SIZE))
			break;

		r = read(infd, ptr, 1);

		if ((r == -1) || (r == 0) || (*ptr == '\n')) {
			*ptr = '\0';
			break;
		}

		ptr += r;
	} while(1);
#if 0
	if (strlen(buf)) {
		printf("buf = \"%s\"\n", buf);
		fflush(stdout);
	}
#endif
	if (!strncmp(buf, "CLEAR", 5)) {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	} else if (!strncmp(buf, "FLUSH", 5)) {
		glFlush();
		glutSwapBuffers();
	} else if (!strncmp(buf, "POLY", 4))
		draw_poly(buf);
	else if (!strncmp(buf, "ROTCAM", 6))
		rot_cam(buf);
	else if (!strncmp(buf, "TRANSCAM", 8))
		trans_cam(buf);
	else if (strlen(buf)) {
		printf("unknown command\n");
		fflush(stdout);
	}

	ptr = buf;

	frames++;
}

void init()
{
	/* set clear color to black */
	glClearColor (0.0, 0.0, 0.0, 0.0);

	/* set fill color to white */
	glColor3f(1.0, 1.0, 1.0);

	/* set up standard orthogonal view with clipping */
	/* box as cube of side 2 centered at origin */
	/* This is default view and these statement could be removed */
	glMatrixMode (GL_PROJECTION);

	//sets up the projection matrix for a perspective transform
	gluPerspective( 90,     //view angle
			1.0,    //aspect ratio
			0.0,   //near clip
			200.0); //far clip
	glMatrixMode(GL_MODELVIEW);

	/*glLoadIdentity ();
	glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);*/

	cam_x = 0.0;
	cam_y = 0.0;
	cam_z = 0.0;
	cam_ax = 0.0;
	cam_ay = 0.0;
	cam_az = 0.0;
}

#define die() __die(__FILE__, __LINE__);

void __die(char* f, int l)
{
	fprintf(stderr, "Error encountered in %s:%d: %s (%d)\n", f, l, strerror(errno), errno);
}

void goodbye()
{
	struct timespec end;
	double delta;

	clock_gettime(CLOCK_REALTIME, &end);

	delta = ((double) end.tv_sec + 1000000000.0/(double)end.tv_nsec)
	      - ((double) start.tv_sec + 1000000000.0/(double)start.tv_nsec);

	printf("Displayed %d frames in %.4lf seconds = %.4lf fps\n", frames, delta, frames/delta);

	close(infd);
	close(outfd);
}

int main(int argc, char** argv)
{
	frames = 0;

	unlink(PIPE_IN);
	unlink(PIPE_OUT);

	if ((buf = (char*) malloc(sizeof(char)*BUF_SIZE)) == NULL)
		die();
	ptr = buf;

	if (mkfifo(PIPE_IN, 0777) == -1)
		die();

	if (mkfifo(PIPE_OUT, 0777) == -1)
		die();

	if ((infd = open(PIPE_IN, O_RDWR | O_NONBLOCK | O_NDELAY)) == -1)
		die();

	if ((outfd = open(PIPE_OUT, O_RDWR | O_NONBLOCK | O_NDELAY)) == -1)
		die();

	atexit(goodbye);

	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(800,800);
	glutInitWindowPosition(0,0);
	glutCreateWindow("3D Engine");
	glEnable(GL_DEPTH_TEST);
	glutDisplayFunc(display);
	glutKeyboardFunc(key);
	glutSpecialFunc(special);
	init();
	
	clock_gettime(CLOCK_REALTIME, &start);

	//glutIdleFunc(idle);
	glutTimerFunc(TIMER_PERIOD, timer, 0);
	glutMainLoop();


	return 0;
}