Title: Custom implementation of glBegin, glVertexXX and the like
Post by: cheb on April 15, 2017, 03:28:13 AM
I was browsing sources of the legendary ZenGL library in search of enlightening when I suddenly realized that ZenGL has its own implementation of most common immediate mode functions to be used on top of GL ES (which, by design, doesn't support 'em). And then I thought: could this be it? Could a well optimized custom implementation be faster than what compatibility layers of modern ICDs provide out of mercy? All I know that immediate mode performance drops *sharply* after around 20 k vertexes. Maybe that's artificial? :-X What if custom implementation packed that array's texture and color values to something more compact than GL_FLOAT ? That would make uploading to video card during glEnd faster. And ZenGL does - it stores color values as GL_UNSIGNED_BYTE. Or do OA sources *already* use something like this? :-\ The inspirational code (can only be used for inspiration, heh) Just look at this little beauty! :-* procedure glEnd; begin if bSize = 0 Then exit;
if RenderTextured Then begin glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glTexCoordPointer( 2, GL_FLOAT, 24, @bVertices[ 0 ] ); end;
glEnableClientState( GL_COLOR_ARRAY ); glColorPointer( 4, GL_UNSIGNED_BYTE, 24, @bVertices[ 0 ].Color );
glEnableClientState( GL_VERTEX_ARRAY ); glVertexPointer( 3, GL_FLOAT, 24, @bVertices[ 0 ].X );
glDrawArrays( RenderMode, 0, bSize );
glDisableClientState( GL_VERTEX_ARRAY ); glDisableClientState( GL_COLOR_ARRAY ); if RenderTextured Then glDisableClientState( GL_TEXTURE_COORD_ARRAY ); end; The rest procedure glBegin(mode: GLenum); begin bSize := 0; RenderTextured := FALSE;
if Mode = GL_QUADS Then begin RenderQuad := TRUE; newTriangle := 0; RenderMode := GL_TRIANGLES; end else begin RenderQuad := FALSE; RenderMode := Mode; end; end;
procedure glColor4ub(red, green, blue, alpha: GLubyte); begin PByteArray( @bColor )[ 0 ] := red; PByteArray( @bColor )[ 1 ] := green; PByteArray( @bColor )[ 2 ] := blue; PByteArray( @bColor )[ 3 ] := alpha; end;
procedure glColor4ubv(v: PGLubyte); begin bColor := PLongWord( v )^; end;
procedure glColor4f(red, green, blue, alpha: GLfloat); begin PByteArray( @bColor )[ 0 ] := Round( red * 255 ); PByteArray( @bColor )[ 1 ] := Round( green * 255 ); PByteArray( @bColor )[ 2 ] := Round( blue * 255 ); PByteArray( @bColor )[ 3 ] := Round( alpha * 255 ); end;
{$IFDEF ANDROID} function tan( x : Single ) : Single; var _sin,_cos : Single; begin m_SinCos( x, _sin, _cos ); tan := _sin / _cos; end; {$ENDIF}
procedure gluPerspective(fovy, aspect, zNear, zFar: GLdouble); var m : array[ 1..4, 1..4 ] of Single; f : Single; begin f := 1 / tan( FOVY * pi / 360 );
m[ 1, 1 ] := f / aspect; m[ 1, 2 ] := 0; m[ 1, 3 ] := 0; m[ 1, 4 ] := 0;
m[ 2, 1 ] := 0; m[ 2, 2 ] := f; m[ 2, 3 ] := 0; m[ 2, 4 ] := 0;
m[ 3, 1 ] := 0; m[ 3, 2 ] := 0; m[ 3, 3 ] := ( zFar + zNear ) / ( zNear - zFar ); m[ 3, 4 ] := -1;
m[ 4, 1 ] := 0; m[ 4, 2 ] := 0; m[ 4, 3 ] := 2 * zFar * zNear / ( zNear - zFar ); m[ 4, 4 ] := 0;
glLoadMatrixf( @m[ 1, 1 ] ); end;
procedure glVertex2f(x, y: GLfloat); var vertex : zglGLESPVertex; begin if ( not RenderTextured ) and ( bSize = Length( bVertices ) ) Then SetLength( bVertices, bSize + 1024 );
vertex := @bVertices[ bSize ]; vertex.X := x; vertex.Y := y; vertex.Z := 0; vertex.Color := bColor; INC( bSize ); if RenderQuad Then begin INC( newTriangle ); if newTriangle = 3 Then begin if bSize = Length( bVertices ) Then SetLength( bVertices, bSize + 1024 ); bVertices[ bSize ] := bVertices[ bSize - 1 ];
INC( bSize ); end else if newTriangle = 4 Then begin if bSize = Length( bVertices ) Then SetLength( bVertices, bSize + 1024 ); bVertices[ bSize ] := bVertices[ bSize - 5 ];
INC( bSize ); newTriangle := 0; end; end; end;
procedure glVertex2fv(v: PGLfloat); var vertex : zglGLESPVertex; begin if ( not RenderTextured ) and ( bSize = Length( bVertices ) ) Then SetLength( bVertices, bSize + 1024 );
vertex := @bVertices[ bSize ]; vertex.X := zglPPoint2D( v ).X; vertex.Y := zglPPoint2D( v ).Y; vertex.Z := 0; vertex.Color := bColor; INC( bSize ); if RenderQuad Then begin INC( newTriangle ); if newTriangle = 3 Then begin if bSize = Length( bVertices ) Then SetLength( bVertices, bSize + 1024 ); bVertices[ bSize ] := bVertices[ bSize - 1 ];
INC( bSize ); end else if newTriangle = 4 Then begin if bSize = Length( bVertices ) Then SetLength( bVertices, bSize + 1024 ); bVertices[ bSize ] := bVertices[ bSize - 5 ];
INC( bSize ); newTriangle := 0; end; end; end;
procedure glVertex3f(x, y, z: GLfloat); var vertex : zglGLESPVertex; begin if ( not RenderTextured ) and ( bSize = Length( bVertices ) ) Then SetLength( bVertices, bSize + 1024 );
vertex := @bVertices[ bSize ]; vertex.X := x; vertex.Y := y; vertex.Z := z; vertex.Color := bColor; INC( bSize ); if RenderQuad Then begin INC( newTriangle ); if newTriangle = 3 Then begin if bSize = Length( bVertices ) Then SetLength( bVertices, bSize + 1024 ); bVertices[ bSize ] := bVertices[ bSize - 1 ];
INC( bSize ); end else if newTriangle = 4 Then begin if bSize = Length( bVertices ) Then SetLength( bVertices, bSize + 1024 ); bVertices[ bSize ] := bVertices[ bSize - 5 ];
INC( bSize ); newTriangle := 0; end; end; end;
procedure glGetTexImage(target: GLenum; level: GLint; format: GLenum; atype: GLenum; pixels: Pointer); begin end;
procedure glTexCoord2f(s, t: GLfloat); begin RenderTextured := TRUE;
if bSize = Length( bVertices ) Then SetLength( bVertices, bSize + 1024 ); bVertices[ bSize ].U := s; bVertices[ bSize ].V := t; end;
procedure glTexCoord2fv(v: PGLfloat); begin RenderTextured := TRUE;
if bSize = Length( bVertices ) Then SetLength( bVertices, bSize + 1024 ); bVertices[ bSize ].U := zglPPoint2D( v ).X; bVertices[ bSize ].V := zglPPoint2D( v ).Y; end;
Title: Re: Custom implementation of glBegin, glVertexXX and the like
Post by: pelya on April 16, 2017, 05:24:21 AM
Is this... Is this Pascal? :o
|