e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/* Copyright (c) 2001, Stanford University
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * All rights reserved
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * See the file LICENSE.txt for information on redistributing this software.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "server_dispatch.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "server.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_error.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "state/cr_statetypes.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic const CRmatrix identity_matrix = {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync 1.0, 0.0, 0.0, 0.0,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync 0.0, 1.0, 0.0, 0.0,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync 0.0, 0.0, 1.0, 0.0,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync 0.0, 0.0, 0.0, 1.0
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync};
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Clip the rectangle q against the given image window.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrServerViewportClipToWindow( const CRrecti *imagewindow, CRrecti *q)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (q->x1 < imagewindow->x1) q->x1 = imagewindow->x1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (q->x1 > imagewindow->x2) q->x1 = imagewindow->x2;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (q->x2 > imagewindow->x2) q->x2 = imagewindow->x2;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (q->x2 < imagewindow->x1) q->x2 = imagewindow->x1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (q->y1 < imagewindow->y1) q->y1 = imagewindow->y1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (q->y1 > imagewindow->y2) q->y1 = imagewindow->y2;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (q->y2 > imagewindow->y2) q->y2 = imagewindow->y2;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (q->y2 < imagewindow->y1) q->y2 = imagewindow->y1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Translate the rectangle q from the image window space to the outputwindow
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * space.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrServerConvertToOutput( const CRrecti *imagewindow,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const CRrecti *outputwindow,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRrecti *q )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q->x1 = q->x1 - imagewindow->x1 + outputwindow->x1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q->x2 = q->x2 - imagewindow->x2 + outputwindow->x2;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q->y1 = q->y1 - imagewindow->y1 + outputwindow->y1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q->y2 = q->y2 - imagewindow->y2 + outputwindow->y2;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Compute clipped image window, scissor, viewport and base projection
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * info for each tile in the mural.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Need to call this when either the viewport or mural is changed.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrServerComputeViewportBounds(const CRViewportState *v, CRMuralInfo *mural)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
81b3101ea5e60964f67c97185bbd43dbf75c5ab5vboxsync#if 0
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync static GLuint serialNo = 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for (i = 0; i < mural->numExtents; i++) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRExtent *extent = &mural->extents[i];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRrecti q;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* If the scissor is disabled set it to the whole output.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ** We might as well use the actual scissorTest rather than
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ** scissorValid - it never gets reset anyway.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!v->scissorTest)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->scissorBox = extent->outputwindow;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q.x1 = v->scissorX;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q.x2 = v->scissorX + v->scissorW;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q.y1 = v->scissorY;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q.y2 = v->scissorY + v->scissorH;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crServerViewportClipToWindow(&(extent->imagewindow), &q);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crServerConvertToOutput(&(extent->imagewindow),
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync &(extent->outputwindow), &q);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->scissorBox = q;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* if the viewport is not valid,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ** set it to the entire output.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!v->viewportValid)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->clippedImagewindow = extent->imagewindow;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->viewport = extent->outputwindow;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q.x1 = v->viewportX;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q.x2 = v->viewportX + v->viewportW;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q.y1 = v->viewportY;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync q.y2 = v->viewportY + v->viewportH;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* This is where the viewport gets clamped to the max size. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crServerViewportClipToWindow(&(extent->imagewindow), &q);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->clippedImagewindow = q;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crServerConvertToOutput(&(extent->imagewindow),
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync &(extent->outputwindow), &q);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->viewport = q;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ** Now, compute the base projection.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (extent->clippedImagewindow.x1 == extent->clippedImagewindow.x2 ||
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->clippedImagewindow.y1 == extent->clippedImagewindow.y2) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* zero-area extent, use identity matrix (doesn't really matter) */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->baseProjection = identity_matrix;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const int vpx = v->viewportX;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const int vpy = v->viewportY;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const int vpw = v->viewportW;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const int vph = v->viewportH;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLfloat xscale, yscale;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync GLfloat xtrans, ytrans;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRrectf p;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * We need to take account of the current viewport parameters,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * and they are passed to this function as x, y, w, h.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * In the default case (from main.c) we pass the the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * full muralsize of 0, 0, width, height
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p.x1 = (GLfloat) (extent->clippedImagewindow.x1 - vpx) / vpw;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p.y1 = (GLfloat) (extent->clippedImagewindow.y1 - vpy) / vph;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p.x2 = (GLfloat) (extent->clippedImagewindow.x2 - vpx) / vpw;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p.y2 = (GLfloat) (extent->clippedImagewindow.y2 - vpy) / vph;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* XXX not sure this clamping is really need anymore
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (p.x1 < 0.0) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p.x1 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (p.x2 > 1.0) p.x2 = 1.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (p.y1 < 0.0) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p.y1 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (p.y2 > 1.0) p.y2 = 1.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Rescale [0,1] -> [-1,1] */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p.x1 = p.x1 * 2.0f - 1.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p.x2 = p.x2 * 2.0f - 1.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p.y1 = p.y1 * 2.0f - 1.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p.y2 = p.y2 * 2.0f - 1.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync xscale = 2.0f / (p.x2 - p.x1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync yscale = 2.0f / (p.y2 - p.y1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync xtrans = -(p.x2 + p.x1) / 2.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ytrans = -(p.y2 + p.y1) / 2.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(xscale == xscale); /* NaN test */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(yscale == yscale);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->baseProjection = identity_matrix;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->baseProjection.m00 = xscale;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->baseProjection.m11 = yscale;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->baseProjection.m30 = xtrans * xscale;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->baseProjection.m31 = ytrans * yscale;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->serialNo = serialNo++;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync mural->viewportValidated = GL_TRUE;
81b3101ea5e60964f67c97185bbd43dbf75c5ab5vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Issue the glScissor, glViewport and projection matrix needed for
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * rendering the tile specified by extNum. We computed the scissor,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * viewport and projection parameters above in crServerComputeViewportBounds.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrServerSetOutputBounds( const CRMuralInfo *mural, int extNum )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
81b3101ea5e60964f67c97185bbd43dbf75c5ab5vboxsync#if 0
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const CRExtent *extent = mural->extents + extNum;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT(mural->viewportValidated);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Serial Number info:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Everytime we compute new scissor, viewport, projection matrix info for
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * a tile, we give that tile a new serial number.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * When we're about to render into a tile, we only update the scissor,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * viewport and projection matrix if the tile's serial number doesn't match
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * the current serial number. This avoids a _LOT_ of redundant calls to
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * those three functions.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (extent->serialNo != cr_server.currentSerialNo) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.Scissor(extent->scissorBox.x1,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->scissorBox.y1,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->scissorBox.x2 - extent->scissorBox.x1,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->scissorBox.y2 - extent->scissorBox.y1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.Viewport(extent->viewport.x1,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->viewport.y1,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->viewport.x2 - extent->viewport.x1,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync extent->viewport.y2 - extent->viewport.y1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crServerApplyBaseProjection(&(extent->baseProjection));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.currentSerialNo = extent->serialNo;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
81b3101ea5e60964f67c97185bbd43dbf75c5ab5vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Pre-multiply the current projection matrix with the current client's
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * base projection. I.e. P' = b * P. Note that OpenGL's glMultMatrix
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * POST-multiplies.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrServerApplyBaseProjection(const CRmatrix *baseProj)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const CRmatrix *projMatrix;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (cr_server.projectionOverride) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int eye = crServerGetCurrentEye();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync projMatrix = &cr_server.projectionMatrix[eye];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
f53ba2efceac1847585b2052ee98569305e9802dvboxsync projMatrix = cr_server.curClient->currentCtxInfo->pContext->transform.projectionStack.top;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.PushAttrib( GL_TRANSFORM_BIT );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.MatrixMode( GL_PROJECTION );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.LoadMatrixf( (const GLfloat *) baseProj );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.MultMatrixf( cr_server.alignment_matrix );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.MultMatrixf( (const GLfloat *) projMatrix );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.PopAttrib();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrServerApplyViewMatrix(const CRmatrix *view)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
f53ba2efceac1847585b2052ee98569305e9802dvboxsync const CRmatrix *modelview = cr_server.curClient->currentCtxInfo->pContext->transform.modelViewStack.top;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.PushAttrib( GL_TRANSFORM_BIT );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.MatrixMode( GL_MODELVIEW );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.LoadMatrixf( (const GLfloat *) view );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.MultMatrixf( (const GLfloat *) modelview );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.PopAttrib();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Called via unpacker module.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Note: when there's a tilesort SPU upstream, the viewport dimensions
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * will typically match the mural size. That is, the viewport dimensions
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * probably won't be the same values that the application issues.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid SERVER_DISPATCH_APIENTRY crServerDispatchViewport( GLint x, GLint y, GLsizei width, GLsizei height )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRMuralInfo *mural = cr_server.curClient->currentMural;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRContext *ctx = crStateGetCurrent();
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (ctx->viewport.viewportX != x ||
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ctx->viewport.viewportY != y ||
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ctx->viewport.viewportW != width ||
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ctx->viewport.viewportH != height) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Note -- If there are tiles, this will be overridden in the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * process of decoding the BoundsInfo packet, so no worries. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crStateViewport( x, y, width, height );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* always dispatch to be safe */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_server.head_spu->dispatch_table.Viewport( x, y, width, height );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}