Archived

This topic is now archived and is closed to further replies.

Common edge removal

This topic is 5433 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all, im currently optimizing the shadow volume rendering for my 3d tile based engine and am looking at removing the common edges from the silohettes. currently im doing the following for each object in scene generate silohette add silohette vertices to engines shadow vertices array ( this checks if the vertex position already exists if so the index of this vertex is returned ) add silohette edge to engines shadow edges array ( an edge is defined by its indices in the shadow vertices array ) render shadow volumes as normal this works fine, however when I change the procedure to add the shadow edge to ignore any duplicate edges ( the theory being that if an edge is shared then it must be internal to the overall silohette of multiple tiles ) i start getting 'tears'. Is this an inherant problem with shadow volumes or am i missing a trick. Many thanks in advance. Mark. [edited by - MButchers on January 30, 2003 7:09:51 AM]

Share this post


Link to post
Share on other sites
Heres my code if it helps

function TNovaEngine.AddShadowVertex(AVertex: PVector3f): Integer;
var
i: Integer;
begin
for i := 0 to FShadowVertIndex-1 do
begin
if VectorEqualTo(@FShadowVertices,AVertex,1) then
begin
Result := i;
Exit;
end;
end;

if FShadowVertIndex > Length(FShadowVertices) then
begin
SetLength(FShadowVertices,Length(FShadowVertices)+100);
end;
FShadowVertices[FShadowVertIndex] := AVertex^;
Result := FShadowVertIndex;

Inc(FShadowVertIndex);
end;

function TNovaEngine.AddShadowEdge(AIndex1,AIndex2: Integer): Integer;
var
i: Integer;
begin
//removed as this causes tears
{for i := 0 to FShadowEdgeIndex-1 do
begin
if (FShadowEdges[i].iVIndex1 = AIndex1) and
(FShadowEdges[i].iVIndex2 = AIndex2) then
begin
FShadowEdges[i].bInternal := true;
Result := i;
Exit;
end else begin
if (FShadowEdges[i].iVIndex1 = AIndex2) and
(FShadowEdges[i].iVIndex2 = AIndex1) then
begin
FShadowEdges[i].bInternal := true;
Result := i;
Exit;
end;
end;
end;}

if FShadowEdgeIndex > Length(FShadowEdges) then
begin
SetLength(FShadowEdges,Length(FShadowEdges)+100);
end;
FShadowEdges[FShadowEdgeIndex].bInternal := false;
FShadowEdges[FShadowEdgeIndex].iVIndex1 := AIndex1;
FShadowEdges[FShadowEdgeIndex].iVIndex2 := AIndex2;
Result := FShadowEdgeIndex;

Inc(FShadowEdgeIndex);
end;

procedure TNovaEngine.DrawShadows;
var
vEqn: TVector4f;
i: Integer;

procedure il_VShadow(v1,v2,vr: PVector3f; ext: Single);
var
v,vi: TVector3f;
begin
v[0] := v1[0] + ((v1[0] - v2[0]) * ext);
v[1] := v1[1] + ((v1[1] - v2[1]) * ext);
v[2] := v1[2] + ((v1[2] - v2[2]) * ext);
RayPlaneIntersection(v1^,v,vEqn,vi);
vr^ := vi;
end;

procedure il_ProcessEdge(E: TShadowEdge);
var
v1,v2,v3,v4: TVector3f;
FShadowVolume: array [0..3] of TVector3f;
begin
//if E.bInternal then Exit;
v1 := FShadowVertices[E.iVIndex1];
v2 := FShadowVertices[E.iVIndex2];
il_VShadow(@v1,@FActiveLightPos,@v3,0.1);
il_VShadow(@v2,@FActiveLightPos,@v4,0.1);
FShadowVolume[0] := v1;
FShadowVolume[1] := v2;
FShadowVolume[2] := v3;
FShadowVolume[3] := v4;
glVertexPointer(3,GL_FLOAT,0,@FShadowVolume);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
end;

begin
vEqn := Vector4f(0,-1,0,0);
//ZeroMemory(FShadowVertices,SizeOf(TVector3f)*Length(FShadowVertices));

glStencilMask($ff);
glClearStencil(128);
ne_DisableGLClientState(GL_NORMAL_ARRAY);
ne_DisableGLClientState(GL_TEXTURE_COORD_ARRAY);

if FStippleShadowVolumes then
begin
ne_EnableGLState(GL_POLYGON_STIPPLE);
glPolygonStipple(@aStipple);
end else begin
ne_DisableGLState(GL_POLYGON_STIPPLE);
end;

ne_DisableGLState(GL_BLEND);
ne_DisableGLState(GL_LIGHTING);
ne_DisableGLState(GL_TEXTURE_2D);
ne_DisableGLState(GL_FOG);
ne_DisableGLState(GL_ALPHA_TEST);

glColorMask(false,false,false,false);
glDepthMask(false);

ne_EnableGLState(GL_STENCIL_TEST);
ne_EnableGLState(GL_CULL_FACE);
glStencilFunc(GL_ALWAYS, 0, $ff);

FShadowVertIndex := 0;
FShadowEdgeIndex := 0;

FRenderMode := rmShadow;
RenderGeometry;

if RenderShadowVolumes then
begin
glColor3f(1,1,1);
ne_DisableGLState(GL_CULL_FACE);
ne_DisableGLState(GL_STENCIL_TEST);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glColorMask(true,true,true,true);
for i := 0 to FShadowEdgeIndex-1 do
begin
il_ProcessEdge(FShadowEdges[i]);
end;
glColorMask(false,false,false,false);
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
ne_EnableGLState(GL_CULL_FACE);
ne_EnableGLState(GL_STENCIL_TEST);
end;

glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
glCullFace(GL_FRONT);
for i := 0 to FShadowEdgeIndex-1 do
begin
il_ProcessEdge(FShadowEdges[i]);
end;

glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glCullFace(GL_BACK);
for i := 0 to FShadowEdgeIndex-1 do
begin
il_ProcessEdge(FShadowEdges[i]);
end;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-FViewWidth/2,FViewWidth/2,FViewHeight/2,-FViewHeight/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushAttrib(GL_ALL_ATTRIB_BITS);

glColorMask(true,true,true,true);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_NOTEQUAL, 128, $ff);

if not FStippleShadowVolumes then
begin
ne_EnableGLState(GL_BLEND);
glColor4f(0,0,0,0.4);
ne_DisableGLState(GL_DEPTH_TEST);
glBegin(GL_QUADS);
glVertex2f(-FViewWidth/2,-FViewHeight/2);
glVertex2f(-FViewWidth/2,FViewHeight/2);
glVertex2f(FViewWidth/2,FViewHeight/2);
glVertex2f(FViewWidth/2,-FViewHeight/2);
glEnd;
end else begin
ne_DisableGLState(GL_BLEND);
glColor4f(0,0,0,1);
ne_DisableGLState(GL_DEPTH_TEST);
glBegin(GL_QUADS);
glVertex2f(-FViewWidth/2,-FViewHeight/2);
glVertex2f(-FViewWidth/2,FViewHeight/2);
glVertex2f(FViewWidth/2,FViewHeight/2);
glVertex2f(FViewWidth/2,-FViewHeight/2);
glEnd;
end;

glPopAttrib();

glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glLoadMatrixd(@FProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glLoadMatrixd(@FModelMatrix);

glDepthMask(true);
ne_DisableGLState(GL_CULL_FACE);
glCullFace(GL_BACK);
glColorMask(true,true,true,true);

ne_EnableGLClientState(GL_NORMAL_ARRAY);
ne_EnableGLClientState(GL_TEXTURE_COORD_ARRAY);

if FStippleShadowVolumes then
begin
ne_DisableGLState(GL_POLYGON_STIPPLE);
end;
ne_DisableGLState(GL_STENCIL_TEST);
end;

Cheers

Mark.

Share this post


Link to post
Share on other sites