Faking an 'infinite grid' in Ortho

Started by
6 comments, last by deadstar 15 years, 10 months ago
Hi, I'm making very good progress with my level editor, and would like to know how I can simulate an infinite 2D grid - if the user pans a 2D view, the grid will continue forever. I don't even know where to start on this one. My current grid rendering is pretty simple:

void GLViewport::DrawGridXY(float r, float g, float b, GLfloat size, GLfloat resolution)
{
    glColor3f(r, g, b);
    for(GLfloat i = -size; i <= size; i += resolution)
    {
        glBegin(GL_LINES);
        glVertex3f(-size, i, 0);
        glVertex3f(size, i, 0);
        glVertex3f(i,-size, 0);
        glVertex3f(i, size, 0);
        glEnd();
    }

    glColor3f(1.0, 1.0, 1.0);
}

Articles, pseudo-code, anything appreciated. Google isn't turning up many results. In addition, I'm planning snap-to-grid, if anyone has any experience with this.

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

Advertisement
One solution would be simply to render only the part of the 'infinite' grid that is currently visible on screen. The code for this would be similar to what you have now, except that instead of using the 'size' variable, you would compute 'start' and 'end' values just past the left, right, top, and bottom edges of the visible area.
I would guess it depends largely on what parameters you're passing to glOrtho(). How are you setting up glOrtho?
Cheers jky, I'll have a go at working it out later on.

Rosewell, I'm setting up Ortho like this:
void GLViewport::Setup2DViewport(float LeftX, float LeftY, float BottomX, float BottomY){    //glClearColor(0.0f, 0.0f, 0.0f, 1.0f);    glEnable(GL_TEXTURE_2D);    glEnable(GL_COLOR_MATERIAL);    glEnable(GL_BLEND);    glDisable(GL_DEPTH_TEST);    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);    glViewport(LeftX, LeftY, BottomX - LeftX, BottomY - LeftY);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    glTranslatef(CamX, CamY, CamZ);    glOrtho (-OrthoZoom, OrthoZoom, -OrthoZoom * BottomY / BottomX, OrthoZoom * BottomY / BottomX, -OrthoZoom, OrthoZoom);    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();}


I pass (0, 0, Width, Height) to that function. The variable names are quite misleading, I'll tidy it up later.

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

For such a task I simply created a shader, that I render full-screen:

Vertex:
uniform vec4 Transpose; // xyz is the transpose, w is the scaleuniform vec2 ScreenSize;uniform int ProjMode;varying vec4 color;varying vec4 vpos;varying vec4 Transpose2;void main(){	vec4 pos = gl_Vertex;		color = 0.44;		vec4 T = Transpose;	Transpose2=T;		color = gl_Color;	vpos = pos;	gl_Position = pos;}


Fragment:
uniform vec4 Transpose; // xyz is the transpose, w is the scaleuniform vec2 ScreenSize;uniform int ProjMode;varying vec4 color;varying vec4 vpos;varying vec4 Transpose2;void main(){	vec4 FinalColor = 0.44;	vec2 CurPos = abs(floor(gl_FragCoord.xy-(ScreenSize*0.5)+Transpose2.xy*Transpose2.w));			float scale1 = 32*exp2(fract(log2(Transpose2.w)));		vec2 modPos = floor(mod(CurPos,scale1));	if(modPos.x==0)FinalColor=0.4;	if(modPos.y==0)FinalColor=0.4;			if(CurPos.x==0)FinalColor=0;	if(CurPos.y==0)FinalColor=0;				if(CurPos.y&lt;32*Transpose2.w){		if(CurPos.x&lt; 32*Transpose2.w)FinalColor.z=1;	}	if(ProjMode==0)FinalColor=0.44;			gl_FragColor = FinalColor;}


This code automatically handles zoom-in passed via the Transpose.w parameter (grid adaptive "subdivision").

Here's how it looks ^^" :

(was just a toy to see if I can make LW-like interface)
Quote:Original post by idinev
For such a task I simply created a shader, that I render full-screen:


That's awesome! Is it convertible to handle rendering the infinite grid in 3D? I was thinking of doing something similar before for 3D where I would render a 'ground plane' quad that spanned the entire frustum and then used a pixel shader to do essentially what you have done.

Author Freeworld3Dhttp://www.freeworld3d.org
I think it's possible, but the math required is not my forte :).
I'm still in fixed-function land for the moment, my shader framework isn't finished.

Here's what I came up with, thanks to several sources and a bit of planning on paper. I'd appreciate some opinions:

void DrawGrid(float CentreX, float CentreY, int Size, int Resolution){    int Spacing[2] = {Resolution, Resolution * 10};	float OffsetX = std::fmod(CentreX, Resolution * Resolution * 2);	float OffsetY = std::fmod(CentreY, Resolution * Resolution * 2);	glBegin(GL_LINES);    for(int Grid = 0; Grid < 2 ; Grid++)    {        if(Grid > 0) glColor3ub(140, 255, 140);		else glColor3ub(100, 100, 100);        for(float x = -CentreX - Size/2; x < -CentreX + Size/2; x += Spacing[grid])        {			glVertex3f(x + OffsetX, -CentreY - Size/2, 0.0f);			glVertex3f(x + OffsetX, -CentreY + Size/2, 0.0f);        }        for(float y = -CentreY - Size/2; y < -CentreY + Size/2; y += Spacing[grid])        {			glVertex3f(-CentreX - Size/2, y + OffsetY, 0.0f);			glVertex3f(-CentreX + Size/2, y + OffsetY, 0.0f);        }    }	glEnd();}


It works as planned: The grid is only drawn inside the viewport, and appears 'infinite' when panned. I'm pleased with the two-tone colour. I'll add zoom functionality later too.

But, my maths skills are a pathetic low, and I can't help but thinking 'fmod' was the wrong tool for the job.

"The right, man, in the wrong, place, can make all the dif-fer-rence in the world..." - GMan, Half-Life 2

A blog of my SEGA Megadrive development adventures: http://www.bigevilcorporation.co.uk

This topic is closed to new replies.

Advertisement