最简单的方法是使用旧式 GL api
const int sz=400; // window resolution
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-1.0,-1.0,0.0);
glScalef(2.0/float(sz),2.0/float(sz),0.0);
glBegin(GL_POINTS);
glColor3f(1.0,1.0,1.0);
glVertex2i(x0,y0);
glVertex2i(x1,y1);
glVertex2i(x2,y2);
...
glEnd();
glFinish();
SwapBuffers(hdc);
但这仅适用于兼容性配置文件或旧 GL 实施。
对于新的东西,您需要创建一个点列表来渲染集合 VAO/VBOs 并使用 glDrawArrays/glDrawElements 和 GL_POINT 样式和粗糙你需要使用着色器。在这里查看完整的立方体示例:
为了让这两种方法的示例更简单(选择注释或取消注释 _gl_old 定义),仅使用一些随机点和非常简单的着色器(期望 400x400 窗口和 [像素] 单位的点)使用 gl_simple.h来自上一个链接:
//---------------------------------------------------------------------------
#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include "Unit1.h"
#include "gl_simple.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
// this define determines if old or new stuff is used
//#define _gl_old
//---------------------------------------------------------------------------
const int sz=400; // window resolution
const int n=1024; // points
const int n2=n+n; // points*dimensions
GLint pnt[n2]; // points x,y ...
#ifndef _gl_old
GLuint pnt_vbo=-1;
GLuint pnt_vao=-1;
#endif
//---------------------------------------------------------------------------
void pnt_init()
{
// compute some points (your line algo should do it I use random instead)
Randomize();
for (int i=0;i<n2;i++) pnt[i]=Random(sz);
// the new stuff need VBO
#ifndef _gl_old
// create VAO/VBO
glGenVertexArrays(1,&pnt_vao);
glGenBuffers(1,&pnt_vbo);
glBindVertexArray(pnt_vao);
// points -> VBO
glBindBuffer(GL_ARRAY_BUFFER,pnt_vbo);
glBufferData(GL_ARRAY_BUFFER,sizeof(pnt),pnt,GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribIPointer(0,2,GL_INT,0,0);
// unbind VAO/VBO
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glDisableVertexAttribArray(0);
#endif
}
//---------------------------------------------------------------------------
void pnt_exit()
{
// the new stuff needs to release VBO/VAO
#ifndef _gl_old
glDeleteVertexArrays(1,&pnt_vao);
glDeleteBuffers(1,&pnt_vbo);
#endif
}
//---------------------------------------------------------------------------
void gl_draw()
{
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
// Old GL 1.0 stuff
#ifdef _gl_old
// set view to 2D in [pixels]
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-1.0,-1.0,0.0);
glScalef(2.0/float(sz),2.0/float(sz),0.0);
// render points froma list
glBegin(GL_POINTS);
glColor3f(1.0,1.0,1.0);
for (int i=0;i<n2;i+=2) glVertex2iv(pnt+i);
glEnd();
#endif
// New GL stuff
#ifndef _gl_old
glUseProgram(prog_id);
glBindVertexArray(pnt_vao);
glDrawArrays(GL_POINTS,0,sizeof(pnt)/sizeof(pnt[0]));
glBindVertexArray(0);
glUseProgram(0);
#endif
// glFlush();
glFinish();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
// Init of program
gl_init(Handle); // init OpenGL
pnt_init(); // init pooints and VAO/VBO
#ifndef _gl_old
// init shaders
char vertex[]="#version 330 core\r\nlayout(location=0) in ivec2 pos;\r\nvoid main(void) { vec2 p; p=vec2(pos); p-=200; p/=200.0; gl_Position=vec4(p,0.0,1.0); }";
char fragment[]="#version 330 core\r\nout vec4 col;\r\nvoid main() { col=vec4(1.0,1.0,1.0,1.0); }";
glsl_init(vertex,fragment);
int hnd=FileCreate("GLSL.txt"); FileWrite(hnd,glsl_log,glsl_logs); FileClose(hnd); // just write logs into file
#endif
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
// Exit of program
gl_exit();
pnt_exit();
#ifndef _gl_old
glsl_exit();
#endif
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
// repaint
gl_draw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
// resize
gl_resize(ClientWidth,ClientHeight);
}
//---------------------------------------------------------------------------
它是 OpenGL/VCL/C++,所以只需忽略 VCL(所有定义、编译指示、包括...除了 gl_simple.h 和 _gl_old)东西并在您的平台上模拟事件(重绘、初始化/退出、调整大小)。新旧风格的区别在于,你需要在渲染之前提前计算渲染的像素,并将它们存储到表/数组中。