Skip to content

Vertices pages boundary overlap #1426

Open
@AlexCP11

Description

@AlexCP11

There is an issue related to vertices pages boundary overlap. Result is extra random triangles or missed triangles. Issue reproduced on my devices iPad Mini (iOS 15.7.1), iPhone 7+ (iOS 15.7.5) and all Simulators (iOS 13.7, 14.2, 16.4).

Simplified sample code. Triangles should fill-up all node to make glitches easy visible. 5 vertices per iteration used to guarantee pages overlap.

- (void) draw:(CCRenderer *)renderer transform:(const GLKMatrix4 *)transform
{
    int verticesCount = 65535*2+10; // to make two pages overlaps
    int trianglesDrawsCount = (verticesCount/5); 
    
    GLKVector4 redColor = [CCColor colorWithRed:1. green:0. blue:0. alpha:1.].glkVector4;
    CGFloat x,y,d;
    int trianlgesPerRow = 132;
    d = <triangle size to fill-up node with triangles>;

    CGFloat vertexArray[10];
    CGPoint points[5];
    for (int trianglesDraw=0; trianglesDraw<trianglesDrawsCount; trianglesDraw++) {
        x = d*(trianglesDraw%trianlgesPerRow);
        y = d*(trianglesDraw/trianlgesPerRow);
        
        vertexArray[0] = x;
        vertexArray[1] = y;
        vertexArray[2] = x+d;
        vertexArray[3] = y;
        vertexArray[4] = x+d;
        vertexArray[5] = y+d;
        
        vertexArray[6] = x;
        vertexArray[7] = y+d;
        vertexArray[8] = x+d;
        vertexArray[9] = y+d;

        CCRenderBuffer buffer = [renderer enqueueTriangles:2 andVertexes:5 withState:self.renderState globalSortOrder:0];

        for (int i=0; i<5; ++i) {
            points[i] = ccp(vertexArray[2*i], vertexArray[2*i+1]);
            CCRenderBufferSetVertex(buffer, i, CCVertexApplyTransform((CCVertex){{points[i].x, points[i].y, 0, 1}, {0, 0}, {0, 0}, redColor}, transform));
        }

        CCRenderBufferSetTriangle(buffer, 0, 0, 1, 2);
        CCRenderBufferSetTriangle(buffer, 1, 0, 3, 4);
    }
}

Result is in attachment.
pagesoverlap_issue

Take a look into CCNoARC.m file. Method CCRenderer::enqueueLines:andVertexes:withState:globalSortOrder:

-(CCRenderBuffer)enqueueTriangles:(NSUInteger)triangleCount andVertexes:(NSUInteger)vertexCount withState:(CCRenderState *)renderState globalSortOrder:(NSInteger)globalSortOrder;
{
	// Need to record the first vertex or element index before pushing more vertexes.
	NSUInteger firstVertex = _buffers->_vertexBuffer->_count;
	NSUInteger firstIndex = _buffers->_indexBuffer->_count;
	
	// Value is 0 unless there a page boundary overlap would occur.
	NSUInteger vertexPageOffset = PageOffset(firstVertex, vertexCount);
	if (vertexPageOffset>0) {
		int stop=0; // #1 if we got here then visual bug will be
	}
	
	// Split vertexes into pages of 2^16 vertexes since GLES2 requires indexing with shorts.
	NSUInteger vertexPage = (firstVertex + vertexPageOffset) >> 16;
	NSUInteger vertexPageIndex = (firstVertex + vertexPageOffset) & 0xFFFF;
	
	// Ensure that the buffers have enough storage space.
	NSUInteger indexCount = 3*triangleCount;
	CCVertex *vertexes = CCGraphicsBufferPushElements(_buffers->_vertexBuffer, vertexCount + vertexPageOffset);
	if (vertexPageOffset>0) {
		vertexes = vertexes + vertexPageOffset; // #2 vertices will be stored from beginning of the next page
	}

You can set breakpoint in line with my first comment to easily detect error.

	if (vertexPageOffset>0) {
		int stop=0; // #1 if we got here then visual bug will be
	}

I've added last three lines to fix this issue. I don't know is it solution or just workaround, but it works now.

	if (vertexPageOffset>0) {
		vertexes = vertexes + vertexPageOffset; // #2 vertices will be stored from beginning of the next page
	}

I hope it helps somebody.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions