简体   繁体   中英

opengl draw in 2D coordinates instead of vertex coordinate system

how can i draw in 2D coordinates instead of vertex coordinate system, as this =>

drawPoint(50 , 100 ,  0.01f);

在此处输入图片说明

this is my code , a background texture and a point

static void Draw(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    double w = glutGet( GLUT_WINDOW_WIDTH ) / 300.0;
    double h = glutGet( GLUT_WINDOW_HEIGHT ) / 300.0;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glOrtho( -1 * w/2, 1 * w/2, -1 * h/2, 1 * h/2, w/2, -h/2);
    glBegin(GL_POLYGON);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(-w/2.f, -h/2.f,  0.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex3f( w/2.f, -h/2.f,  0.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex3f( w/2.f,  h/2.f,  0.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-w/2.f,  h/2.f,  0.0f);
    glEnd();

  drawPoint(50 , 100 ,  0.01f);
  glutSwapBuffers();
}

the function DrawPoint => draws circles

void drawPoint(GLfloat x, GLfloat y, GLfloat radius){
    glDisable(GL_LIGHTING);
    glDisable(GL_TEXTURE_2D);
    int i;
    int triangleAmount = 20; //# of triangles used to draw circle

    //GLfloat radius = 0.8f; //radius
    GLfloat twicePi = 2.0f * 3.1415;

    glBegin(GL_TRIANGLE_FAN);
    glColor3f(1.0, 0.0, 0.0);
        glVertex2f(x, y); // center of circle
        for(i = 0; i <= triangleAmount;i++) {
            glVertex2f(
                    x + (radius * cos(i *  twicePi / triangleAmount)),
                y + (radius * sin(i * twicePi / triangleAmount))
            );
        }
    glEnd();
    glEnable(GL_LIGHTING);
    glEnable(GL_TEXTURE_2D);
}

So I don't know if I have to change the DrawPoint function.

UPDATE : this is my main source

 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInit(&argc, argv);
    glutInitWindowSize(widthX, heightY);
    glutCreateWindow("prg");
    glutReshapeFunc(resize);
    glutDisplayFunc(Draw);
    glutKeyboardFunc(keyPressed);
    glutKeyboardUpFunc(keyUp);
    texture[0] = SOIL_load_OGL_texture 
    (
        "img.jpg",
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
    );
    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glEnable(GL_TEXTURE_2D);
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glEnable(GL_POINT_SMOOTH);
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    glutMainLoop();

UPDATE 2 :

if in this way is impossible, is there a method that transform an x and y into a vector ?, so for example :

DrawPoint(VectConvert(50),VectConvert(100),0.01f);

I am not sure if this is right answer. I edited your code, try this:

static void Draw(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // You divided your window width and height by 300 which seems to be wrong
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // Create ortho 2d
    // The last two parameters are near and far planes
    // Since you are using only 2D you should keep them at 0.0 and 1.0
    glOrtho( -1 * w/2.0, 1 * w/2.0, -1 * h/2.0, 1 * h/2.0, 0.0f, 1.0f);
    // Mirror Y axis 
    glScalef(1, -1, 1);
    // Now your coordinate system starts at center of your window
    // You need to move it to the left top corner
    glTranslatef(-(w/2.0f), -(h/2.0f), 0.0f);

    texture[0] = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
    (
        "img.jpg",
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
    );

    glBindTexture(GL_TEXTURE_2D, texture[0]);
    glBegin(GL_POLYGON);
    // You need also to mirror your Y coordinates for texture
    glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f , 0.0f, 0.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(w    , 0.0f, 0.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(w    , h   , 0.0f);
    glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f , h   , 0.0f);
    glEnd();
    drawPoint(50 , 100 ,  0.01f);
    glutSwapBuffers();
}

Also, do not load your texture from file every frame. It is overkill for your GPU.

Just set an ortogonal projection as you need it:

 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 glOrtho( 0, w, h, 0, -1, 1);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();

Please note a few things here:

  • This assumes that w and h are actually the width and height of your viewport.
  • I put this into the GL_PROJECTION matrix. That is where this stuff belongs. (Although it might not be critical in your use case).
  • I set the near and far planes to -1 and 1 respectively. I don't know what you actually will need, but your values didn't make any sense.
  • That will set up a coordinate system where the pixel centers are actually exactly between two integer values, and integer values denote the middle between two adjacent pixels, so (0,0) will be the top left corner of the top left pixel, and (w,h) the bottom right corner of the bottom left pixel.
  • You also could set up a mapping that maps the integers to the pixel centers, like glOrtho(-0.5, w-0.5, h-0.5, -0.5, -1, 1) . Now (0,0) is the center of the top left pixel, and (w,h) is outside the screen, (w-1,h-1) is the center of the bottom right pixel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM