示例#1
0
GLUSfloat GLUSAPIENTRY glusOrientedBoxDistancePoint4f(const GLUSfloat center[4], const GLUSfloat halfExtend[3], const GLUSfloat orientation[3], const GLUSfloat point[4])
{
	GLUSfloat matrix[9];
	GLUSfloat vector[3];

	GLUSfloat insideDistance;
	GLUSfloat outsideDistance;

	glusPoint4SubtractPoint4f(vector, point, center);

	glusMatrix3x3Identityf(matrix);
	glusMatrix3x3RotateRzRyRxf(matrix, -orientation[2], -orientation[1], -orientation[0]);
	glusMatrix3x3MultiplyVector3f(vector, matrix, vector);

	vector[0] = fabsf(vector[0]) - halfExtend[0];
	vector[1] = fabsf(vector[1]) - halfExtend[1];
	vector[2] = fabsf(vector[2]) - halfExtend[2];

	insideDistance = glusMathMinf(glusMathMaxf(vector[0], glusMathMaxf(vector[1], vector[2])), 0.0f);

	vector[0] = glusMathMaxf(vector[0], 0.0f);
	vector[1] = glusMathMaxf(vector[1], 0.0f);
	vector[2] = glusMathMaxf(vector[2], 0.0f);

	outsideDistance = glusVector3Lengthf(vector);

	return insideDistance + outsideDistance;
}
示例#2
0
GLUSboolean GLUSAPIENTRY glusCalculateTangentSpacef(GLUSshape* shape)
{
    GLUSuint i;

    if (!shape || !shape->vertices || !shape->texCoords || shape->mode != GL_TRIANGLES)
    {
        return GLUS_FALSE;
    }

    // Allocate memory if needed
    if (!shape->tangents)
    {
    	shape->tangents = (GLUSfloat*) malloc(3 * shape->numberVertices * sizeof(GLUSfloat));

        if (!shape->tangents)
        {
            return GLUS_FALSE;
        }
    }

    if (!shape->bitangents)
    {
    	shape->bitangents = (GLUSfloat*) malloc(3 * shape->numberVertices * sizeof(GLUSfloat));

        if (!shape->bitangents)
        {
            return GLUS_FALSE;
        }
    }

    // Reset all tangents to 0.0f
    for (i = 0; i < shape->numberVertices; i++)
    {
    	shape->tangents[i * 3] = 0.0f;
    	shape->tangents[i * 3 + 1] = 0.0f;
    	shape->tangents[i * 3 + 2] = 0.0f;
    }

    if (shape->numberIndices > 0)
    {
    	float s1, t1, s2, t2;
    	float Q1[4];
    	float Q2[4];
    	float tangent[3];
    	float scalar;

    	for (i = 0; i < shape->numberIndices; i += 3)
    	{
    		s1 = shape->texCoords[2*shape->indices[i+1]] - shape->texCoords[2*shape->indices[i]];
    		t1 = shape->texCoords[2*shape->indices[i+1]+1] - shape->texCoords[2*shape->indices[i]+1];
    		s2 = shape->texCoords[2*shape->indices[i+2]] - shape->texCoords[2*shape->indices[i]];
    		t2 = shape->texCoords[2*shape->indices[i+2]+1] - shape->texCoords[2*shape->indices[i]+1];

    		scalar = 1.0f / (s1*t2-s2*t1);

    		glusPoint4SubtractPoint4f(Q1, &shape->vertices[4*shape->indices[i+1]], &shape->vertices[4*shape->indices[i]]);
    		Q1[3] = 1.0f;
    		glusPoint4SubtractPoint4f(Q2, &shape->vertices[4*shape->indices[i+2]], &shape->vertices[4*shape->indices[i]]);
    		Q2[3] = 1.0f;

    		tangent[0] = scalar * (t2 * Q1[0] - t1 * Q2[0]);
    		tangent[1] = scalar * (t2 * Q1[1] - t1 * Q2[1]);
    		tangent[2] = scalar * (t2 * Q1[2] - t1 * Q2[2]);

    		glusVector3Normalizef(tangent);

        	shape->tangents[3 * shape->indices[i]] += tangent[0];
        	shape->tangents[3 * shape->indices[i] + 1] += tangent[1];
        	shape->tangents[3 * shape->indices[i] + 2] += tangent[2];

        	shape->tangents[3 * shape->indices[i+1]] += tangent[0];
        	shape->tangents[3 * shape->indices[i+1] + 1] += tangent[1];
        	shape->tangents[3 * shape->indices[i+1] + 2] += tangent[2];

        	shape->tangents[3 * shape->indices[i+2]] += tangent[0];
        	shape->tangents[3 * shape->indices[i+2] + 1] += tangent[1];
        	shape->tangents[3 * shape->indices[i+2] + 2] += tangent[2];
    	}
    }
    else
    {
    	float s1, t1, s2, t2;
    	float Q1[4];
    	float Q2[4];
    	float tangent[3];
    	float scalar;

    	for (i = 0; i < shape->numberVertices; i += 3)
    	{
    		s1 = shape->texCoords[2*(i+1)] - shape->texCoords[2*i];
    		t1 = shape->texCoords[2*(i+1)+1] - shape->texCoords[2*i+1];
    		s2 = shape->texCoords[2*(i+2)] - shape->texCoords[2*i];
    		t2 = shape->texCoords[2*(i+2)+1] - shape->texCoords[2*i+1];

    		scalar = 1.0f / (s1*t2-s2*t1);

    		glusPoint4SubtractPoint4f(Q1, &shape->vertices[4*(i+1)], &shape->vertices[4*i]);
    		Q1[3] = 1.0f;
    		glusPoint4SubtractPoint4f(Q2, &shape->vertices[4*(i+2)], &shape->vertices[4*i]);
    		Q2[3] = 1.0f;

    		tangent[0] = scalar * (t2 * Q1[0] - t1 * Q2[0]);
    		tangent[1] = scalar * (t2 * Q1[1] - t1 * Q2[1]);
    		tangent[2] = scalar * (t2 * Q1[2] - t1 * Q2[2]);

    		glusVector3Normalizef(tangent);

        	shape->tangents[3 * i] += tangent[0];
        	shape->tangents[3 * i + 1] += tangent[1];
        	shape->tangents[3 * i + 2] += tangent[2];

        	shape->tangents[3 * (i+1)] += tangent[0];
        	shape->tangents[3 * (i+1) + 1] += tangent[1];
        	shape->tangents[3 * (i+1) + 2] += tangent[2];

        	shape->tangents[3 * (i+2)] += tangent[0];
        	shape->tangents[3 * (i+2) + 1] += tangent[1];
        	shape->tangents[3 * (i+2) + 2] += tangent[2];
    	}
    }

    // Normalize, as several triangles have added a vector
    for (i = 0; i < shape->numberVertices; i++)
    {
		glusVector3Normalizef(&(shape->tangents[i * 3]));
    }

    // Calculate bitangents out of tangents and normals
    for (i = 0; i < shape->numberVertices; i++)
    {
        glusVector3Crossf(&(shape->bitangents[i * 3]), &(shape->normals[i * 3]), &(shape->tangents[i * 3]));
    }

    return GLUS_TRUE;
}
示例#3
0
文件: main.c 项目: AJ92/OpenGL
static GLvoid march(GLfloat pixelColor[4], const GLfloat rayPosition[4], const GLfloat rayDirection[3], const GLint depth)
{
	GLint i, k, m, o;

	Primitive* primitiveNear = 0;

	GLfloat marchPosition[4];
	GLfloat marchDirection[3];

	GLfloat hitPosition[4];
	GLfloat hitDirection[3];

	GLfloat eyeDirection[3];

	GLfloat t = 0.0f;

	//

	pixelColor[0] = 0.0f;
	pixelColor[1] = 0.0f;
	pixelColor[2] = 0.0f;
	pixelColor[3] = 1.0f;

	//

	for (i = 0; i < MAX_STEPS; i++)
	{
		GLfloat distance = INFINITY;
		GLfloat currentDistance;
		Primitive* closestPrimitive = 0;

		glusVector3MultiplyScalarf(marchDirection, rayDirection, t);
		glusPoint4AddVector3f(marchPosition, rayPosition, marchDirection);

		for (k = 0; k < NUM_SPHERES + NUM_BOXES; k++)
		{
			Primitive* currentPrimitive = &g_allPrimitives[k];

			currentDistance = currentPrimitive->distanceFunction(marchPosition, currentPrimitive);

			if (currentDistance < distance)
			{
				distance = currentDistance;

				closestPrimitive = currentPrimitive;
			}
		}

		if (distance < EPSILON)
		{
			GLfloat samplePoints[4 * 6];

			// Copy hit position ...
			glusPoint4Copyf(hitPosition, marchPosition);

			// ... and calculate normal by sampling around the hit position.
			for (k = 0; k < 6; k++)
			{
				samplePoints[k*4+0] = hitPosition[0];
				samplePoints[k*4+1] = hitPosition[1];
				samplePoints[k*4+2] = hitPosition[2];
				samplePoints[k*4+3] = hitPosition[3];

				samplePoints[k*4+k/2] += GAMMA * (k%2 == 0 ? 1.0f : -1.0f);
			}
			for (k = 0; k < 3; k++)
			{
				hitDirection[k] = closestPrimitive->distanceFunction(&samplePoints[k*2*4 + 0], closestPrimitive) - closestPrimitive->distanceFunction(&samplePoints[k*2*4 + 4], closestPrimitive);
			}

			glusVector3Normalizef(hitDirection);

			primitiveNear = closestPrimitive;

			break;
		}

		// If t is larger than a given distance, assume that there is the nothing.
		if (t > MAX_DISTANCE)
		{
			break;
		}

		t += distance;
	}

	//

	// No intersection, return background color / ambient light.
	if (!primitiveNear)
	{
		pixelColor[0] = 0.8f;
		pixelColor[1] = 0.8f;
		pixelColor[2] = 0.8f;

		return;
	}

	//

	glusVector3MultiplyScalarf(eyeDirection, rayDirection, -1.0f);

	// Diffuse and specular color
	for (i = 0; i < NUM_LIGHTS; i++)
	{
		PointLight* pointLight = &g_allLights[i];

		GLboolean obstacle = GL_FALSE;
		GLfloat lightDirection[3];
		GLfloat incidentLightDirection[3];

		glusPoint4SubtractPoint4f(lightDirection, pointLight->position, hitPosition);
		glusVector3Normalizef(lightDirection);
		glusVector3MultiplyScalarf(incidentLightDirection, lightDirection, -1.0f);

		// Check for obstacles between current hit point surface and point light.
		for (k = 0; k < NUM_SPHERES + NUM_BOXES; k++)
		{
			Primitive* obstaclePrimitive = &g_allPrimitives[k];

			if (obstaclePrimitive == primitiveNear)
			{
				continue;
			}

			t = 0.0f;

			for (m = 0; m < MAX_STEPS; m++)
			{
				GLfloat distance = INFINITY;
				GLfloat currentDistance;
				Primitive* closestPrimitive = 0;

				glusVector3MultiplyScalarf(marchDirection, lightDirection, -t);
				glusPoint4AddVector3f(marchPosition, pointLight->position, marchDirection);

				for (o = 0; o < NUM_SPHERES + NUM_BOXES; o++)
				{
					Primitive* currentPrimitive = &g_allPrimitives[o];

					currentDistance = currentPrimitive->distanceFunction(marchPosition, currentPrimitive);

					if (currentDistance < distance && currentDistance >= 0.0f)
					{
						distance = currentDistance;

						closestPrimitive = currentPrimitive;
					}
					else if (currentDistance > distance && currentDistance < 0.0f)
					{
						distance = currentDistance;

						closestPrimitive = currentPrimitive;
					}
				}

				if (distance < EPSILON)
				{
					if (closestPrimitive != primitiveNear)
					{
						obstacle = GL_TRUE;
					}

					break;
				}

				if (t > MAX_DISTANCE)
				{
					break;
				}

				t += distance;
			}
		}

		// If no obstacle, illuminate hit point surface.
		if (!obstacle)
		{
			GLfloat diffuseIntensity = glusMathMaxf(0.0f, glusVector3Dotf(hitDirection, lightDirection));

			if (diffuseIntensity > 0.0f)
			{
				GLfloat specularReflection[3];

				GLfloat eDotR;

				pixelColor[0] = pixelColor[0] + diffuseIntensity * primitiveNear->material.diffuseColor[0] * pointLight->color[0];
				pixelColor[1] = pixelColor[1] + diffuseIntensity * primitiveNear->material.diffuseColor[1] * pointLight->color[1];
				pixelColor[2] = pixelColor[2] + diffuseIntensity * primitiveNear->material.diffuseColor[2] * pointLight->color[2];

				glusVector3Reflectf(specularReflection, incidentLightDirection, hitDirection);
				glusVector3Normalizef(specularReflection);

				eDotR = glusMathMaxf(0.0f, glusVector3Dotf(eyeDirection, specularReflection));

				if (eDotR > 0.0f)
				{
					GLfloat specularIntensity = powf(eDotR, primitiveNear->material.shininess);

					pixelColor[0] = pixelColor[0] + specularIntensity * primitiveNear->material.specularColor[0] * pointLight->color[0];
					pixelColor[1] = pixelColor[1] + specularIntensity * primitiveNear->material.specularColor[1] * pointLight->color[1];
					pixelColor[2] = pixelColor[2] + specularIntensity * primitiveNear->material.specularColor[2] * pointLight->color[2];
				}
			}
		}
	}

	// Emissive color
	pixelColor[0] = pixelColor[0] + primitiveNear->material.emissiveColor[0];
	pixelColor[1] = pixelColor[1] + primitiveNear->material.emissiveColor[1];
	pixelColor[2] = pixelColor[2] + primitiveNear->material.emissiveColor[2];
}
示例#4
0
文件: main.c 项目: Adon-m/OpenGL
static GLvoid trace(GLfloat pixelColor[4], const GLfloat rayPosition[4], const GLfloat rayDirection[3], const GLint depth)
{
	const GLfloat bias = 1e-4f;

	GLint i, k;

	GLfloat tNear = INFINITY;
	Sphere* sphereNear = 0;
	GLboolean insideSphereNear = GL_FALSE;

	GLfloat ray[3];

	GLfloat hitPosition[4];
	GLfloat hitDirection[3];

	GLfloat biasedPositiveHitPosition[4];
	GLfloat biasedNegativeHitPosition[4];
	GLfloat biasedHitDirection[3];

	GLfloat eyeDirection[3];

	//

	pixelColor[0] = 0.0f;
	pixelColor[1] = 0.0f;
	pixelColor[2] = 0.0f;
	pixelColor[3] = 1.0f;

	//

	for (i = 0; i < NUM_SPHERES; i++)
	{
		GLfloat t0 = INFINITY;
		GLfloat t1 = INFINITY;
		GLboolean insideSphere = GL_FALSE;

		Sphere* currentSphere = &g_allSpheres[i];

		GLint numberIntersections = glusIntersectRaySpheref(&t0, &t1, &insideSphere, rayPosition, rayDirection, currentSphere->center, currentSphere->radius);

		if (numberIntersections)
		{
			// If intersection happened inside the sphere, take second intersection point, as this one is on the surface.
			if (insideSphere)
			{
				t0 = t1;
			}

			// Found a sphere, which is closer.
			if (t0 < tNear)
			{
				tNear = t0;
				sphereNear = currentSphere;
				insideSphereNear = insideSphere;
			}
		}
	}

	//

	// No intersection, return background color / ambient light.
	if (!sphereNear)
	{
		pixelColor[0] = 0.8f;
		pixelColor[1] = 0.8f;
		pixelColor[2] = 0.8f;

		return;
	}

	// Calculate ray hit position ...
	glusVector3MultiplyScalarf(ray, rayDirection, tNear);
	glusPoint4AddVector3f(hitPosition, rayPosition, ray);

	// ... and normal
	glusPoint4SubtractPoint4f(hitDirection, hitPosition, sphereNear->center);
	glusVector3Normalizef(hitDirection);

	// If inside the sphere, reverse hit vector, as ray comes from inside.
	if (insideSphereNear)
	{
		glusVector3MultiplyScalarf(hitDirection, hitDirection, -1.0f);
	}

	//

	// Biasing, to avoid artifacts.
	glusVector3MultiplyScalarf(biasedHitDirection, hitDirection, bias);
	glusPoint4AddVector3f(biasedPositiveHitPosition, hitPosition, biasedHitDirection);
	glusPoint4SubtractVector3f(biasedNegativeHitPosition, hitPosition, biasedHitDirection);

	//

	GLfloat reflectionColor[4] = {0.0f, 0.0f, 0.0f, 1.0f};
	GLfloat refractionColor[4] = {0.0f, 0.0f, 0.0f, 1.0f};

	GLfloat fresnel = glusVector3Fresnelf(rayDirection, hitDirection, R0);

	// Reflection ...
	if (sphereNear->material.reflectivity > 0.0f && depth < MAX_RAY_DEPTH)
	{
		GLfloat reflectionDirection[3];

		glusVector3Reflectf(reflectionDirection, rayDirection, hitDirection);
		glusVector3Normalizef(reflectionDirection);

		trace(reflectionColor, biasedPositiveHitPosition, reflectionDirection, depth + 1);
	}

	// ... refraction.
	if (sphereNear->material.alpha < 1.0f && depth < MAX_RAY_DEPTH)
	{
		GLfloat refractionDirection[3];

		// If inside, it is from glass to air.
		GLfloat eta = insideSphereNear ? 1.0f / Eta : Eta;

		glusVector3Refractf(refractionDirection, rayDirection, hitDirection, eta);
		glusVector3Normalizef(refractionDirection);

		trace(refractionColor, biasedNegativeHitPosition, refractionDirection, depth + 1);
	}
	else
	{
		fresnel = 1.0f;
	}

	//

	glusVector3MultiplyScalarf(eyeDirection, rayDirection, -1.0f);

	// Diffuse and specular color
	for (i = 0; i < NUM_LIGHTS; i++)
	{
		PointLight* pointLight = &g_allLights[i];

		GLboolean obstacle = GL_FALSE;
		GLfloat lightDirection[3];
		GLfloat incidentLightDirection[3];

		glusPoint4SubtractPoint4f(lightDirection, pointLight->position, hitPosition);
		glusVector3Normalizef(lightDirection);
		glusVector3MultiplyScalarf(incidentLightDirection, lightDirection, -1.0f);

		// Check for obstacles between current hit point surface and point light.
		for (k = 0; k < NUM_SPHERES; k++)
		{
			Sphere* obstacleSphere = &g_allSpheres[k];

			if (obstacleSphere == sphereNear)
			{
				continue;
			}

			if (glusIntersectRaySpheref(0, 0, 0, biasedPositiveHitPosition, lightDirection, obstacleSphere->center, obstacleSphere->radius))
			{
				obstacle = GL_TRUE;

				break;
			}
		}

		// If no obstacle, illuminate hit point surface.
		if (!obstacle)
		{
			GLfloat diffuseIntensity = glusMaxf(0.0f, glusVector3Dotf(hitDirection, lightDirection));

			if (diffuseIntensity > 0.0f)
			{
				GLfloat specularReflection[3];

				GLfloat eDotR;

				pixelColor[0] = pixelColor[0] + diffuseIntensity * sphereNear->material.diffuseColor[0] * pointLight->color[0];
				pixelColor[1] = pixelColor[1] + diffuseIntensity * sphereNear->material.diffuseColor[1] * pointLight->color[1];
				pixelColor[2] = pixelColor[2] + diffuseIntensity * sphereNear->material.diffuseColor[2] * pointLight->color[2];

				glusVector3Reflectf(specularReflection, incidentLightDirection, hitDirection);
				glusVector3Normalizef(specularReflection);

				eDotR = glusMaxf(0.0f, glusVector3Dotf(eyeDirection, specularReflection));

				if (eDotR > 0.0f && !insideSphereNear)
				{
					GLfloat specularIntensity = powf(eDotR, sphereNear->material.shininess);

					pixelColor[0] = pixelColor[0] + specularIntensity * sphereNear->material.specularColor[0] * pointLight->color[0];
					pixelColor[1] = pixelColor[1] + specularIntensity * sphereNear->material.specularColor[1] * pointLight->color[1];
					pixelColor[2] = pixelColor[2] + specularIntensity * sphereNear->material.specularColor[2] * pointLight->color[2];
				}
			}
		}
	}

	// Emissive color
	pixelColor[0] = pixelColor[0] + sphereNear->material.emissiveColor[0];
	pixelColor[1] = pixelColor[1] + sphereNear->material.emissiveColor[1];
	pixelColor[2] = pixelColor[2] + sphereNear->material.emissiveColor[2];

	// Final color with reflection and refraction
	pixelColor[0] = (1.0f - fresnel) * refractionColor[0] * (1.0f - sphereNear->material.alpha) + pixelColor[0] * (1.0f - sphereNear->material.reflectivity) * sphereNear->material.alpha + fresnel * reflectionColor[0] * sphereNear->material.reflectivity;
	pixelColor[1] = (1.0f - fresnel) * refractionColor[1] * (1.0f - sphereNear->material.alpha) + pixelColor[1] * (1.0f - sphereNear->material.reflectivity) * sphereNear->material.alpha + fresnel * reflectionColor[1] * sphereNear->material.reflectivity;
	pixelColor[2] = (1.0f - fresnel) * refractionColor[2] * (1.0f - sphereNear->material.alpha) + pixelColor[2] * (1.0f - sphereNear->material.reflectivity) * sphereNear->material.alpha + fresnel * reflectionColor[2] * sphereNear->material.reflectivity;
}