Пример #1
0
/**
 * Apply antialiasing coverage value to alpha values.
 */
static inline void
apply_aa_coverage(SWspan *span)
{
   const GLfloat *coverage = span->array->coverage;
   GLuint i;
   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
      GLubyte (*rgba)[4] = span->array->rgba8;
      for (i = 0; i < span->end; i++) {
         const GLfloat a = rgba[i][ACOMP] * coverage[i];
         rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0);
         ASSERT(coverage[i] >= 0.0);
         ASSERT(coverage[i] <= 1.0);
      }
   }
   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
      GLushort (*rgba)[4] = span->array->rgba16;
      for (i = 0; i < span->end; i++) {
         const GLfloat a = rgba[i][ACOMP] * coverage[i];
         rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0);
      }
   }
   else {
      GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL];
      for (i = 0; i < span->end; i++) {
         rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i];
         /* clamp later */
      }
   }
}
Пример #2
0
/**
 * Apply fog to a span of RGBA pixels.
 * The fog value are either in the span->array->fog array or interpolated from
 * the fog/fogStep values.
 * They fog values are either fog coordinates (Z) or fog blend factors.
 * _PreferPixelFog should be in sync with that state!
 */
void
_swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
{
   const SWcontext *swrast = CONST_SWRAST_CONTEXT(ctx);
   GLfloat rFog, gFog, bFog;

   ASSERT(swrast->_FogEnabled);
   ASSERT(span->arrayMask & SPAN_RGBA);

   /* compute (scaled) fog color */
   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
      rFog = ctx->Fog.Color[RCOMP] * 255.0F;
      gFog = ctx->Fog.Color[GCOMP] * 255.0F;
      bFog = ctx->Fog.Color[BCOMP] * 255.0F;
   }
   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
      rFog = ctx->Fog.Color[RCOMP] * 65535.0F;
      gFog = ctx->Fog.Color[GCOMP] * 65535.0F;
      bFog = ctx->Fog.Color[BCOMP] * 65535.0F;
   }
   else {
      rFog = ctx->Fog.Color[RCOMP];
      gFog = ctx->Fog.Color[GCOMP];
      bFog = ctx->Fog.Color[BCOMP];
   }

   if (swrast->_PreferPixelFog) {
      /* The span's fog values are fog coordinates, now compute blend factors
       * and blend the fragment colors with the fog color.
       */
      switch (swrast->_FogMode) {
      case GL_LINEAR:
         {
            const GLfloat fogEnd = ctx->Fog.End;
            const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End)
               ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
               GLubyte (*rgba)[4] = span->array->rgba8;
               FOG_LOOP(GLubyte, LINEAR_FOG);
            }
            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
               GLushort (*rgba)[4] = span->array->rgba16;
               FOG_LOOP(GLushort, LINEAR_FOG);
            }
            else {
               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
               ASSERT(span->array->ChanType == GL_FLOAT);
               FOG_LOOP(GLfloat, LINEAR_FOG);
            }
         }
         break;

      case GL_EXP:
         {
            const GLfloat density = -ctx->Fog.Density;
            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
               GLubyte (*rgba)[4] = span->array->rgba8;
               FOG_LOOP(GLubyte, EXP_FOG);
            }
            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
               GLushort (*rgba)[4] = span->array->rgba16;
               FOG_LOOP(GLushort, EXP_FOG);
            }
            else {
               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
               ASSERT(span->array->ChanType == GL_FLOAT);
               FOG_LOOP(GLfloat, EXP_FOG);
            }
         }
         break;

      case GL_EXP2:
         {
            const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
            if (span->array->ChanType == GL_UNSIGNED_BYTE) {
               GLubyte (*rgba)[4] = span->array->rgba8;
               FOG_LOOP(GLubyte, EXP2_FOG);
            }
            else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
               GLushort (*rgba)[4] = span->array->rgba16;
               FOG_LOOP(GLushort, EXP2_FOG);
            }
            else {
               GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
               ASSERT(span->array->ChanType == GL_FLOAT);
               FOG_LOOP(GLfloat, EXP2_FOG);
            }
         }
         break;

      default:
         _mesa_problem(ctx, "Bad fog mode in _swrast_fog_rgba_span");
         return;
      }
   }
   else {
      /* The span's fog start/step/array values are blend factors in [0,1].
       * They were previously computed per-vertex.
       */
      if (span->array->ChanType == GL_UNSIGNED_BYTE) {
         GLubyte (*rgba)[4] = span->array->rgba8;
         FOG_LOOP(GLubyte, BLEND_FOG);
      }
      else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
         GLushort (*rgba)[4] = span->array->rgba16;
         FOG_LOOP(GLushort, BLEND_FOG);
      }
      else {
         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
         ASSERT(span->array->ChanType == GL_FLOAT);
         FOG_LOOP(GLfloat, BLEND_FOG);
      }
   }
}
void CreateHeightFieldMesh (NewtonCollision* collision, Entity* ent)
{
	int width;
	int height;
	dFloat hScale;
	dFloat vScale;
	unsigned short* elevations;
	NewtonCollisionInfoRecord collisionInfo;

	// keep the compiler happy
	memset (&collisionInfo, 0, sizeof (NewtonCollisionInfoRecord));
	NewtonCollisionGetInfo (collision, &collisionInfo);

	// get the info from the collision mesh and create a visual mesh
	width = collisionInfo.m_heightField.m_width;
	height = collisionInfo.m_heightField.m_height;
	elevations = collisionInfo.m_heightField.m_elevation;
	vScale = collisionInfo.m_heightField.m_verticalScale;
	hScale = collisionInfo.m_heightField.m_horizonalScale;

	// allocate space to store vertex data
	ent->m_vertexCount = width * height;
	ent->m_vertex = (dFloat*) malloc (3 * width * height * sizeof (dFloat));
	ent->m_normal = (dFloat*) malloc (3 * width * height * sizeof (dFloat));
	ent->m_uv = (dFloat*) malloc (2 * width * height * sizeof (dFloat));



	// scan the height field and convert every cell into two triangles
	for (int z = 0; z < height; z ++) {
		int z0;
		int z1;
		z0 = ((z - 1) < 0) ? 0 : z - 1;
		z1 = ((z + 1) > (height - 1)) ? height - 1 : z + 1 ;
		for (int x = 0; x < width; x ++) {
			int x0;
			int x1;

			x0 = ((x - 1) < 0) ? 0 : x - 1;
			x1 = ((x + 1) > (width - 1)) ? width - 1 : x + 1 ;

			dVector p0 (hScale * x0, elevations[z * width + x1] * vScale, hScale * z);
			dVector p1 (hScale * x1, elevations[z * width + x0] * vScale, hScale * z);
			dVector x10 (p1 - p0);

			dVector q0 (hScale * x, elevations[z0 * width + x] * vScale, hScale * z0);
			dVector q1 (hScale * x, elevations[z1 * width + x] * vScale, hScale * z1);
			dVector z10 (q1 - q0);

			dVector normal (z10 * x10);
			normal = normal.Scale (dSqrt (1.0f / (normal % normal)));
			dVector point (hScale * x, elevations[z * width + x] * vScale, hScale * z);

			ent->m_vertex[(z * width + x) * 3 + 0] = point.m_x;
			ent->m_vertex[(z * width + x) * 3 + 1] = point.m_y;
			ent->m_vertex[(z * width + x) * 3 + 2] = point.m_z;

			ent->m_normal[(z * width + x) * 3 + 0] = normal.m_x;
			ent->m_normal[(z * width + x) * 3 + 1] = normal.m_y;
			ent->m_normal[(z * width + x) * 3 + 2] = normal.m_z;

			ent->m_uv[(z * width + x) * 2 + 0] = x * TEXTURE_SCALE;
			ent->m_uv[(z * width + x) * 2 + 1] = z * TEXTURE_SCALE;
		}
	}

	
	// since the bitmap sample is 256 x 256, i fix into a single 16 bit index vertex array with
	ent->m_subMeshCount = 1;
	ent->m_subMeshes = (Entity::SubMesh*) malloc (sizeof (Entity::SubMesh));

	// allocate space to the index list
	ent->m_subMeshes[0].m_textureHandle = LoadTexture ("grassAndDirt.tga");
	ent->m_subMeshes[0].m_indexCount = (width - 1) * (height - 1) * 6;
	ent->m_subMeshes[0].m_indexArray = (unsigned short*) malloc (ent->m_subMeshes[0].m_indexCount * sizeof (unsigned short));

	// now following the grid pattern and create and index list
	int index;
	int vertexIndex;

	index = 0;
	vertexIndex = 0;
	for (int z = 0; z < height - 1; z ++) {
		vertexIndex = z * width;
		for (int x = 0; x < width - 1; x ++) {

			ent->m_subMeshes[0].m_indexArray[index + 0] = GLushort (vertexIndex);
			ent->m_subMeshes[0].m_indexArray[index + 1] = GLushort (vertexIndex + width);
			ent->m_subMeshes[0].m_indexArray[index + 2] = GLushort (vertexIndex + 1);
			index += 3;

			ent->m_subMeshes[0].m_indexArray[index + 0] = GLushort (vertexIndex + 1);
			ent->m_subMeshes[0].m_indexArray[index + 1] = GLushort (vertexIndex + width);
			ent->m_subMeshes[0].m_indexArray[index + 2] = GLushort (vertexIndex + width + 1);
			index += 3;
			vertexIndex ++;
		}
	}

	// Optimize the mesh for hardware rendering if possible
	ent->OptimizeMesh();

/*
	dVector boxP0; 
	dVector boxP1; 
	// get the position of the aabb of this geometry
	dMatrix matrix (ent->m_curRotation, ent->m_curPosition);
	NewtonCollisionCalculateAABB (collision, &matrix[0][0], &boxP0.m_x, &boxP1.m_x); 

	// place the origin of the visual mesh at the center of the height field
	matrix.m_posit = (boxP0 + boxP1).Scale (-0.5f);
	matrix.m_posit.m_w = 1.0f;
	ent->m_curPosition = matrix.m_posit;
	ent->m_prevPosition = matrix.m_posit;


	// create the level rigid body
	body = NewtonCreateBody(world, collision);

	// release the collision tree (this way the application does not have to do book keeping of Newton objects
	NewtonReleaseCollision (world, collision);


	// save the pointer to the graphic object with the body.
	NewtonBodySetUserData (body, ent);

	// set the global position of this body
	NewtonBodySetMatrix (body, &matrix[0][0]); 


	// set the destructor for this object
//	NewtonBodySetDestructorCallback (body, Destructor);

	// get the position of the aabb of this geometry
	NewtonCollisionCalculateAABB (collision, &matrix[0][0], &boxP0.m_x, &boxP1.m_x); 

	// add some extra padding the world size
	boxP0.m_x -=  10.0f;
	boxP0.m_y -=  10.0f;
	boxP0.m_z -=  10.0f;
	boxP1.m_x +=  10.0f;
	boxP1.m_y += 400.0f;
	boxP1.m_z +=  10.0f;

	// set the world size
	NewtonSetWorldSize (world, &boxP0.m_x, &boxP1.m_x); 
	return body;
*/
}
Пример #4
0
/**
 * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16)
 * color array.
 */
static inline void
interpolate_int_colors(struct gl_context *ctx, SWspan *span)
{
#if CHAN_BITS != 32
   const GLuint n = span->end;
   GLuint i;

   ASSERT(!(span->arrayMask & SPAN_RGBA));
#endif

   switch (span->array->ChanType) {
#if CHAN_BITS != 32
   case GL_UNSIGNED_BYTE:
      {
         GLubyte (*rgba)[4] = span->array->rgba8;
         if (span->interpMask & SPAN_FLAT) {
            GLubyte color[4];
            color[RCOMP] = FixedToInt(span->red);
            color[GCOMP] = FixedToInt(span->green);
            color[BCOMP] = FixedToInt(span->blue);
            color[ACOMP] = FixedToInt(span->alpha);
            for (i = 0; i < n; i++) {
               COPY_4UBV(rgba[i], color);
            }
         }
         else {
            GLfixed r = span->red;
            GLfixed g = span->green;
            GLfixed b = span->blue;
            GLfixed a = span->alpha;
            GLint dr = span->redStep;
            GLint dg = span->greenStep;
            GLint db = span->blueStep;
            GLint da = span->alphaStep;
            for (i = 0; i < n; i++) {
               rgba[i][RCOMP] = FixedToChan(r);
               rgba[i][GCOMP] = FixedToChan(g);
               rgba[i][BCOMP] = FixedToChan(b);
               rgba[i][ACOMP] = FixedToChan(a);
               r += dr;
               g += dg;
               b += db;
               a += da;
            }
         }
      }
      break;
   case GL_UNSIGNED_SHORT:
      {
         GLushort (*rgba)[4] = span->array->rgba16;
         if (span->interpMask & SPAN_FLAT) {
            GLushort color[4];
            color[RCOMP] = FixedToInt(span->red);
            color[GCOMP] = FixedToInt(span->green);
            color[BCOMP] = FixedToInt(span->blue);
            color[ACOMP] = FixedToInt(span->alpha);
            for (i = 0; i < n; i++) {
               COPY_4V(rgba[i], color);
            }
         }
         else {
            GLushort (*rgba)[4] = span->array->rgba16;
            GLfixed r, g, b, a;
            GLint dr, dg, db, da;
            r = span->red;
            g = span->green;
            b = span->blue;
            a = span->alpha;
            dr = span->redStep;
            dg = span->greenStep;
            db = span->blueStep;
            da = span->alphaStep;
            for (i = 0; i < n; i++) {
               rgba[i][RCOMP] = FixedToChan(r);
               rgba[i][GCOMP] = FixedToChan(g);
               rgba[i][BCOMP] = FixedToChan(b);
               rgba[i][ACOMP] = FixedToChan(a);
               r += dr;
               g += dg;
               b += db;
               a += da;
            }
         }
      }
      break;
#endif
   case GL_FLOAT:
      interpolate_active_attribs(ctx, span, FRAG_BIT_COL);
      break;
   default:
      _mesa_problem(ctx, "bad datatype 0x%x in interpolate_int_colors",
                    span->array->ChanType);
   }
   span->arrayMask |= SPAN_RGBA;
}
Пример #5
0
/**
 * Apply the color mask to a span of rgba values.
 */
void
_swrast_mask_rgba_span(struct gl_context *ctx, struct gl_renderbuffer *rb,
                       SWspan *span)
{
   const GLuint n = span->end;
   void *rbPixels;

   ASSERT(n < MAX_WIDTH);
   ASSERT(span->arrayMask & SPAN_RGBA);

   rbPixels = _swrast_get_dest_rgba(ctx, rb, span);

   /*
    * Do component masking.
    * Note that we're not using span->array->mask[] here.  We could...
    */
   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
      /* treat 4xGLubyte as 1xGLuint */
      const GLuint srcMask = *((GLuint *) ctx->Color.ColorMask);
      const GLuint dstMask = ~srcMask;
      const GLuint *dst = (const GLuint *) rbPixels;
      GLuint *src = (GLuint *) span->array->rgba8;
      GLuint i;
      for (i = 0; i < n; i++) {
         src[i] = (src[i] & srcMask) | (dst[i] & dstMask);
      }
   }
   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
      /* 2-byte components */
      /* XXX try to use 64-bit arithmetic someday */
      const GLushort rMask = ctx->Color.ColorMask[RCOMP] ? 0xffff : 0x0;
      const GLushort gMask = ctx->Color.ColorMask[GCOMP] ? 0xffff : 0x0;
      const GLushort bMask = ctx->Color.ColorMask[BCOMP] ? 0xffff : 0x0;
      const GLushort aMask = ctx->Color.ColorMask[ACOMP] ? 0xffff : 0x0;
      const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels;
      GLushort (*src)[4] = span->array->rgba16;
      GLuint i;
      for (i = 0; i < n; i++) {
         src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask);
         src[i][GCOMP] = (src[i][GCOMP] & gMask) | (dst[i][GCOMP] & ~gMask);
         src[i][BCOMP] = (src[i][BCOMP] & bMask) | (dst[i][BCOMP] & ~bMask);
         src[i][ACOMP] = (src[i][ACOMP] & aMask) | (dst[i][ACOMP] & ~aMask);
      }
   }
   else {
      /* 4-byte components */
      const GLuint rMask = ctx->Color.ColorMask[RCOMP] ? ~0x0 : 0x0;
      const GLuint gMask = ctx->Color.ColorMask[GCOMP] ? ~0x0 : 0x0;
      const GLuint bMask = ctx->Color.ColorMask[BCOMP] ? ~0x0 : 0x0;
      const GLuint aMask = ctx->Color.ColorMask[ACOMP] ? ~0x0 : 0x0;
      const GLuint (*dst)[4] = (const GLuint (*)[4]) rbPixels;
      GLuint (*src)[4] = (GLuint (*)[4]) span->array->attribs[FRAG_ATTRIB_COL];
      GLuint i;
      for (i = 0; i < n; i++) {
         src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask);
         src[i][GCOMP] = (src[i][GCOMP] & gMask) | (dst[i][GCOMP] & ~gMask);
         src[i][BCOMP] = (src[i][BCOMP] & bMask) | (dst[i][BCOMP] & ~bMask);
         src[i][ACOMP] = (src[i][ACOMP] & aMask) | (dst[i][ACOMP] & ~aMask);
      }
   }
}
Пример #6
0
void xglrenderer::ev_sphere(xobjevent *pev) 
{
	xobject *pNotifier;
	int evid;
	float detail;
	if(!((xpackev*)pev)->unpack("odf",&pNotifier,&evid,&detail)) {
		wyc_error("xglrenderer::sphere: bad args");
		return;
	}

	unsigned batchid=strhash("sphere");
	xvertex_batch *pbatch=(xvertex_batch*)m_groups[GROUP_BATCH]->request(batchid);
	if(pbatch==0) {
		// a quarter of circle have 4~16 points
		unsigned quarter=4+unsigned(detail*12); 
		unsigned circle=quarter*4;
		float step=float(XMATH_HPI/quarter);
		float rad=step;
		// pre-compute the sin & cos
		float *sina=new float[quarter], *cosa=new float[quarter];
		sina[0]=0, cosa[0]=1;
		for(unsigned i=1; i<quarter; ++i) {
			sina[i]=sin(rad);
			cosa[i]=cos(rad);
			rad+=step;
		}
		// fill vertex positions
		unsigned vertexCount=(2*quarter-1)*quarter*4+2;
		xvec3f_t *buffer=new xvec3f_t[vertexCount];
		xvec3f_t *part1=buffer, *part2, *part3, *part4;
		// top half of sphere
		part1->set(0,1,0);
		part1+=1;
		for(int i=quarter-1; i>=0; --i) {
			float y=sina[i], len=cosa[i];
			part2=part1+quarter;
			part3=part2+quarter;
			part4=part3+quarter;
			part1->set(len,y,0);
			part2->set(0,y,len);
			part3->set(-len,y,0);
			part4->set(0,y,-len);
			part2+=quarter;
			part4+=quarter;
			for(unsigned j=1; j<quarter; ++j) {
				float x=len*cosa[j], z=len*sina[j];
				++part1;
				part1->set(x,y,z);
				--part2;
				part2->set(-x,y,z);
				++part3;
				part3->set(-x,y,-z);
				--part4;
				part4->set(x,y,-z);
			}
			part1=part4+quarter-1;
		}
		// bottom half of sphere
		part1=buffer+1;
		part2=buffer+vertexCount-1;
		part2->set(0,-1,0);
		for(unsigned i=quarter-1; i>0; --i) {
			part2-=circle;
			for(unsigned j=0; j<circle; ++j, ++part1) 
				part2[j].set(part1->x,-part1->y,part1->z);
		}
		assert(unsigned(part2-part1)==circle);
		// vertex buffer
		GLuint vertbuffs[2];
		glGenBuffers(2,vertbuffs);
		glBindBuffer(GL_ARRAY_BUFFER,vertbuffs[0]);
		glBufferData(GL_ARRAY_BUFFER,vertexCount*sizeof(xvec3f_t),buffer,GL_STATIC_DRAW);
		delete [] buffer;
		delete [] sina;
		delete [] cosa;
		// index buffer
		unsigned indexCount=48*quarter*quarter-24*quarter;
		assert(indexCount<65536);
		GLushort *index=new GLushort[indexCount];
		GLushort *iter=index;
		GLushort vidx=1;
		while(vidx<circle) {
			*iter++=0;
			*iter++=vidx+1;
			*iter++=vidx;
			++vidx;
		}
		*iter++=0;
		*iter++=1;
		*iter++=vidx;
		vidx=1;
		for(unsigned i=2*quarter-2; i>0; --i) {
			unsigned end=vidx+circle-1;
			while(vidx<end) {
				iter[0]=vidx;
				iter[1]=vidx+1;
				iter[2]=GLushort(vidx+circle);
				iter[3]=iter[2];
				iter[4]=iter[1];
				iter[5]=GLushort(iter[1]+circle);
				iter+=6;
				++vidx;
			}
			iter[0]=vidx;
			iter[1]=GLushort(vidx+1-circle);
			iter[2]=GLushort(vidx+circle);
			iter[3]=iter[2];
			iter[4]=iter[1];
			iter[5]=vidx+1;
			iter+=6;
			++vidx;
		}
		GLushort last=GLushort(vertexCount-1);
		for(unsigned i=1; i<circle; ++i) {
			*iter++=last;
			*iter++=vidx;
			*iter++=vidx+1;
			++vidx;
		}
		*iter++=last;
		*iter++=vidx;
		*iter++=GLushort(vidx+1-circle);
		assert(unsigned(iter-index)==indexCount);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vertbuffs[1]);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER,indexCount*sizeof(GLushort),index,GL_STATIC_DRAW);
		delete [] index;
		
		xvertex_buffer *pvb;
		if(GLEW_ARB_vertex_array_object) 
		{
			GLuint vao;
			glGenVertexArrays(1,&vao);
			glBindVertexArray(vao);

			glBindBuffer(GL_ARRAY_BUFFER,vertbuffs[0]);
			glVertexAttribPointer(USAGE_POSITION,3,GL_FLOAT,GL_FALSE,0,(void*)0);
			glEnableVertexAttribArray(USAGE_POSITION);

			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vertbuffs[1]);

			glBindVertexArray(0);

			pbatch=(xvertex_batch*)m_groups[GROUP_BATCH]->create(batchid,(void*)vao);
			pvb=wycnew xvertex_buffer;
			pvb->create(vertbuffs[0]);
			pbatch->add_buffer(pvb);
		}
		else {
			pbatch=(xvertex_batch*)m_groups[GROUP_BATCH]->create(batchid,0);
			pvb=wycnew xvertex_buffer;
			pvb->create(vertbuffs[0]);
			pbatch->add_buffer(pvb,USAGE_POSITION,3,GL_FLOAT,false,0,0);
		}
		pvb=wycnew xvertex_buffer;
		pvb->create(vertbuffs[1]);
		pbatch->set_index(pvb,GL_UNSIGNED_SHORT);
		pbatch->set_mode(GL_TRIANGLES,indexCount,0);
	} // if (pbatch==0)

	if(pNotifier) {
		pev=xpackev::pack("o",pbatch);
		pNotifier->on_event(evid,pev);
	}
}
Пример #7
0
/**
 * Apply fog to a span of RGBA pixels.
 * The fog value are either in the span->array->fog array or interpolated from
 * the fog/fogStep values.
 * They fog values are either fog coordinates (Z) or fog blend factors.
 * _PreferPixelFog should be in sync with that state!
 */
void
_swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span )
{
   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
   GLfloat rFog, gFog, bFog;
   const GLuint haveW = (span->interpMask & SPAN_W);

   ASSERT(swrast->_FogEnabled);
   ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
   ASSERT(span->arrayMask & SPAN_RGBA);

   if (span->array->ChanType == GL_UNSIGNED_BYTE) {
      rFog = ctx->Fog.Color[RCOMP] * 255.0;
      gFog = ctx->Fog.Color[GCOMP] * 255.0;
      bFog = ctx->Fog.Color[BCOMP] * 255.0;
   }
   else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
      rFog = ctx->Fog.Color[RCOMP] * 65535.0;
      gFog = ctx->Fog.Color[GCOMP] * 65535.0;
      bFog = ctx->Fog.Color[BCOMP] * 65535.0;
   }
   else {
      rFog = ctx->Fog.Color[RCOMP];
      gFog = ctx->Fog.Color[GCOMP];
      bFog = ctx->Fog.Color[BCOMP];
   }


   /* NOTE: if haveW is true, that means the fog start/step values are
    * perspective-corrected and we have to divide each fog coord by W.
    */

   /* we need to compute fog blend factors */
   if (swrast->_PreferPixelFog) {
      /* The span's fog values are fog coordinates, now compute blend factors
       * and blend the fragment colors with the fog color.
       */
      const GLfloat fogEnd = ctx->Fog.End;
      const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End)
         ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start);
      const GLfloat density = -ctx->Fog.Density;
      const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;

      switch (swrast->_FogMode) {
      case GL_LINEAR:
#define COMPUTE_F  f = (fogEnd - FABSF(fogCoord) / w) * fogScale;
         if (span->array->ChanType == GL_UNSIGNED_BYTE) {
            GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
            FOG_LOOP(GLubyte, COMPUTE_F);
         }
         else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
            FOG_LOOP(GLushort, COMPUTE_F);
         }
         else {
            GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
            ASSERT(span->array->ChanType == GL_FLOAT);
            FOG_LOOP(GLfloat, COMPUTE_F);
         }
#undef COMPUTE_F
         break;

      case GL_EXP:
#define COMPUTE_F  f = EXPF(density * FABSF(fogCoord) / w);
         if (span->array->ChanType == GL_UNSIGNED_BYTE) {
            GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
            FOG_LOOP(GLubyte, COMPUTE_F);
         }
         else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
            FOG_LOOP(GLushort, COMPUTE_F);
         }
         else {
            GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
            ASSERT(span->array->ChanType == GL_FLOAT);
            FOG_LOOP(GLfloat, COMPUTE_F);
         }
#undef COMPUTE_F
         break;

      case GL_EXP2:
#define COMPUTE_F  const GLfloat coord = fogCoord / w; \
                   GLfloat tmp = negDensitySquared * coord * coord; \
                   if (tmp < FLT_MIN_10_EXP) \
                      tmp = FLT_MIN_10_EXP; \
                   f = EXPF(tmp);
         if (span->array->ChanType == GL_UNSIGNED_BYTE) {
            GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
            FOG_LOOP(GLubyte, COMPUTE_F);
         }
         else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
            GLushort (*rgba)[4] = span->array->color.sz2.rgba;
            FOG_LOOP(GLushort, COMPUTE_F);
         }
         else {
            GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
            ASSERT(span->array->ChanType == GL_FLOAT);
            FOG_LOOP(GLfloat, COMPUTE_F);
         }
#undef COMPUTE_F
         break;

      default:
         _mesa_problem(ctx, "Bad fog mode in _swrast_fog_rgba_span");
         return;
      }
   }
   else if (span->arrayMask & SPAN_FOG) {
      /* The span's fog array values are blend factors.
       * They were previously computed per-vertex.
       */
      GLuint i;
      if (span->array->ChanType == GL_UNSIGNED_BYTE) {
         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
         for (i = 0; i < span->end; i++) {
            const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
            const GLfloat oneMinusF = 1.0F - f;
            rgba[i][RCOMP] = (GLubyte) (f * rgba[i][RCOMP] + oneMinusF * rFog);
            rgba[i][GCOMP] = (GLubyte) (f * rgba[i][GCOMP] + oneMinusF * gFog);
            rgba[i][BCOMP] = (GLubyte) (f * rgba[i][BCOMP] + oneMinusF * bFog);
         }
      }
      else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
         for (i = 0; i < span->end; i++) {
            const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
            const GLfloat oneMinusF = 1.0F - f;
            rgba[i][RCOMP] = (GLushort) (f * rgba[i][RCOMP] + oneMinusF * rFog);
            rgba[i][GCOMP] = (GLushort) (f * rgba[i][GCOMP] + oneMinusF * gFog);
            rgba[i][BCOMP] = (GLushort) (f * rgba[i][BCOMP] + oneMinusF * bFog);
         }
      }
      else {
         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
         ASSERT(span->array->ChanType == GL_FLOAT);
         for (i = 0; i < span->end; i++) {
            const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0];
            const GLfloat oneMinusF = 1.0F - f;
            rgba[i][RCOMP] = f * rgba[i][RCOMP] + oneMinusF * rFog;
            rgba[i][GCOMP] = f * rgba[i][GCOMP] + oneMinusF * gFog;
            rgba[i][BCOMP] = f * rgba[i][BCOMP] + oneMinusF * bFog;
         }
      }

   }
   else {
      /* The span's fog start/step values are blend factors.
       * They were previously computed per-vertex.
       */
#define COMPUTE_F f = fogCoord / w;
      if (span->array->ChanType == GL_UNSIGNED_BYTE) {
         GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
         FOG_LOOP(GLubyte, COMPUTE_F);
      }
      else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
         GLushort (*rgba)[4] = span->array->color.sz2.rgba;
         FOG_LOOP(GLushort, COMPUTE_F);
      }
      else {
         GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0];
         ASSERT(span->array->ChanType == GL_FLOAT);
         FOG_LOOP(GLfloat, COMPUTE_F);
      }
#undef COMPUTE_F
   }
}