Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何将简单的opengl线条绘制代码转换为使用顶点数组_C_Opengl_Glut - Fatal编程技术网

C 如何将简单的opengl线条绘制代码转换为使用顶点数组

C 如何将简单的opengl线条绘制代码转换为使用顶点数组,c,opengl,glut,C,Opengl,Glut,我用C编写了一个简单的opengl应用程序,它绘制了sin(x)。这是我当前的draw函数,运行速度非常慢。如何转换此代码以使用更快的“顶点数组”模式 使用的变量和函数列表: N=总点数 x1=最小值(x) x2=最大值(x) y1=最小值(y) y2=最大值(y) func(x)=sin(x) 下面是完整的代码: /* to compile, do: $ gcc -o out simple.c -lglut */ #include <stdio.h> #include

我用C编写了一个简单的opengl应用程序,它绘制了sin(x)。这是我当前的
draw
函数,运行速度非常慢。如何转换此代码以使用更快的“顶点数组”模式

使用的变量和函数列表:

  • N=总点数
  • x1=最小值(x)
  • x2=最大值(x)
  • y1=最小值(y)
  • y2=最大值(y)
  • func(x)=sin(x)
下面是完整的代码:

/* to compile, do:

 $ gcc -o out simple.c -lglut

*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <time.h>

float xmin = -10, xmax = 10, ymin = -5, ymax = 5;
int nPoints = 3000;

/* function to calculate each data point */
float func(float x)
{
    return sin(x);
}

/* plotting function - very slow */
void draw(float (* func)(float x), float x1, float x2, float y1, float y2, int N)
{
    float x, dx = 1.0/N;

    glPushMatrix(); 

    glScalef(1.0 / (x2 - x1), 1.0 / (y2 - y1), 1.0);
    glTranslatef(-x1, -y1, 0.0);
    glColor3f(1.0, 1.0, 1.0);

    glBegin(GL_LINE_STRIP);

    for(x = x1; x < x2; x += dx)
    {
        glVertex2f(x, func(x));
    }

    glEnd();

    glPopMatrix();
};

/* Redrawing func */
void redraw(void)
{

    clock_t start = clock();
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // -x, +x, -y, +y, number points

    draw(func, xmin, xmax, ymin, ymax, nPoints);

    glutSwapBuffers();
    printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);
};

/* Idle proc. Redisplays, if called. */
void idle(void)
{
    // shift 'xmin' & 'xmax' by one.
    xmin++; 
    xmax++;
    glutPostRedisplay();
};

/* Key press processing */
void key(unsigned char c, int x, int y)
{
    if(c == 27) exit(0);
};

/* Window reashape */
void reshape(int w, int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 1, 0, 1, -1, 1);
    glMatrixMode(GL_MODELVIEW);
};

/* Main function */
int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutCreateWindow("Graph plotter");
    glutReshapeWindow(1024, 800);
    glutPostRedisplay(); // This call may or may not be necessary


    /* Register GLUT callbacks. */
    glutDisplayFunc(redraw);
    glutKeyboardFunc(key);
    glutReshapeFunc(reshape);

    glutIdleFunc(idle);

    /* Init the GL state */
    glLineWidth(2.0);

    /* Main loop */
    glutMainLoop();
    return 0;
}
/*要编译,请执行以下操作:
$gcc-o out simple.c-lglut
*/
#包括
#包括
#包括
#包括
#包括
浮点xmin=-10,xmax=10,ymin=-5,ymax=5;
int nPoints=3000;
/*函数来计算每个数据点*/
浮点函数(浮点x)
{
返回sin(x);
}
/*绘图功能-非常慢*/
无效绘制(浮点(*func)(浮点x),浮点x1,浮点x2,浮点y1,浮点y2,整数N)
{
浮点数x,dx=1.0/N;
glPushMatrix();
glScalef(1.0/(x2-x1)、1.0/(y2-y1)、1.0);
glTranslatef(-x1,-y1,0.0);
GL3F(1.0,1.0,1.0);
glBegin(GL_线_带);
对于(x=x1;x
在结构/功能方面:

// shared
vector pts;
vector_init( &pts, sizeof( float ) );

// whenever x1, x2, or N changes
vector_cleanup( &pts );
float x, dx = 1.0/N;
for(x = x1; x < x2; x += dx)
{
    vector_resize( &pts, pts.size + 2 );
    *(float*)vector_get( &pts, pts.size-2 ) = x;
    *(float*)vector_get( &pts, pts.size-1 ) = func(x);
}

// whenever you want to draw
glPushMatrix();

glScalef(1.0 / (x2 - x1), 1.0 / (y2 - y1), 1.0);
glTranslatef(-x1, -y1, 0.0);
glColor3f(1.0, 1.0, 1.0);

glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 2, GL_FLOAT, 0, (float*)pts.data );
glDrawArrays( GL_LINE_STRIP, 0, pts.size / 2 );
glDisableClientState( GL_VERTEX_ARRAY );

glPopMatrix();
//共享
向量pts;
向量_init(&pts,sizeof(float));
//每当x1、x2或N发生变化时
向量_清理(&pts);
浮点数x,dx=1.0/N;
对于(x=x1;x
编辑:完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <time.h>

typedef struct vector /*dynamic vector of void* pointers. This one is used only by the deflate compressor*/
{
  void* data;
  size_t size; /*in groups of bytes depending on type*/
  size_t allocsize; /*in bytes*/
  unsigned typesize; /*sizeof the type you store in data*/
} vector;

static unsigned vector_resize(vector* p, size_t size) /*returns 1 if success, 0 if failure ==> nothing done*/
{
  if(size * p->typesize > p->allocsize)
  {
    size_t newsize = size * p->typesize * 2;
    void* data = realloc(p->data, newsize);
    if(data)
    {
      p->allocsize = newsize;
      p->data = data;
      p->size = size;
    }
    else return 0;
  }
  else p->size = size;
  return 1;
}

static void vector_cleanup(void* p)
{
  ((vector*)p)->size = ((vector*)p)->allocsize = 0;
  free(((vector*)p)->data);
  ((vector*)p)->data = NULL;
}

static void vector_init(vector* p, unsigned typesize)
{
  p->data = NULL;
  p->size = p->allocsize = 0;
  p->typesize = typesize;
}

static void* vector_get(vector* p, size_t index)
{
  return &((char*)p->data)[index * p->typesize];
}

float xmin = -10, xmax = 10, ymin = -5, ymax = 5;
int nPoints = 3000;
vector pts;

/* function to calculate each data point */
float func(float x)
{
    return sin(x);
}

void update(float (* func)(float x), float x1, float x2, int N)
{
    float x, dx = 1.0/N;
    vector_cleanup( &pts );
    for(x = x1; x < x2; x += dx)
    {
        vector_resize( &pts, pts.size + 2 );
        *(float*)vector_get( &pts, pts.size-2 ) = x;
        *(float*)vector_get( &pts, pts.size-1 ) = func(x);
    }
}

/* plotting function - very slow */
void draw(float x1, float x2, float y1, float y2)
{
    glPushMatrix(); 

    glScalef(1.0 / (x2 - x1), 1.0 / (y2 - y1), 1.0);
    glTranslatef(-x1, -y1, 0.0);
    glColor3f(1.0, 1.0, 1.0);

    if( pts.size > 0 )
    {
        glEnableClientState( GL_VERTEX_ARRAY );
        glVertexPointer( 2, GL_FLOAT, 0, (float*)pts.data );
        glDrawArrays( GL_LINE_STRIP, 0, pts.size / 2 );
        glDisableClientState( GL_VERTEX_ARRAY );
    }

    glPopMatrix();
};

/* Redrawing func */
void redraw(void)
{
    clock_t start = clock();
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // -x, +x, -y, +y, number points
    draw(xmin, xmax, ymin, ymax);

    glutSwapBuffers();
    printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);
};

/* Idle proc. Redisplays, if called. */
void idle(void)
{
    // shift 'xmin' & 'xmax' by one.
    xmin++; 
    xmax++;

    update(func, xmin, xmax, nPoints);

    glutPostRedisplay();
};

/* Key press processing */
void key(unsigned char c, int x, int y)
{
    if(c == 27) exit(0);
};

/* Window reashape */
void reshape(int w, int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 1, 0, 1, -1, 1);
    glMatrixMode(GL_MODELVIEW);
};

/* Main function */
int main(int argc, char **argv)
{
    vector_init( &pts, sizeof( float ) );

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutCreateWindow("Graph plotter");
    glutReshapeWindow(1024, 800);
    glutPostRedisplay(); // This call may or may not be necessary


    /* Register GLUT callbacks. */
    glutDisplayFunc(redraw);
    glutKeyboardFunc(key);
    glutReshapeFunc(reshape);

    glutIdleFunc(idle);

    /* Init the GL state */
    glLineWidth(2.0);

    /* Main loop */
    glutMainLoop();
    return 0;
}
#包括
#包括
#包括
#包括
#包括
typedef struct vector/*void*指针的动态向量。这一个仅由放气压缩机使用*/
{
作废*数据;
大小\u t size;/*以字节为单位,具体取决于类型*/
大小\u t allocsize;/*以字节为单位*/
未签名的typesize;/*存储在数据中的类型的大小*/
}载体;
静态无符号向量_resize(vector*p,size\t size)/*如果成功返回1,如果失败返回0==>未执行任何操作*/
{
如果(大小*p->typesize>p->allocsize)
{
size\u t newsize=size*p->typesize*2;
void*data=realloc(p->data,newsize);
如果(数据)
{
p->allocsize=newsize;
p->data=数据;
p->size=size;
}
否则返回0;
}
否则p->size=size;
返回1;
}
静态空心向量_清理(空心*p)
{
((向量*)p)->大小=((向量*)p)->allocsize=0;
自由(((向量*)p)->数据);
((向量*)p)->数据=NULL;
}
静态void vector_init(vector*p,无符号字体大小)
{
p->data=NULL;
p->size=p->allocsize=0;
p->typesize=typesize;
}
静态void*vector\u get(vector*p,size\u t索引)
{
返回((char*)p->data)[index*p->typesize];
}
浮点xmin=-10,xmax=10,ymin=-5,ymax=5;
int nPoints=3000;
向量pts;
/*函数来计算每个数据点*/
浮点函数(浮点x)
{
返回sin(x);
}
无效更新(浮点(*func)(浮点x),浮点x1,浮点x2,整数N)
{
浮点数x,dx=1.0/N;
向量_清理(&pts);
对于(x=x1;x0)
{
glEnableClientState(GL_顶点_数组);
glVertexPointer(2,GL_浮点,0,(浮点*)pts.data);
GLDRAW阵列(GL_线_带,0,pts.size/2);
glDisableClientState(GL_顶点_数组);
}
glPopMatrix();
};
/*重绘函数*/
作废重画(作废)
{
时钟启动=时钟();
glClearColor(0,0,0,0);
glClear(GLU颜色缓冲位);
glMatrixMode(GLU模型视图);
glLoadIdentity();
//-x,+x,-y,+y,点数
绘制(xmin,xmax,ymin,ymax);
glutSwapBuffers();
printf(“经过的时间:%f\n”,((双)时钟()-开始)/每秒时钟数);
};
/*空闲进程。重新显示,如果调用*/
无效空闲(无效)
{
//将“xmin”和“xmax”移位一。
xmin++;
xmax++;
更新(func、xmin、xmax、nPoints);
再发现();
};
/*按键程序