   line 1 pixel too high
  I'm using OpenGL for a 2D application. I use the "official" code for setting up a 2D view in OpenGL. (see source below, it comes from http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/)I think that should mean that the top row of pixels has y-coordinate 0. However, when it comes to drawing lines, it has coordinate 1.The annoying thing is that quads are correct, and only lines are 1 pixel too high.#include <GL/gl.h>#include <SDL/SDL.h>int main(){  int w = 800; //width of the screen  int h = 600; //height of the screen    SDL_Init(SDL_INIT_VIDEO);    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);  SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);    SDL_Surface* scr = SDL_SetVideoMode(w, h, 32, SDL_OPENGL);    //the official code for "Setting Your Raster Position to a Pixel Location" (i.e. set up an oldskool 2D screen)  glViewport(0, 0, w, h);  glMatrixMode(GL_PROJECTION);  glLoadIdentity();  glOrtho(0, w, h, 0, -1, 1);  glMatrixMode(GL_MODELVIEW);  glLoadIdentity();    glColor4ub(255, 255, 0, 255);    //this yellow line should be on the top row (y coordinate 0), but it's invisible because it's 1 higher  glBegin(GL_LINES);    glVertex2d(0, 0);    glVertex2d(100, 0);  glEnd();    glColor4ub(255, 0, 0, 255);    //this line is on the top row, even though it should be the second row (y coordinate 1)  glBegin(GL_LINES);    glVertex2d(0, 1);    glVertex2d(100, 1);  glEnd();    //2x2 pixel square ---> this one is correct!! it includes pixels from the top row and the row below that, a 2x2 pixel square  glBegin(GL_QUADS);    glVertex3d(300, 0, 1);    glVertex3d(302, 0, 1);    glVertex3d(302, 2, 1);    glVertex3d(300, 2, 1);  glEnd();    SDL_Event event = {0};  int done = 0;  while(done == 0)  {    while(SDL_PollEvent(&event))    { if(event.type == SDL_QUIT) done = 1; if(event.type == SDL_KEYDOWN) done = 1; SDL_GL_SwapBuffers();    }    SDL_Delay(5); //so it consumes less processing power  }}Why are the lines 1 pixel higher while rectangles are correct? Is this platform dependent? Let's hope not because then OpenGL would be less useful for 2D drawing!If it's not platform dependent: is there a reasoning behind it, and is the solution simply to draw my lines one pixel lower and it'll work pixel-correct on all possible platforms?   
  What happens if you make the line 3d as well?   ;Quote:Original post by dpadam450What happens if you make the line 3d as well?Using 2d or 3d vertices has no effect. E.g. the following code has exactly the same result:  //why is this yellow line invisible? It should be at the top pixel row (y = 0)  glColor4ub(255, 255, 0, 255);  glBegin(GL_LINES);    glVertex3d(0, 0, 0);    glVertex3d(100, 0, 0);  glEnd();    //this red line is seen at the top row, but it has y coordinate 1 which should be the second row  glColor4ub(255, 0, 0, 255);  glBegin(GL_LINES);    glVertex3d(0, 1, 0);    glVertex3d(100, 1, 0);  glEnd();    //unlike the lines, this rectangle (a 2x2 pixel square) occupies the top row (0) and the second row (1)  glBegin(GL_QUADS);    glVertex2d(300, 0);    glVertex2d(302, 0);    glVertex2d(302, 2);    glVertex2d(300, 2);  glEnd();;  OpenGL got different rules for rasterizing point and lines compared to triangles. Your code is correct for drawing surface primitives, but ambiguous for lines and points.Your setup, for example, have y=0 at the very top of the viewport, and the very top of the viewport is at the top edge of the top row of pixels. If you draw a line exactly on the edge between two pixel rows, only the mechanism of rounding half an integer determines which line of pixels is actually drawn.If you need pixel perfect line and point drawing, you need to offset your coordinates by one half so you actually hit pixel centers, not pixel edges. However, offsetting by one half indroduces the exact same problem when drawing surface primitives instead. Solution is to either offset by something between no offset and one half offset, that is, 0.25, or to use different matrix setup for surface and lines/points.This is well specified in the API specification.   ;  Brother Bob has got it.Basically, in OpenGL, when drawing lines in 2d, you want the line to go through the center of the pixels: e.g. glVertex2d(0, 0.5); glVertex2d(640, 0.5); for a line covering the first row of pixels.When drawing primitives with an area, you want to specify the corners of pixels: e.g. glVertex2d(15, 15); glVertex2d(15, 20); glVertex2d(20, 20); glVertex2d(20, 15); for a 5x5 pixel square.   ;  Here's a picture I drew to help describe the solution in a past thread here. The grid corresponds to pixels.;  I don't know if this is the correct way to solve it, but when I had this problem I would push a translation matrix on the stack with the offset before rendering the 2d portions...   ;  Thank you very much, it works very well now (at least for horizontal lines), and I'm also glad to hear that it's defined like this in OpenGL to be pixel precise.I almost thought it depended on the video card what it would do!Quote:Original post by shurcoolBasically, in OpenGL, when drawing lines in 2d, you want the line to go through the center of the pixels: e.g. glVertex2d(0, 0.5); glVertex2d(640, 0.5); for a line covering the first row of pixels.I still have a question about this:For horizontal lines I didn't have the same problem as for vertical lines. In your code, the y coordinates are 0.5, but the x coordinates still are whole numbers.If I'd be drawing sloped lines, how can I make it so that the line will always include the upper left pixel, and always exclude the lower right pixel? I like having the top left being inclusive and the bottom right being exclusive, just like with arrays starting at index 0 and not including the index that is their size.E.g. if in a 2D graphics engine that doesn't use centres of pixels but the top lefts I'd want to draw a line from 0,0 to 547,200, then pixel 0,0 should be included, pixel 547,200 not.If in your code I'd use 0.5 and 640.5 instead of 0 and 640, wouldn't the line be one pixel too long, that is, 641 instead of 640 pixels long?   ;Quote:Original post by LodeI still have a question about this:For horizontal lines I didn't have the same problem as for vertical lines. In your code, the y coordinates are 0.5, but the x coordinates still are whole numbers.The problem is solved for the Y-axis in the picture, but the line ends as you noticed on pixel boundaries. It is not defined which will be the start and end pixels in that case. To define it, X-coordinates should be pixel centers aswell.Quote:Original post by LodeIf I'd be drawing sloped lines, how can I make it so that the line will always include the upper left pixel, and always exclude the lower right pixel? I like having the top left being inclusive and the bottom right being exclusive, just like with arrays starting at index 0 and not including the index that is their size.E.g. if in a 2D graphics engine that doesn't use centres of pixels but the top lefts I'd want to draw a line from 0,0 to 547,200, then pixel 0,0 should be included, pixel 547,200 not.This is the required behaviour in OpenGL already. Assuming pixel perfect coordinates, drawing a line will always include the starting pixel, and exclude the ending pixel. Check the specification, or search the web, for the diamond exit rule. That means, if you draw a line from (0, 0) to (547,20), then (0, 0) will be drawn but not (547,20).The purpose of this is to make sure connected lines are not overdrawn. Make a strip of lines and all pixels on the lines are drawn exactly once, and is required by the specification.Now, if you require to always exclude the lower right pixel of a line, then just swap start and end points of the line accordingly, so that the end point of the line ends up to the lower right.   