我適應您的代碼位:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float aspect=float(xs)/float(ys);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0/aspect,aspect,0.1,100.0);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
int e;
float x0=60.0,y0=40.0,r=20.0,a,da=M_PI/36.0;
// move modelview to center of shape
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-x0,-y0,-4.0*r);
// render disc
glColor3f(1.0,0.0,0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(x0,y0);
for (e=1,a=0.0;e;a+=da)
{
if (a>=2.0*M_PI) { e=0; a=0.0; }
glVertex2f(x0+(r*sin(a)),y0+(r*cos(a)));
}
glEnd();
// rotation symetry construct
glMatrixMode(GL_MODELVIEW); // store matrix in case you need it later or
glPushMatrix();
for (e=8,a=360.0/float(e);e>0;e--)
{
// render shape
glColor3f(0.0,0.0,1.0);
glBegin(GL_POLYGON);
glVertex2i(55, 75);
glVertex2i(60, 85);
glVertex2i(65, 75);
glVertex2i(61, 50);
glVertex2i(59, 50);
glEnd();
glBegin(GL_POLYGON);
glVertex2i(65, 72);
glVertex2i(66, 69);
glVertex2i(62, 50);
glVertex2i(61, 50);
glEnd();
glBegin(GL_POLYGON);
glVertex2i(54, 70);
glVertex2i(55, 72);
glVertex2i(59, 50);
glVertex2i(58, 50);
glEnd();
glMatrixMode(GL_MODELVIEW);
// rotate around(x0,y0)
glTranslatef(+x0,+y0,0.0);
glRotatef(a,0.0,0.0,1.0);
glTranslatef(-x0,-y0,0.0);
}
glMatrixMode(GL_MODELVIEW); // restore matrix in case you need it later or
glPopMatrix();
glFlush();
SwapBuffers(hdc);
所以我添加for
環和周圍形狀中心轉動它。這導致:
的xs,ys
是透視相機設置我的窗口的分辨率和hdc
是我的上下文。另外,我發現在交換緩衝區之後我打電話給flush
。
[EDIT1]全碼
我使用BDS2006 C++所以代碼使用VCL(只用於創建窗口和事件)沒有GLUT或任何部分,你必須改變,以符合您平臺...該應用程序只是單一的清潔表單上有一個定時器。
//---------------------------------------------------------------------------
#include <vcl.h> // you can ignore this
#include <math.h>
#pragma hdrstop // you can ignore this
#include "Unit1.h" // you can ignore this
#include "gl_simple.h" // this file is in next code chunk
//---------------------------------------------------------------------------
#pragma package(smart_init) // you can ignore this
#pragma resource "*.dfm" // you can ignore this
TForm1 *Form1; // you can ignore this its is just my window class
//---------------------------------------------------------------------------
void gl_draw() // this renders the scene
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float aspect=float(xs)/float(ys);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0/aspect,aspect,0.1,100.0);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
int e;
float x0=60.0,y0=40.0,r=20.0,a,da=M_PI/36.0;
// move modelview to center of shape
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-x0,-y0,-4.0*r);
// render disc
glColor3f(1.0,0.0,0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(x0,y0);
for (e=1,a=0.0;e;a+=da)
{
if (a>=2.0*M_PI) { e=0; a=0.0; }
glVertex2f(x0+(r*sin(a)),y0+(r*cos(a)));
}
glEnd();
// rotation symetry construct
glMatrixMode(GL_MODELVIEW); // store matrix in case you need it later or
glPushMatrix();
for (e=8,a=360.0/float(e);e>0;e--)
{
// render shape
glColor3f(0.0,0.0,1.0);
glBegin(GL_POLYGON);
glVertex2i(55, 75);
glVertex2i(60, 85);
glVertex2i(65, 75);
glVertex2i(61, 50);
glVertex2i(59, 50);
glEnd();
glBegin(GL_POLYGON);
glVertex2i(65, 72);
glVertex2i(66, 69);
glVertex2i(62, 50);
glVertex2i(61, 50);
glEnd();
glBegin(GL_POLYGON);
glVertex2i(54, 70);
glVertex2i(55, 72);
glVertex2i(59, 50);
glVertex2i(58, 50);
glEnd();
glMatrixMode(GL_MODELVIEW);
// rotate around(x0,y0)
glTranslatef(+x0,+y0,0.0);
glRotatef(a,0.0,0.0,1.0);
glTranslatef(-x0,-y0,0.0);
}
glMatrixMode(GL_MODELVIEW); // restore matrix in case you need it later or
glPopMatrix();
glFlush();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner) // constructor of my window
{
gl_init(Handle);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender) // destructor of my window
{
gl_exit();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender) // OnPaint event
{
gl_draw();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender) // OnTimer event
{
gl_draw();
}
//---------------------------------------------------------------------------
的gl_simple.h只是用於創建GL背景下,所以你可以忽略VAO和GLSL東西。這裏的源文件:
//---------------------------------------------------------------------------
#define GLEW_STATIC
#include "glew.c"
#include <gl\gl.h>
#include <gl\glu.h>
//---------------------------------------------------------------------------
//--- OpenGL GL example -----------------------------------------------------
//---------------------------------------------------------------------------
int xs,ys; // screen size
HDC hdc=NULL; // device context
HGLRC hrc=NULL; // rendering context
int gl_inicialized=0;
int gl_init(HWND Handle);
void gl_exit();
void gl_draw();
void gl_resize(int _xs,int _ys);
//---------------------------------------------------------------------------
//--- OpenGL GLSL example ---------------------------------------------------
//---------------------------------------------------------------------------
GLint prog_id=0, // whole program
vert_id=0, // vertex shader
frag_id=0; // fragment shader
char glsl_log[4096];// compile/link GLSL log
int glsl_logs=0;
void glsl_init(char *vert,char *frag); // create/compile/link GLSL program
void glsl_exit();
//---------------------------------------------------------------------------
//--- OpenGL VAO example ----------------------------------------------------
//---------------------------------------------------------------------------
#pragma pack(1)
//#define vao_indices
GLuint vbo[4]={-1,-1,-1,-1};
GLuint vao[4]={-1,-1,-1,-1};
const GLfloat vao_pos[]=
{
// x y z //ix
-1.0,-1.0,-1.0, //0
+1.0,-1.0,-1.0, //1
+1.0,+1.0,-1.0, //2
-1.0,+1.0,-1.0, //3
-1.0,-1.0,+1.0, //4
+1.0,-1.0,+1.0, //5
+1.0,+1.0,+1.0, //6
-1.0,+1.0,+1.0, //7
#ifndef vao_indices
-1.0,-1.0,-1.0, //0
+1.0,-1.0,-1.0, //1
+1.0,-1.0,+1.0, //5
-1.0,-1.0,+1.0, //4
+1.0,-1.0,-1.0, //1
+1.0,+1.0,-1.0, //2
+1.0,+1.0,+1.0, //6
+1.0,-1.0,+1.0, //5
+1.0,+1.0,-1.0, //2
-1.0,+1.0,-1.0, //3
-1.0,+1.0,+1.0, //7
+1.0,+1.0,+1.0, //6
-1.0,+1.0,-1.0, //3
-1.0,-1.0,-1.0, //0
-1.0,-1.0,+1.0, //4
-1.0,+1.0,+1.0, //7
#endif
};
const GLfloat vao_col[]=
{
// r g b //ix
0.0,0.0,0.0, //0
1.0,0.0,0.0, //1
1.0,1.0,0.0, //2
0.0,1.0,0.0, //3
0.0,0.0,1.0, //4
1.0,0.0,1.0, //5
1.0,1.0,1.0, //6
0.0,1.0,1.0, //7
#ifndef vao_indices
0.0,0.0,0.0, //0
1.0,0.0,0.0, //1
1.0,0.0,1.0, //5
0.0,0.0,1.0, //4
1.0,0.0,0.0, //1
1.0,1.0,0.0, //2
1.0,1.0,1.0, //6
1.0,0.0,1.0, //5
1.0,1.0,0.0, //2
0.0,1.0,0.0, //3
0.0,1.0,1.0, //7
1.0,1.0,1.0, //6
0.0,1.0,0.0, //3
0.0,0.0,0.0, //0
0.0,0.0,1.0, //4
0.0,1.0,1.0, //7
#endif
};
#ifndef vao_indices
const GLfloat vao_nor[]=
{
// nx ny nz //ix
0.0, 0.0,-1.0, //0
0.0, 0.0,-1.0, //1
0.0, 0.0,-1.0, //2
0.0, 0.0,-1.0, //3
0.0, 0.0,+1.0, //4
0.0, 0.0,+1.0, //5
0.0, 0.0,+1.0, //6
0.0, 0.0,+1.0, //7
0.0,-1.0, 0.0, //0
0.0,-1.0, 0.0, //1
0.0,-1.0, 0.0, //5
0.0,-1.0, 0.0, //4
+1.0, 0.0, 0.0, //1
+1.0, 0.0, 0.0, //2
+1.0, 0.0, 0.0, //6
+1.0, 0.0, 0.0, //5
0.0,+1.0, 0.0, //2
0.0,+1.0, 0.0, //3
0.0,+1.0, 0.0, //7
0.0,+1.0, 0.0, //6
-1.0, 0.0, 0.0, //3
-1.0, 0.0, 0.0, //0
-1.0, 0.0, 0.0, //4
-1.0, 0.0, 0.0, //7
};
#endif
#ifdef vao_indices
const GLuint vao_ix[]=
{
0,1,2,3,
4,5,6,7,
0,1,5,4,
1,2,6,5,
2,3,7,6,
3,0,4,7,
};
#endif
#pragma pack()
void vao_init();
void vao_exit();
void vao_draw();
//---------------------------------------------------------------------------
//--- bodies: ---------------------------------------------------------------
//---------------------------------------------------------------------------
int gl_init(HWND Handle)
{
if (gl_inicialized) return 1;
hdc = GetDC(Handle); // get device context
PIXELFORMATDESCRIPTOR pfd;
ZeroMemory(&pfd, sizeof(pfd)); // set the pixel format for the DC
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 24;
pfd.iLayerType = PFD_MAIN_PLANE;
SetPixelFormat(hdc,ChoosePixelFormat(hdc, &pfd),&pfd);
hrc = wglCreateContext(hdc); // create current rendering context
if(hrc == NULL)
{
ShowMessage("Could not initialize OpenGL Rendering context !!!");
gl_inicialized=0;
return 0;
}
if(wglMakeCurrent(hdc, hrc) == false)
{
ShowMessage("Could not make current OpenGL Rendering context !!!");
wglDeleteContext(hrc); // destroy rendering context
gl_inicialized=0;
return 0;
}
gl_resize(1,1);
glEnable(GL_DEPTH_TEST); // Zbuf
glDisable(GL_CULL_FACE); // vynechavaj odvratene steny
glDisable(GL_TEXTURE_2D); // pouzivaj textury, farbu pouzivaj z textury
glDisable(GL_BLEND); // priehladnost
glShadeModel(GL_SMOOTH); // gourard shading
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // background color
gl_inicialized=1;
glewInit();
return 1;
}
//---------------------------------------------------------------------------
void gl_exit()
{
if (!gl_inicialized) return;
wglMakeCurrent(NULL, NULL); // release current rendering context
wglDeleteContext(hrc); // destroy rendering context
gl_inicialized=0;
}
//---------------------------------------------------------------------------
void gl_resize(int _xs,int _ys)
{
xs=_xs;
ys=_ys;
if (xs<=0) xs = 1; // Prevent a divide by zero
if (ys<=0) ys = 1;
if (!gl_inicialized) return;
glViewport(0,0,xs,ys); // Set Viewport to window dimensions
glMatrixMode(GL_PROJECTION); // operacie s projekcnou maticou
glLoadIdentity(); // jednotkova matica projekcie
gluPerspective(30,float(xs)/float(ys),0.1,100.0); // matica=perspektiva,120 stupnov premieta z viewsize do 0.1
glMatrixMode(GL_TEXTURE); // operacie s texturovou maticou
glLoadIdentity(); // jednotkova matica textury
glMatrixMode(GL_MODELVIEW); // operacie s modelovou maticou
glLoadIdentity(); // jednotkova matica modelu (objektu)
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void glsl_init(char *vert,char *frag)
{
const int _size=1024;
GLint status,siz=0,i;
const char * VS = vert;
const char * FS = frag;
glsl_logs=0;
if (prog_id<=0) prog_id=glCreateProgram();
if (vert_id<=0) vert_id=glCreateShader(GL_VERTEX_SHADER); else glDetachShader(prog_id,vert_id);
if (vert)
{
glShaderSource(vert_id, 1, &VS,NULL);
glCompileShader(vert_id);
glAttachShader(prog_id,vert_id);
glGetShaderiv(vert_id,GL_COMPILE_STATUS,&status);
const char t[]="[Vertex]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
glGetShaderInfoLog(vert_id,_size,&siz,glsl_log+glsl_logs);
glsl_logs+=siz;
}
if (frag_id<=0) frag_id=glCreateShader(GL_FRAGMENT_SHADER); else glDetachShader(prog_id,frag_id);
if (frag)
{
glShaderSource(frag_id, 1, &FS,NULL);
glCompileShader(frag_id);
glAttachShader(prog_id,frag_id);
glGetShaderiv(frag_id,GL_COMPILE_STATUS,&status);
const char t[]="[Fragment]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
glGetShaderInfoLog(frag_id,_size,&siz,glsl_log+glsl_logs);
glsl_logs+=siz;
}
glLinkProgram(prog_id);
glGetProgramiv(prog_id,GL_LINK_STATUS,&status);
const char t[]="[Program]\r\n"; for (i=0;t[i];i++) { glsl_log[glsl_logs]=t[i]; glsl_logs++; }
glGetShaderInfoLog(prog_id,_size,&siz,glsl_log+glsl_logs);
glsl_logs+=siz;
glReleaseShaderCompiler();
glsl_log[glsl_logs]=0;
}
//------------------------------------------------------------------------------
void glsl_exit()
{
glUseProgram(0);
if (vert_id>0) { glDetachShader(prog_id,vert_id); glDeleteShader(vert_id); }
if (frag_id>0) { glDetachShader(prog_id,frag_id); glDeleteShader(frag_id); }
if (prog_id>0) { glDeleteShader(prog_id); }
glsl_log[0]=0;
}
//---------------------------------------------------------------------------
//------------------------------------------------------------------------------
void vao_init()
{
GLuint i;
glGenVertexArrays(4,vao);
glGenBuffers(4,vbo);
glBindVertexArray(vao[0]);
i=0; // vertex
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_pos),vao_pos,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
i=1; // indices
#ifdef vao_indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(vao_ix),vao_ix,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,4,GL_UNSIGNED_INT,GL_FALSE,0,0);
#endif
i=2; // normal
#ifndef vao_indices
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_nor),vao_nor,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
#endif
i=3; // color
glBindBuffer(GL_ARRAY_BUFFER,vbo[i]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vao_col),vao_col,GL_STATIC_DRAW);
glEnableVertexAttribArray(i);
glVertexAttribPointer(i,3,GL_FLOAT,GL_FALSE,0,0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
}
//---------------------------------------------------------------------------
void vao_exit()
{
glDeleteVertexArrays(4,vao);
glDeleteBuffers(4,vbo);
}
//---------------------------------------------------------------------------
void vao_draw()
{
glBindVertexArray(vao[0]);
#ifndef vao_indices
glDrawArrays(GL_QUADS,0,sizeof(vao_pos)/sizeof(GLfloat)); // QUADS ... no indices
#endif
#ifdef vao_indices
glDrawElements(GL_QUADS,sizeof(vao_idx)/sizeof(GLuint),GL_UNSIGNED_INT,0); // indices (choose just one line not both !!!)
#endif
glBindVertexArray(0);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BTW該文件摘自:
的M_PI=3.1415926535897932384626433832795
是恆定
#include <math.h>
定義你應該已經包含在您正在使用的sin,cos
函數中。
的GLEW.c是OpenGL擴展牧馬人,當你只使用OpenGL的1.0你不需要它...但粗,一旦你刪除包括你也需要刪除這個文件中的所有VAO/VBO和GLSL的東西(這無論如何都不會使用)
你要填寫的多邊形或只是折線周長? – Spektre