Drawing infinite grid

Started by
11 comments, last by zgintasz 11 years ago

You don't have to draw an infinite grid to make it look like one:

">

#include <GL/glfw.h>

int main(){
    int x, y, nx, ny, mx, my, lx, ly;
    int dx = 0;
    int dy = 0;
    int w = 512;
    int h = 512;
    int cell_w = 32;
    int cell_h = 32;

    glfwInit();
    glfwOpenWindow(w, h, 8, 8, 8, 8, 0, 0, GLFW_WINDOW);

    glfwGetMousePos(&lx, &ly);

    while (!glfwGetKey(GLFW_KEY_ESC)){
        glClear(GL_COLOR_BUFFER_BIT);

        /* Make OpenGL cover full window size */
        glfwGetWindowSize(&w, &h);
        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(0, w, h, 0, -1, 1);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        /* Handle mouse input */
        glfwGetMousePos(&mx, &my);
        if (glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT)){
            /* Offset the grid by the distance the mouse moved */
            dx += mx - lx;
            dy += my - ly;
            /* Use the %-operator to jump back */
            dx %= cell_w;
            dy %= cell_h;

            float r = 10.0f;
            glRectf(mx-r, my-r, mx+r, my+r);
        }
        lx = mx;
        ly = my;

        glTranslatef(dx, dy, 0.0f);

        /* Draw a grid which is a little bigger than the screen */
        nx = w/cell_w + 2;
        ny = h/cell_h + 2;
        glBegin(GL_LINES);
        for (x=0; x<nx; x++){
            glVertex2f(x*cell_w,  -cell_h);
            glVertex2f(x*cell_w, h+cell_h);
        }
        for (y=0; y<ny; y++){
            glVertex2f( -cell_w, y*cell_h);
            glVertex2f(w+cell_w, y*cell_h);
        }
        glEnd();

        glfwSwapBuffers();
    }
    glfwTerminate();
    return 0;
}

This is deprecated OpenGL. With a fragment shader this would be much easier (but much harder to setup).

Advertisement

What have you tried?

I knew somebody will ask that question biggrin.png.

After a few hours of thinking I finally almost completed it, there is only one issue left:

http://tinypic.com/player.php?v=6h55wl&s=6

sorry for that terrible quality(I can try to record it again if needed...), but as you can see the grid doesn't follow the screen very well.


I'll be very thankful if someone will help me fixing that problem.

I've just started learning opengl few weeks ago, so I don't know everything very well...

Here is my code(grid class, code is a probably a mess right now, I will tidy it after fixing that problem):


    public class grid
    {
        private MainWindow mainWindow;
        
        public float viewWidth;
        public float viewHeight;
        public Point cameraPos;

        public Rectangle glview;
        public int WidthItems { get; set; }
        public int HeightItems { get; set; }
        public Rectangle[] squares;
        private int totalSquares;
        private int squareSize = 75;

        public grid(MainWindow window, int widthitems, int heightitems, int ViewWidth, int ViewHeight)
        {
            mainWindow = window;
            cameraPos = new Point(0, 0);
            viewWidth = ViewWidth;
            viewHeight = ViewHeight;
            WidthItems = (int)(viewHeight / squareSize);
            HeightItems = (int)(viewWidth / squareSize);
            totalSquares = WidthItems * HeightItems;
            squares = new Rectangle[totalSquares];
        }
        public Point CalculateViewCenterPos()
        {
            return mainWindow.convertScreenToWorldCoords((0 + glview.Width) / 2, (0 + glview.Height) / 2);
        }
        float tempOffsetX = 0f, tempOffsetY = 0f;
        float offsetX = 0f, offsetY = 0f;
        public void CameraMoved(float x, float y)
        {
            tempOffsetX += x;
            if (tempOffsetX > squareSize)
            {
                offsetX -= squareSize;
                tempOffsetX = 0;
            }
            else if (tempOffsetX < -squareSize)
            {
                offsetX += squareSize;
                tempOffsetX = 0;
            }
            tempOffsetY += y;
            if (tempOffsetY > squareSize)
            {
                offsetY -= squareSize;
                tempOffsetY = 0;
            }
            else if (tempOffsetY < -squareSize)
            {
                offsetY += squareSize;
                tempOffsetY = 0;
            }
        }
        public void calculateCoords()
        {
            Point topleft = mainWindow.convertScreenToWorldCoords(0, 0);
            mainWindow.testclickX = topleft.X;
            mainWindow.testclickY = topleft.Y;

            int startPosX = topleft.X - squareSize * 2;
            int startPosY = topleft.Y + squareSize;
            int id = 0;
            for (int i = 0; i < WidthItems; i++)
            {
                for (int j = 0; j < HeightItems; j++)
                {
                    squares[id].X = startPosX;
                    squares[id].Y = startPosY;
                    startPosX += squareSize;
                    id++;
                }
                startPosX = topleft.X - squareSize * 2;
                startPosY -= squareSize;
            }
        }
        public void draw()
        {
            for (int i = 0; i < totalSquares; i++)
            {
                GL.Color3(Color.Green);
                GL.PushMatrix();
                GL.Begin(BeginMode.Lines);
                GL.Vertex3(squares.X + offsetX, squares.Y + offsetY, -2);
                GL.Vertex3(squares.X + offsetX, squares.Y + squareSize + offsetY, -2);

                GL.Vertex3(squares.X + offsetX, squares.Y + offsetY, -2);
                GL.Vertex3(squares.X + squareSize + offsetX, squares.Y + offsetY, -2);

                GL.Vertex3(squares.X + squareSize + offsetX, squares.Y + squareSize + offsetY, -2);
                GL.Vertex3(squares.X + offsetX, squares.Y + squareSize + offsetY, -2);

                GL.Vertex3(squares.X + squareSize + offsetX, squares.Y + squareSize + offsetY, -2);
                GL.Vertex3(squares.X + squareSize + offsetX, squares.Y + offsetY, -2);
                GL.End();
                GL.PopMatrix();
            }
        }
    }

and MainWindow class:


                // ...
                grid maingrid;
                // ...
                maingrid.draw();
                // ...
                glviewRatio = (ClientRectangle.Width / zoom) / (ClientRectangle.Height / zoom) * 5;
                // ...
                maingrid = new grid(this, 50, 50, ClientRectangle.Width * 5 / zoom, ClientRectangle.Height * 5 / zoom);
                maingrid.glview = new Rectangle(glview.Location.X, glview.Location.Y, glview.Size.Width, glview.Size.Height);
                maingrid.calculateCoords();
                // ...
                // (every frame when mouse button is clicked)
                float x = (MousePosition.X - started_mouse_pos.X) * glviewRatio / zoom;
                float y = -(MousePosition.Y - started_mouse_pos.Y) * glviewRatio / zoom;
                maingrid.CameraMoved(x, y);
                started_mouse_pos.X = MousePosition.X;
                started_mouse_pos.Y = MousePosition.Y;

Game I'm making - GANGFORT, Google Play, iTunes

Finally, found the solution myself smile.png. Just changed CameraMoved function:


        public static void CameraMoved(float x, float y)
        {
            tempOffsetX += x;
            tempOffsetY += y;
            while (tempOffsetX >= squareSize)
            {
                offsetX -= squareSize;
                tempOffsetX -= squareSize;
            }
            while (tempOffsetX <= -squareSize)
            {
                offsetX += squareSize;
                tempOffsetX += squareSize;
            }
            while (tempOffsetY >= squareSize)
            {
                offsetY -= squareSize;
                tempOffsetY -= squareSize;
            }
            while (tempOffsetY <= -squareSize)
            {
                offsetY += squareSize;
                tempOffsetY += squareSize;
            }
        }

Game I'm making - GANGFORT, Google Play, iTunes

This topic is closed to new replies.

Advertisement