在OpenGL中,一行在绘制另一行后消失

时间:2015-07-03 19:42:58

标签: opengl

在OpenGL中,我正在尝试实施Bresenham的Line算法。

首先,我正在绘制双轴线。然后绘制给定的线。但完成绘图后水平轴消失

我正在绘制轴,如下所示:

for (int i = -300; i<=300; i++)
    setPixel(0,i),setPixel(i,0);

查看我的完整代码:

/**
 * Implementation of Bresenham's Algorithm
 *
 * Written by Enamul Hassan July 2015
 *
 * This program draws a line having two pixel co-ordinate
 * using Bresenham's line Algorithm.
 *
 */
#include <windows.h>

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <cstring>
#include <sstream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cctype>
using namespace std;

/* Program entry point */
double x1, y1, x2, y2;


/**
 * setPixel(int,int) - This function mainly sets the pixel at the
 *                     co-ordinate (x,y) on the OpenGL screen.
 */
void setPixel(int x, int y)
{   /**
     * glBegin(GLbitfield mask) - delimit the vertices of a primitive or
     *                            a group of like primitives
     *
     * GL_POINTS - Treats each vertex as a single point.
     *             Vertex n defines point n. N points are drawn.
     */
    glBegin(GL_POINTS);
    /**
     * glVertex2f(float,float) - This function takes two floating
     *                           point values of co-ordinate and
     *                           set the point.
     */
    glVertex2f(x,y);

    /**
     * Sleep(int) - wait time in milliseconds. It is for distinguish
     *              two operations.
     */
//    Sleep(5);

    /**
     * glEnd() - end of the environment created by glBegin(int)
     */
    glEnd();

    /**
     * glutSwapBuffers() -  swaps the buffers of the current window
     *                      if double buffered
     */
    glutSwapBuffers();
}

void bresenham_algo(void)
{
    /**
     * glClear(GLbitfield mask) — clear buffers to preset values
     * GL_COLOR_BUFFER_BIT - Indicates the buffers currently
     *                       enabled for color writing
     * GL_DEPTH_BUFFER_BIT - Indicates the depth buffer
     */
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    /**
     * void glColor3d(GLdouble red, GLdouble green, GLdouble blue) -
     *          set RGB color.
     */
    glColor3d(1,0,0); // cyan color
    for (int i = -350; i<=350; i++)
        setPixel(0,i),setPixel(i,0);

    glColor3d(0,1,1); // cyan color

    ///Main algorithm

    int x1prime = x1+0.5;
    int x2prime = x2+0.5;
    int y1prime = y1+0.5;
    int y2prime = y2+0.5;

    double m = (y2-y1)/(x2-x1);

    if(!(0<=m && m<=1))
    {
        printf("m should be in range of 0 to 1.\n");
        printf("To get the mirrored counter part, swap the co-ordinates accordingly.\n");
        exit(0);
        return;
    }


    int x = x1prime, y = y1prime;
    int dx = x2prime - x1prime, dy = y2prime - y1prime, dT = 2*(dy-dx), dS = 2*dy;
    int d = 2*dy - dx;
    setPixel(x,y);

    while(x<x2prime)
    {
        x++;
        if(d<0) d+=dS;
        else y++,d+=dT;
        setPixel(x,y);
    }
    glutSwapBuffers();
}


int main(int argc, char *argv[])
{
    /**
     * glutInit(int, char*) - initializes glut environment.
     */
    glutInit(&argc, argv);
    /**
     * glutInitWindowSize(int,int)- initializes new glut window of
     *                              size W * H
     *                              default: 300, 300
     */
    glutInitWindowSize(700,700);
    /**
     * glutInitWindowPosition(int,int) - set the origin of the
     *                                   co-ordinate
     *                                   default: -1, -1
     */
    glutInitWindowPosition(10,10);

    /**
     * glutInitDisplayMode(unsigned int) - set the initial display mode.
     *                      It can take a combinations of some masks
     *                      which are not overlapped in their binary
     *                      representation. So, it takes them having
     *                      bitwise OR.
     * GLUT_RGB - the color input would by set by RGB values.
     * GLUT_DOUBLE - makes it double buffered. It is like using two blackboard.
     *               One blackboard would be shown to the screen and hidden one
     *               would be processed behind. they can be swapped any time.
     * GLUT_DEPTH - It is mainly enables depth concept. Algorithm like z-buffering
     *              could be done by using this.
     */
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

    /**
     * glutCreateWindow(char*) - creates a top-level window having the title
     *                           given as parameter.
     */
    glutCreateWindow("Brasenham's Algorithm for Line Drawing");

    /**
     * gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top) -
     *                              define a 2D orthographic projection matrix
     */
    gluOrtho2D(-350,350,-350,350);
    printf("Give the input as: \"x1 y1 x2 y2\" - ");

    scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
    if(x1>x2) swap(x1,x2), swap(y1,y2);

    /**
     * void glutDisplayFunc(void (*func)(void))  - this function takes a function pointer
     *                                             in which all works done.
     */
    glutDisplayFunc(bresenham_algo);

    /**
     * glutMainLoop() - enters the GLUT event processing loop. This routine should be
     *                  called at most once in a GLUT program. Once called, this routine
     *                  will never return. It will call as necessary any callbacks that
     *                  have been registered.
     */
    glutMainLoop();


    return EXIT_SUCCESS;
}

解决方案是什么?

1 个答案:

答案 0 :(得分:3)

主要问题是您在glutSwapBuffers功能中呼叫setPixel

交换缓冲区意味着当前“后退”缓冲区(通常是您正在绘制的缓冲区)将成为“前”缓冲区,即用户显示的缓冲区。在过去,这也意味着前缓冲区成为后台缓冲区,因此称为“交换”。但是,在现代,GL实现可能会使用更多缓冲区,并在其认为合适时分配新缓冲区。从技术上讲,在调用SwapBuffers() 后,后台缓冲区的内容将变为未定义。

所以你需要做的是:

绘制您想要呈现给用户的完整图像,然后进行一次缓冲交换。然后,从头开始绘制一个全新的框架。您不能只重复绘制单个像素,睡眠和交换,并假设这会导致正在渲染的线条的动画。您必须以动画的步骤重新编写应用程序循环,正在渲染完整的帧。