gpt4 book ai didi

c - 如何将简单的 opengl 线图代码转换为使用顶点数组

转载 作者:太空宇宙 更新时间:2023-11-04 04:03:23 25 4
gpt4 key购买 nike

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

使用的变量和函数列表:

  • N = 总点数
  • x1 = min(x)
  • x2 = 最大值(x)
  • y1 = min(y)
  • y2 = 最大值(y)
  • 函数(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;
}

最佳答案

LodePNG's C-style vector方面结构/功能:

// 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();

编辑:完整代码:

#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;
}

关于c - 如何将简单的 opengl 线图代码转换为使用顶点数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9185200/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com