[Bf-committers] windows coder needed!

Holger Haase bf-committers@blender.org
Fri, 13 Jun 2003 19:21:30 +0200


This is a multi-part message in MIME format.

------=_NextPart_000_0003_01C331E0.FE500C00
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

hi ton!

the multimedia timer did it.

the modified files are blender\projectfiles\blender\blender.dsp (now with
winmm.lib)
and blender\source\blender\src\renderwin.c.
please put them into cvs.

i compared the render times between a version with the timer and one without
it and realized no difference.

if you are interested in the pros and cons of the different windows timers,
there's an article at http://www.codeproject.com/system/timers_intro.asp.

-
 holger

------=_NextPart_000_0003_01C331E0.FE500C00
Content-Type: application/octet-stream;
	name="renderwin.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="renderwin.c"

/**
 * $Id: renderwin.c,v 1.11 2003/06/13 13:54:08 ton Exp $
 *
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software =
Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */

#ifdef WIN32
/* for the multimedia timer */
#include <windows.h>
#include <mmsystem.h>
#endif

#include <string.h>
#include <stdarg.h>
#include <math.h>

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifdef WIN32
#include "BLI_winstuff.h"
#else
 /* for signal callback, not (fully) supported at windows */
#include <sys/time.h>
#include <signal.h>

#endif

#include "BLI_blenlib.h"

#include "MEM_guardedalloc.h"

#include "BMF_Api.h"

#include "DNA_view3d_types.h"
#include "DNA_screen_types.h"
#include "DNA_vec_types.h"

#include "BKE_global.h"
#include "BKE_utildefines.h"

#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "BIF_graphics.h"
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_mywindow.h"
#include "BIF_renderwin.h"
#include "BIF_toets.h"

#include "BDR_editobject.h"

#include "BSE_view.h"
#include "BSE_drawview.h"
#include "BSE_filesel.h"
#include "BSE_headerbuttons.h"

#include "blendef.h"
#include "mydevice.h"
#include "winlay.h"
#include "render.h"

/* ------------ renderwin struct, to prevent too much global vars =
--------- */
/* ------------ only used for display in a 2nd window  --------- */


/* flags escape presses during event handling
* so we can test for user break later.
*/
#define RW_FLAGS_ESCAPE		(1<<0)
/* old zoom style (2x, locked to mouse, exits
* when mouse leaves window), to be removed
* at some point.
*/
#define RW_FLAGS_OLDZOOM		(1<<1)
/* on when image is being panned with middlemouse
*/
#define RW_FLAGS_PANNING		(1<<2)
/* on when the mouse is dragging over the image
* to examine pixel values.
*/
#define RW_FLAGS_PIXEL_EXAMINING	(1<<3)


typedef struct {
	Window *win;

	float zoom, zoomofs[2];
	int active;
=09
	int mbut[3];
	int lmouse[2];
=09
	unsigned int flags;
=09
	float pan_mouse_start[2], pan_ofs_start[2];

	char *info_text;
} RenderWin;

static RenderWin *render_win=3D NULL;

/* --------------- help functions for RenderWin struct =
---------------------------- */


/* only called in function open_renderwin */
static RenderWin *renderwin_alloc(Window *win)
{
	RenderWin *rw=3D MEM_mallocN(sizeof(*rw), "RenderWin");
	rw->win=3D win;
	rw->zoom=3D 1.0;
	rw->active=3D 0;
	rw->flags=3D 0;
	rw->zoomofs[0]=3D rw->zoomofs[1]=3D 0;
	rw->info_text=3D NULL;

	rw->lmouse[0]=3D rw->lmouse[1]=3D 0;
	rw->mbut[0]=3D rw->mbut[1]=3D rw->mbut[2]=3D 0;

	return rw;
}


static void renderwin_queue_redraw(RenderWin *rw)
{
	window_queue_redraw(rw->win); // to ghost
}

static void renderwin_reshape(RenderWin *rw)
{
	;
}

static void renderwin_get_disprect(RenderWin *rw, float =
disprect_r[2][2])
{
	float display_w, display_h;
	float cent_x, cent_y;
	int w, h;

	window_get_size(rw->win, &w, &h);

	display_w=3D R.rectx*rw->zoom;
	display_h=3D R.recty*rw->zoom;
	cent_x=3D (rw->zoomofs[0] + R.rectx/2)*rw->zoom;
	cent_y=3D (rw->zoomofs[1] + R.recty/2)*rw->zoom;
=09
	disprect_r[0][0]=3D w/2 - cent_x;
	disprect_r[0][1]=3D h/2 - cent_y;
	disprect_r[1][0]=3D disprect_r[0][0] + display_w;
	disprect_r[1][1]=3D disprect_r[0][1] + display_h;
}

	/**=20
	 * Project window coordinate to image pixel coordinate.
	 * Returns true if resulting coordinate is within image.
	 */
static int renderwin_win_to_image_co(RenderWin *rw, int winco[2], int =
imgco_r[2])
{
	float disprect[2][2];
=09
	renderwin_get_disprect(rw, disprect);
=09
	imgco_r[0]=3D (int) ((winco[0]-disprect[0][0])/rw->zoom);
	imgco_r[1]=3D (int) ((winco[1]-disprect[0][1])/rw->zoom);
=09
	return (imgco_r[0]>=3D0 && imgco_r[1]>=3D0 && imgco_r[0]<R.rectx && =
imgco_r[1]<R.recty);
}

	/**
	 * Project window coordinates to normalized device coordinates
	 * Returns true if resulting coordinate is within window.
	 */
static int renderwin_win_to_ndc(RenderWin *rw, int win_co[2], float =
ndc_r[2])
{
	int w, h;

	window_get_size(rw->win, &w, &h);

	ndc_r[0]=3D (float) ((win_co[0]*2)/(w-1) - 1.0);
	ndc_r[1]=3D (float) ((win_co[1]*2)/(h-1) - 1.0);

	return (fabs(ndc_r[0])<=3D1.0 && fabs(ndc_r[1])<=3D1.0);
}

static void renderwin_set_infotext(RenderWin *rw, char *info_text)
{
	if (rw->info_text) MEM_freeN(rw->info_text);
	rw->info_text=3D info_text?BLI_strdup(info_text):NULL;
}

static void renderwin_reset_view(RenderWin *rw)
{
	if (rw->info_text) renderwin_set_infotext(rw, NULL);

	rw->zoom=3D 1.0;
	rw->zoomofs[0]=3D rw->zoomofs[1]=3D 0;
	renderwin_queue_redraw(rw);
}

static void renderwin_draw(RenderWin *rw, int just_clear)
{
	float disprect[2][2];
	rcti rect;

	rect.xmin=3D rect.ymin=3D 0;
	window_get_size(rw->win, &rect.xmax, &rect.ymax);
	renderwin_get_disprect(rw, disprect);
=09
	window_make_active(rw->win);
=09
	glEnable(GL_SCISSOR_TEST);
	glaDefine2DArea(&rect);
=09
	glClearColor(.1875, .1875, .1875, 1.0);=20
	glClear(GL_COLOR_BUFFER_BIT);

	if (just_clear || !R.rectot) {
		glColor3ub(0, 0, 0);
		glRectfv(disprect[0], disprect[1]);
	} else {
		glPixelZoom(rw->zoom, rw->zoom);
		glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, =
R.rectot);
		glPixelZoom(1.0, 1.0);
	}
=09
	if (rw->info_text) {
		glColor3ub(255, 255, 255);
		glRasterPos2i(10, 10);
		BMF_DrawString(G.font, rw->info_text);
	}

	window_swap_buffers(rw->win);
}

/* ------ interactivity calls for RenderWin ------------- */

static void renderwin_mouse_moved(RenderWin *rw)
{
	if (rw->flags&RW_FLAGS_PIXEL_EXAMINING) {
		int imgco[2];
		char buf[64];

		if (R.rectot && renderwin_win_to_image_co(rw, rw->lmouse, imgco)) {
			unsigned char *pxl=3D (char*) &R.rectot[R.rectx*imgco[1] + imgco[0]];

			sprintf(buf, "R: %d, G: %d, B: %d, A: %d", pxl[0], pxl[1], pxl[2], =
pxl[3]);
			renderwin_set_infotext(rw, buf);
			renderwin_queue_redraw(rw);
		} else {
			renderwin_set_infotext(rw, NULL);
			renderwin_queue_redraw(rw);
		}
	} else if (rw->flags&RW_FLAGS_PANNING) {
		int delta_x=3D rw->lmouse[0] - rw->pan_mouse_start[0];
		int delta_y=3D rw->lmouse[1] - rw->pan_mouse_start[1];
=09
		rw->zoomofs[0]=3D rw->pan_ofs_start[0] - delta_x/rw->zoom;
		rw->zoomofs[1]=3D rw->pan_ofs_start[1] - delta_y/rw->zoom;
		rw->zoomofs[0]=3D CLAMPIS(rw->zoomofs[0], -R.rectx/2, R.rectx/2);
		rw->zoomofs[1]=3D CLAMPIS(rw->zoomofs[1], -R.recty/2, R.recty/2);

		renderwin_queue_redraw(rw);
	} else if (rw->flags&RW_FLAGS_OLDZOOM) {
		float ndc[2];
		int w, h;

		window_get_size(rw->win, &w, &h);
		renderwin_win_to_ndc(rw, rw->lmouse, ndc);

		rw->zoomofs[0]=3D -0.5*ndc[0]*(w-R.rectx*rw->zoom)/rw->zoom;
		rw->zoomofs[1]=3D -0.5*ndc[1]*(h-R.recty*rw->zoom)/rw->zoom;

		renderwin_queue_redraw(rw);
	}
}

static void renderwin_mousebut_changed(RenderWin *rw)
{
	if (rw->mbut[0]) {
		rw->flags|=3D RW_FLAGS_PIXEL_EXAMINING;
	} else if (rw->mbut[1]) {
		rw->flags|=3D RW_FLAGS_PANNING;
		rw->pan_mouse_start[0]=3D rw->lmouse[0];
		rw->pan_mouse_start[1]=3D rw->lmouse[1];
		rw->pan_ofs_start[0]=3D rw->zoomofs[0];
		rw->pan_ofs_start[1]=3D rw->zoomofs[1];
	} else {
		if (rw->flags&RW_FLAGS_PANNING) {
			rw->flags&=3D ~RW_FLAGS_PANNING;
			renderwin_queue_redraw(rw);
		}
		if (rw->flags&RW_FLAGS_PIXEL_EXAMINING) {
			rw->flags&=3D ~RW_FLAGS_PIXEL_EXAMINING;
			renderwin_set_infotext(rw, NULL);
			renderwin_queue_redraw(rw);
		}
	}
}


/* handler for renderwin, passed on to Ghost */
static void renderwin_handler(Window *win, void *user_data, short evt, =
short val, char ascii)
{
	RenderWin *rw=3D user_data;

	if (evt=3D=3DRESHAPE) {
		renderwin_reshape(rw);
	} else if (evt=3D=3DREDRAW) {
		renderwin_draw(rw, 0);
#ifndef __APPLE__
	} else if (evt=3D=3DWINCLOSE) {
		BIF_close_render_display();
#endif
	} else if (evt=3D=3DINPUTCHANGE) {
		rw->active=3D val;

		if (!val && (rw->flags&RW_FLAGS_OLDZOOM)) {
			rw->flags&=3D ~RW_FLAGS_OLDZOOM;
			renderwin_reset_view(rw);
		}
	} else if (ELEM(evt, MOUSEX, MOUSEY)) {
		rw->lmouse[evt=3D=3DMOUSEY]=3D val;
		renderwin_mouse_moved(rw);
	} else if (ELEM3(evt, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE)) {
		int which=3D (evt=3D=3DLEFTMOUSE)?0:(evt=3D=3DMIDDLEMOUSE)?1:2;
		rw->mbut[which]=3D val;
		renderwin_mousebut_changed(rw);
	} else if (val) {
		if (evt=3D=3DESCKEY) {
			if (rw->flags&RW_FLAGS_OLDZOOM) {
				rw->flags&=3D ~RW_FLAGS_OLDZOOM;
				renderwin_reset_view(rw);
			} else {
				rw->flags|=3D RW_FLAGS_ESCAPE;
				mainwindow_raise();
			}
		} else if (evt=3D=3DJKEY) {
			BIF_swap_render_rects();
		} else if (evt=3D=3DZKEY) {
			if (rw->flags&RW_FLAGS_OLDZOOM) {
				rw->flags&=3D ~RW_FLAGS_OLDZOOM;
				renderwin_reset_view(rw);
			} else {
				rw->zoom=3D 2.0;
				rw->flags|=3D RW_FLAGS_OLDZOOM;
				renderwin_mouse_moved(rw);
			}
		} else if (evt=3D=3DPADPLUSKEY) {
			if (rw->zoom<15.9) {
				rw->zoom*=3D 2.0;
				renderwin_queue_redraw(rw);
			}
		} else if (evt=3D=3DPADMINUS) {
			if (rw->zoom>0.26) {
				rw->zoom*=3D 0.5;
				renderwin_queue_redraw(rw);
			}
		} else if (evt=3D=3DPADENTER || evt=3D=3DHOMEKEY) {
			if (rw->flags&RW_FLAGS_OLDZOOM) {
				rw->flags&=3D ~RW_FLAGS_OLDZOOM;
			}
			renderwin_reset_view(rw);
		} else if (evt=3D=3DF3KEY) {
			mainwindow_raise();
			mainwindow_make_active();
			areawinset(find_biggest_area()->win);
			BIF_save_rendered_image();
		} else if (evt=3D=3DF11KEY) {
			BIF_toggle_render_display();
		} else if (evt=3D=3DF12KEY) {
			BIF_do_render(0);
		}
	}
}


/* opens window and allocs struct */
static void open_renderwin(int winpos[2], int winsize[2])
{
	Window *win;

	win=3D window_open("Blender:Render", winpos[0], winpos[1], winsize[0], =
winsize[1], 0);

	render_win=3D renderwin_alloc(win);

	/* Ghost calls handler */
	window_set_handler(win, renderwin_handler, render_win);

	winlay_process_events(0);
	window_make_active(render_win->win);
	winlay_process_events(0);

	renderwin_draw(render_win, 1);
	renderwin_draw(render_win, 1);
}

/* -------------- callbacks for render loop: Window (RenderWin) =
----------------------- */

/* calculations for window size and position */
void calc_renderwin_rectangle(int posmask, int renderpos_r[2], int =
rendersize_r[2])=20
{
	int scr_w, scr_h, x, y, div=3D 0;
	float ndc_x=3D 0.0, ndc_y=3D 0.0;

		/* XXX, we temporarily hack the screen size and position so
		 * the window is always 30 pixels away from a side, really need
		 * a GHOST_GetMaxWindowBounds or so - zr
		 */
	winlay_get_screensize(&scr_w, &scr_h);
=09
	rendersize_r[0]=3D (G.scene->r.size*G.scene->r.xsch)/100;
	rendersize_r[1]=3D (G.scene->r.size*G.scene->r.ysch)/100;
	if(G.scene->r.mode & R_PANORAMA) {
		rendersize_r[0]*=3D G.scene->r.xparts;
		rendersize_r[1]*=3D G.scene->r.yparts;
	}

	rendersize_r[0]=3D CLAMPIS(rendersize_r[0], 100, scr_w-90);
	rendersize_r[1]=3D CLAMPIS(rendersize_r[1], 100, scr_h-90);

	for (y=3D-1; y<=3D1; y++) {
		for (x=3D-1; x<=3D1; x++) {
			if (posmask & (1<<((y+1)*3 + (x+1)))) {
				ndc_x+=3D x;
				ndc_y+=3D y;
				div++;
			}
		}
	}

	if (div) {
		ndc_x/=3D div;
		ndc_y/=3D div;
	}
	=09
	renderpos_r[0]=3D 60 + (scr_w-90-rendersize_r[0])*(ndc_x*0.5 + 0.5);
	renderpos_r[1]=3D 30 + (scr_h-90-rendersize_r[1])*(ndc_y*0.5 + 0.5);
}
=09
/* init renderwin, alloc/open/resize */
static void renderwin_init_display_cb(void)=20
{
	if (G.afbreek =3D=3D 0) {
		int rendersize[2], renderpos[2];

		calc_renderwin_rectangle(R.winpos, renderpos, rendersize);

		if (!render_win) {
			open_renderwin(renderpos, rendersize);
		} else {
			int win_x, win_y;
			int win_w, win_h;

			window_get_position(render_win->win, &win_x, &win_y);
			window_get_size(render_win->win, &win_w, &win_h);

				/* XXX, this is nasty and I guess bound to cause problems,
				 * but to ensure the window is at the user specified position
				 * and size we reopen the window all the time... we need
				 * a ghost _set_position to fix this -zr
				 */
			BIF_close_render_display();
			open_renderwin(renderpos, rendersize);

			renderwin_reset_view(render_win);
			render_win->flags&=3D ~RW_FLAGS_ESCAPE;
		}
	}
}

/* callback for redraw render win */
static void renderwin_clear_display_cb(short ignore)=20
{
	if (render_win) {
		window_make_active(render_win->win);=09
		renderwin_draw(render_win, 1);
	}
}

/* XXX, this is not good, we do this without any regard to state
* ... better is to make this an optimization of a more clear
* implementation. the bug shows up when you do something like
* open the window, then draw part of the progress, then get
* a redraw event. whatever can go wrong will.
*/

/* in render window; display a couple of scanlines of rendered image =
(see callback below) */
static void renderwin_progress(RenderWin *rw, int start_y, int nlines, =
int rect_w, int rect_h, unsigned char *rect)
{
	float disprect[2][2];
	rcti win_rct;

	win_rct.xmin=3D win_rct.ymin=3D 0;
	window_get_size(rw->win, &win_rct.xmax, &win_rct.ymax);
	renderwin_get_disprect(rw, disprect);

	window_make_active(rw->win);

	glEnable(GL_SCISSOR_TEST);
	glaDefine2DArea(&win_rct);

	glDrawBuffer(GL_FRONT);
	glPixelZoom(rw->zoom, rw->zoom);
	glaDrawPixelsSafe(disprect[0][0], disprect[0][1] + start_y*rw->zoom, =
rect_w, nlines, &rect[start_y*rect_w*4]);
	glPixelZoom(1.0, 1.0);
	glFlush();
	glDrawBuffer(GL_BACK);
}


/* in render window; display a couple of scanlines of rendered image */
static void renderwin_progress_display_cb(int y1, int y2, int w, int h, =
unsigned int *rect)
{
	if (render_win) {
		renderwin_progress(render_win, y1, y2-y1+1, w, h, (unsigned char*) =
rect);
	}
}


/* -------------- callbacks for render loop: in View3D =
----------------------- */


static View3D *render_view3d =3D NULL;

/* init Render view callback */
static void renderview_init_display_cb(void)
{
	ScrArea *sa;

		/* Choose the first view with a persp camera,
		 * if one doesn't exist we will get the first
		 * View3D window.
		 */=20
	render_view3d=3D NULL;
	for (sa=3D G.curscreen->areabase.first; sa; sa=3D sa->next) {
		if (sa->win && sa->spacetype=3D=3DSPACE_VIEW3D) {
			View3D *vd=3D sa->spacedata.first;
		=09
			if (vd->persp=3D=3D2 && vd->camera=3D=3DG.scene->camera) {
				render_view3d=3D vd;
				break;
			} else if (!render_view3d) {
				render_view3d=3D vd;
			}
		}
	}
}


/* in 3d view; display a couple of scanlines of rendered image */
static void renderview_progress_display_cb(int y1, int y2, int w, int h, =
unsigned int *rect)
{
	if (render_view3d) {
		View3D *v3d=3D render_view3d;
		int nlines=3D y2-y1+1;
		float sx, sy, facx, facy;
		rcti win_rct, vb;

		calc_viewborder(v3d, &vb);

		facx=3D (float) (vb.xmax-vb.xmin)/R.rectx;
		facy=3D (float) (vb.ymax-vb.ymin)/R.recty;

		bwin_get_rect(v3d->area->win, &win_rct);

		glaDefine2DArea(&win_rct);
=09
		glDrawBuffer(GL_FRONT);
	=09
		sx=3D vb.xmin;
		sy=3D vb.ymin + facy*y1;

		glPixelZoom(facx, facy);
		glaDrawPixelsSafe(sx, sy, w, nlines, rect+w*y1);
		glPixelZoom(1.0, 1.0);

		glFlush();
		glDrawBuffer(GL_BACK);
	=09
		v3d->flag |=3D V3D_DISPIMAGE;
				=09
		v3d->area->win_swap=3D WIN_FRONT_OK;
	}
}

/* -------------- callbacks for render loop: interactivity =
----------------------- */


/* callback for print info in top header in interface */
static void printrenderinfo_cb(double time, int sample)
{
	extern int mem_in_use;
	float megs_used_memory=3D mem_in_use/(1024.0*1024.0);
	char str[300], tstr[32], *spos=3D str;
	=09
	timestr(time, tstr);
	spos+=3D sprintf(spos, "RENDER  Fra:%d  Ve:%d Fa:%d La:%d", =
(G.scene->r.cfra), R.totvert, R.totvlak, R.totlamp);
	spos+=3D sprintf(spos, "Mem:%.2fM Time:%s ", megs_used_memory, tstr);

	if (R.r.mode & R_FIELDS) {
		spos+=3D sprintf(spos, "Field %c ", (R.flag&R_SEC_FIELD)?'B':'A');
	}
	if (sample!=3D-1) {
		spos+=3D sprintf(spos, "Sample: %d ", sample);
	}
=09
	screen_draw_info_text(G.curscreen, str);
}

/* -------------- callback system to allow ESC from rendering =
----------------------- */

/* WIN32: this function is called all the time, and should not use cpu =
or resources */
static int test_break()
{

	if(G.afbreek=3D=3D2) { /* code for testing queue */

		G.afbreek=3D 0;

		blender_test_break(); /* tests blender interface */

		if (G.afbreek=3D=3D0 && render_win) { /* tests window */
			winlay_process_events(0);
			// render_win can be closed in winlay_process_events()
			if (render_win =3D=3D 0 || (render_win->flags & RW_FLAGS_ESCAPE))
				G.afbreek=3D 1;
		}
	}

	if(G.afbreek=3D=3D1) return 1;
	else return 0;
}

#ifdef _WIN32
/* we use the multimedia time here */
static UINT uRenderTimerId;

VOID CALLBACK interruptESC(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, =
DWORD dw2)
{
	if(G.afbreek=3D=3D0) G.afbreek=3D 2;	/* code for read queue */
}

/* WIN32: init Timer callback */
static void init_test_break_callback()
{
	timeBeginPeriod(50);
  uRenderTimerId =3D timeSetEvent(250, 1, interruptESC, 0, =
TIME_PERIODIC);
}

/* WIN32: stop Timer callback */
static void end_test_break_callback()
{
	timeEndPeriod(50);
	timeKillEvent(uRenderTimerId);
}

#else
/* all other OS's support signal(SIGVTALRM) */

/* POSIX: this function goes in the signal() callback */
static void interruptESC(int sig)
{

	if(G.afbreek=3D=3D0) G.afbreek=3D 2;	/* code for read queue */

	/* call again, timer was reset */
	signal(SIGVTALRM, interruptESC);
}

/* POSIX: initialize timer and signal */
static void init_test_break_callback()
{

	struct itimerval tmevalue;

	tmevalue.it_interval.tv_sec =3D 0;
	tmevalue.it_interval.tv_usec =3D 250000;
	/* wanneer de eerste ? */
	tmevalue.it_value.tv_sec =3D 0;
	tmevalue.it_value.tv_usec =3D 10000;

	signal(SIGVTALRM, interruptESC);
	setitimer(ITIMER_VIRTUAL, &tmevalue, 0);

}

/* POSIX: stop timer and callback */
static void end_test_break_callback()
{
	struct itimerval tmevalue;

	tmevalue.it_value.tv_sec =3D 0;
	tmevalue.it_value.tv_usec =3D 0;
	setitimer(ITIMER_VIRTUAL, &tmevalue, 0);
	signal(SIGVTALRM, SIG_IGN);

}

#endif


/* -------------- callbacks for render loop: init & run! =
----------------------- */


/* - initialize displays
   - both opengl render as blender render
   - set callbacks
   - cleanup
*/

static void do_render(View3D *ogl_render_view3d, int anim, int =
force_dispwin)
{
	if (R.displaymode =3D=3D R_DISPLAYWIN || force_dispwin) {
		RE_set_initrenderdisplay_callback(NULL);
		RE_set_clearrenderdisplay_callback(renderwin_clear_display_cb);
		RE_set_renderdisplay_callback(renderwin_progress_display_cb);

		renderwin_init_display_cb();
	} else {
		BIF_close_render_display();

		RE_set_initrenderdisplay_callback(renderview_init_display_cb);
		RE_set_clearrenderdisplay_callback(NULL);
		RE_set_renderdisplay_callback(renderview_progress_display_cb);
	}

	init_test_break_callback();
	RE_set_test_break_callback(test_break);
=09
	RE_set_timecursor_callback(set_timecursor);
	RE_set_printrenderinfo_callback(printrenderinfo_cb);
=09
	if (render_win) window_set_cursor(render_win->win, CURSOR_WAIT);
	waitcursor(1);

	G.afbreek=3D 0;
	if(G.obedit && !(G.scene->r.scemode & R_OGL)) {
		exit_editmode(0);	/* 0 =3D no free data */
	}

	if(anim) {
		RE_animrender(ogl_render_view3d);
	}
	else {
		RE_initrender(ogl_render_view3d);
	}
	update_for_newframe();
	R.flag=3D 0;
=09
	if (render_win) window_set_cursor(render_win->win, CURSOR_STD);
	waitcursor(0);

	free_filesel_spec(G.scene->r.pic);

	G.afbreek=3D 0;
	end_test_break_callback();
	mainwindow_make_active();
}

/* finds area with a 'dispview' set */
static ScrArea *find_dispimage_v3d(void)
{
	ScrArea *sa;
=09
	for (sa=3D G.curscreen->areabase.first; sa; sa=3D sa->next) {
		if (sa->spacetype=3D=3DSPACE_VIEW3D) {
			View3D *vd=3D sa->spacedata.first;
			if (vd->flag & V3D_DISPIMAGE)
				return sa;
		}
	}
=09
	return NULL;
}

/* used for swapping with spare buffer, when images are different size =
*/
static void scalefastrect(unsigned int *recto, unsigned int *rectn, int =
oldx, int oldy, int newx, int newy)
{
	unsigned int *rect, *newrect;
	int x, y;
	int ofsx, ofsy, stepx, stepy;

	stepx =3D (int)((65536.0 * (oldx - 1.0) / (newx - 1.0)) + 0.5);
	stepy =3D (int)((65536.0 * (oldy - 1.0) / (newy - 1.0)) + 0.5);
	ofsy =3D 32768;
	newrect=3D rectn;
=09
	for (y =3D newy; y > 0 ; y--){
		rect =3D recto;
		rect +=3D (ofsy >> 16) * oldx;
		ofsy +=3D stepy;
		ofsx =3D 32768;
		for (x =3D newx ; x>0 ; x--){
			*newrect++ =3D rect[ofsx >> 16];
			ofsx +=3D stepx;
		}
	}
}

/* -------------- API: externally called --------------- */

/* set up display, render an image or scene */
void BIF_do_render(int anim)
{
	do_render(NULL, anim, 0);
}

/* set up display, render the current area view in an image */
void BIF_do_ogl_render(View3D *ogl_render_view3d, int anim)
{
	G.scene->r.scemode |=3D R_OGL;
	do_render(ogl_render_view3d, anim, 1);
	G.scene->r.scemode &=3D ~R_OGL;
}

void BIF_swap_render_rects(void)
{
	unsigned int *temp;

	if(R.rectspare=3D=3D0) {
		R.rectspare=3D (unsigned int =
*)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot");
		R.sparex=3D R.rectx;
		R.sparey=3D R.recty;
	}
	else if(R.sparex!=3DR.rectx || R.sparey!=3DR.recty) {
		temp=3D (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, =
"rectot");
				=09
		scalefastrect(R.rectspare, temp, R.sparex, R.sparey, R.rectx, =
R.recty);
		MEM_freeN(R.rectspare);
		R.rectspare=3D temp;
				=09
		R.sparex=3D R.rectx;
		R.sparey=3D R.recty;
	}
=09
	temp=3D R.rectot;
	R.rectot=3D R.rectspare;
	R.rectspare=3D temp;

	/* redraw */
	if (R.displaymode =3D=3D R_DISPLAYWIN) {
		// don't open render_win if rendering has been
	    // canceled or the render_win has been actively closed
		if (render_win) {
			renderwin_queue_redraw(render_win);
		}
	} else {
		renderview_init_display_cb();
		renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, =
R.rectot);
	}
}			=09

/* called from usiblender.c too, to free and close renderwin */
void BIF_close_render_display(void)
{
	if (render_win) {

		if (render_win->info_text) MEM_freeN(render_win->info_text);

		window_destroy(render_win->win); /* ghost close window */
		MEM_freeN(render_win);

		render_win=3D NULL;
	}
}


/* typical with F11 key, show image or hide/close */
void BIF_toggle_render_display(void)=20
{
	ScrArea *sa=3D find_dispimage_v3d();
=09
	if (render_win && render_win->active) {
		if (R.displaymode =3D=3D R_DISPLAYVIEW) {
			BIF_close_render_display();
		}
		mainwindow_raise();
	} else if (sa) {
		View3D *vd=3D sa->spacedata.first;
		vd->flag &=3D ~V3D_DISPIMAGE;
		scrarea_queue_winredraw(sa);
	} else {
		if (R.displaymode =3D=3D R_DISPLAYWIN) {
			renderwin_init_display_cb();
		} else {
			if (render_win) {
				BIF_close_render_display();
			}
			renderview_init_display_cb();
			renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, =
R.rectot);
		}
	}
}

void BIF_renderwin_set_custom_cursor(unsigned char mask[16][2], unsigned =
char bitmap[16][2])
{
	if (render_win) {
		window_set_custom_cursor(render_win->win, mask, bitmap);
	}
}

------=_NextPart_000_0003_01C331E0.FE500C00
Content-Type: application/octet-stream;
	name="blender.dsp"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="blender.dsp"

# Microsoft Developer Studio Project File - Name=3D"blender" - Package =
Owner=3D<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** NICHT BEARBEITEN **

# TARGTYPE "Win32 (x86) Console Application" 0x0103

CFG=3Dblender - Win32 Release
!MESSAGE Dies ist kein g=FCltiges Makefile. Zum Erstellen dieses =
Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und f=FChren =
Sie den Befehl
!MESSAGE=20
!MESSAGE NMAKE /f "blender.mak".
!MESSAGE=20
!MESSAGE Sie k=F6nnen beim Ausf=FChren von NMAKE eine Konfiguration =
angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum =
Beispiel:
!MESSAGE=20
!MESSAGE NMAKE /f "blender.mak" CFG=3D"blender - Win32 Release"
!MESSAGE=20
!MESSAGE F=FCr die Konfiguration stehen zur Auswahl:
!MESSAGE=20
!MESSAGE "blender - Win32 Release" (basierend auf  "Win32 (x86) Console =
Application")
!MESSAGE "blender - Win32 Debug" (basierend auf  "Win32 (x86) Console =
Application")
!MESSAGE=20

# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=3Dcl.exe
RSC=3Drc.exe

!IF  "$(CFG)" =3D=3D "blender - Win32 Release"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\..\obj\windows\blender"
# PROP Intermediate_Dir "..\..\obj\windows\blender"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" =
/D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\source\blender\misc" /I =
"..\..\..\lib\windows\guardedalloc\include" /I =
"..\..\source\blender\blenlib" /I "..\..\source\kernel\gen_messaging" /I =
"..\..\source\blender\include" /I "..\..\source\blender" /I =
"..\..\source\blender\makesdna" /I "..\..\source\blender\blenkernel" /I =
"..\..\source\blender\blenloader" /I =
"..\..\source\blender\bpython\include" /I =
"..\..\source\blender\render\extern\include" /I =
"..\..\source\blender\radiosity\extern\include" /I =
"..\..\source\kernel\gen_system" /I =
"..\..\source\blender\renderconverter\\" /I =
"..\..\source\blender\renderui\\" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" =
/D "_MBCS" /D "WITH_QUICKTIME" /YX /FD /c
# ADD BASE RSC /l 0x413 /d "NDEBUG"
# ADD RSC /l 0x413 /d "NDEBUG"
BSC32=3Dbscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=3Dlink.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib =
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib =
odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib =
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib =
odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 freetype2ST.lib ftgl_static_ST.lib gnu_gettext.lib =
qtmlClient.lib odelib.lib openal_static.lib libguardedalloc.a libbsp.a =
libbmfont.a libghost.a libstring.a ws2_32.lib dxguid.lib opengl32.lib =
libjpeg.a glu32.lib user32.lib gdi32.lib vfw32.lib advapi32.lib =
ole32.lib winmm.lib libdecimation.a libblenkey.a libeay32.lib =
libiksolver.a libpng.a libz.a libmoto.a /nologo /subsystem:console =
/machine:I386 /nodefaultlib:"msvcprt.lib" /nodefaultlib:"glut32.lib" =
/nodefaultlib:"libcd.lib" /nodefaultlib:"libc.lib" =
/nodefaultlib:"libcpd.lib" /nodefaultlib:"libcp.lib" =
/nodefaultlib:"libcmtd.lib" /out:"..\..\bin\blender.exe" =
/libpath:"..\..\..\lib\windows\freetype\lib" =
/libpath:"..\..\..\lib\windows\ftgl\lib" =
/libpath:"..\..\..\lib\windows\gettext\lib" =
/libpath:"..\..\..\lib\windows\ode\lib" =
/libpath:"..\..\..\lib\windows\bsp\lib" =
/libpath:"..\..\..\lib\windows\moto\lib" =
/libpath:"..\..\..\lib\windows\bmfont\lib" =
/libpath:"..\..\..\lib\windows\ghost\lib" =
/libpath:"..\..\..\lib\windows\python\frozen" =
/libpath:"..\..\..\lib\windows\guardedalloc\lib" =
/libpath:"..\..\..\lib\windows\string\lib" =
/libpath:"..\..\..\lib\windows\python\lib" =
/libpath:"..\..\..\lib\windows\iksolver\lib" =
/libpath:"..\..\..\lib\windows\decimation\lib" =
/libpath:"..\..\..\lib\windows\openal\lib" =
/libpath:"..\..\..\lib\windows\jpeg\lib" =
/libpath:"..\..\..\lib\windows\blenkey\lib" =
/libpath:"..\..\..\lib\windows\openssl\lib" =
/libpath:"..\..\..\lib\windows\zlib\lib\\" =
/libpath:"..\..\..\lib\windows\png\lib\\"
# SUBTRACT LINK32 /pdb:none
# Begin Special Build Tool
SOURCE=3D"$(InputPath)"
PostBuild_Cmds=3DECHO Copying required 3rd party dlls...	XCOPY /Y =
..\..\..\lib\windows\gettext\lib\*.dll ..\..\bin\	ECHO Done
# End Special Build Tool

!ELSEIF  "$(CFG)" =3D=3D "blender - Win32 Debug"

# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\..\obj\windows\blender\debug"
# PROP Intermediate_Dir "..\..\obj\windows\blender\debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D =
"_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I =
"..\..\source\blender\misc" /I =
"..\..\..\lib\windows\guardedalloc\include" /I =
"..\..\source\blender\blenlib" /I "..\..\source\kernel\gen_messaging" /I =
"..\..\source\blender\include" /I "..\..\source\blender" /I =
"..\..\source\blender\makesdna" /I "..\..\source\blender\blenkernel" /I =
"..\..\source\blender\blenloader" /I =
"..\..\source\blender\bpython\include" /I =
"..\..\source\blender\render\extern\include" /I =
"..\..\source\blender\radiosity\extern\include" /I =
"..\..\source\kernel\gen_system" /I =
"..\..\source\blender\renderconverter\\" /I =
"..\..\source\blender\renderui\\" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" =
/D "_MBCS" /YX /FD /GZ /c
# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x413 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=3Dbscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=3Dlink.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib =
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib =
odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib =
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib =
odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 =
/pdbtype:sept
# ADD LINK32 odelib.lib openal_static.lib libguardedalloc.a libbsp.a =
libbmfont.a libghost.a libstring.a ws2_32.lib dxguid.lib opengl32.lib =
libjpeg.a glu32.lib user32.lib gdi32.lib vfw32.lib advapi32.lib =
ole32.lib winmm.lib libdecimation.a libblenkey.a libeay32.lib =
libiksolver.a libpng.a libz.a libmoto.a /nologo /subsystem:console =
/debug /machine:I386 /nodefaultlib:"glut32.lib" =
/nodefaultlib:"libcd.lib" /nodefaultlib:"libc.lib" =
/nodefaultlib:"libcpd.lib" /nodefaultlib:"libcp.lib" =
/nodefaultlib:"libcmt.lib" /nodefaultlib:"libcpmtd.lib" =
/nodefaultlib:"msvcprtd.lib" /out:"..\..\bin\debug\blender.exe" =
/pdbtype:sept /libpath:"..\..\..\lib\windows\ode\lib" =
/libpath:"..\..\..\lib\windows\bsp\lib\debug" =
/libpath:"..\..\..\lib\windows\moto\lib\debug" =
/libpath:"..\..\..\lib\windows\bmfont\lib\debug" =
/libpath:"..\..\..\lib\windows\ghost\lib\debug" =
/libpath:"..\..\..\lib\windows\python\frozen" =
/libpath:"..\..\..\lib\windows\guardedalloc\lib\debug" =
/libpath:"..\..\..\lib\windows\string\lib\debug" =
/libpath:"..\..\..\lib\windows\python\lib" =
/libpath:"..\..\..\lib\windows\iksolver\lib\debug" =
/libpath:"..\..\..\lib\windows\decimation\lib\debug" =
/libpath:"..\..\..\lib\windows\openal\lib" =
/libpath:"..\..\..\lib\windows\jpeg\lib" =
/libpath:"..\..\..\lib\windows\blenkey\lib\debug" =
/libpath:"..\..\..\lib\windows\openssl\lib" =
/libpath:"..\..\..\lib\windows\zlib\lib\\" =
/libpath:"..\..\..\lib\windows\png\lib\\"
# SUBTRACT LINK32 /pdb:none
# Begin Special Build Tool
SOURCE=3D"$(InputPath)"
PostBuild_Cmds=3DECHO Copying required 3rd party dlls...	XCOPY /Y =
..\..\..\lib\windows\gettext\lib\*.dll ..\..\bin\	ECHO Done
# End Special Build Tool

!ENDIF=20

# Begin Target

# Name "blender - Win32 Release"
# Name "blender - Win32 Debug"
# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File

SOURCE=3D..\..\source\creator\creator.c
# End Source File
# Begin Source File

SOURCE=3D..\..\source\icons\winblender.rc
# End Source File
# End Group
# Begin Group "Header Files"

# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"

# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File

SOURCE=3D..\..\source\icons\winblender.ico
# End Source File
# Begin Source File

SOURCE=3D..\..\source\icons\winblenderfile.ico
# End Source File
# End Group
# End Target
# End Project

------=_NextPart_000_0003_01C331E0.FE500C00--