使用 OpenGl 库在 C++ 中生成 2D 形状
2D shape in C++ by using the OpenGl library
我正在尝试使用 OpenGl 库在 C++ 中绘制形状
我写了下面的代码,但我得到的只是下面的形状):
但是我需要使用 glRotatef 来获得这个形状吗:?我该如何使用它?
这是我的代码:)
#include <Windows.h>
#include <GL\glew.h>
#include <GL\freeglut.h>
#include <iostream>
#include <math.h>
using namespace std;
float angle, radius, xx1, yy1;
int main(int argc, char** argv) {
void Transform(void);
void circle(void);
void shape(void);
void init(void);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400, 300);
glutInitWindowPosition(50, 100);
glutCreateWindow("MyShape");
init();
glutDisplayFunc(Transform);
glutMainLoop();
return 0;
}
void init(void) {
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
void Transform(void){
void shape();
void circle();
shape();
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glColor3f(1, 0, 0);
glScalef(1.5, 1.5, 0);
circle();
shape();
glPopMatrix();
glutSwapBuffers();
glFlush();
}
void circle(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 0); /* draw filled red circle*/
xx1 = 60; yy1 = 40; radius = 20;
glBegin(GL_TRIANGLE_FAN);
for (angle = 0; angle <= 360; angle++)
glVertex2f(xx1 + sin(angle)*radius, yy1 + cos(angle)*radius);
glEnd();
glFlush();
}
void shape(void) {
// Main rectangle
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0, 0, 1);
glBegin(GL_POLYGON);
glVertex2i(55, 75);// left
glVertex2i(60, 85); // top center
glVertex2i(65, 75); // right
glVertex2i(61, 50);// buttom right
glVertex2i(59, 50);// buttom left
glEnd();
//rectangle right
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0, 0, 1);
glBegin(GL_POLYGON);
glVertex2i(65, 72);// top left
glVertex2i(66, 69); //top right
glVertex2i(62, 50); // buttom right
glVertex2i(61, 50); // buttom left
glEnd();
//rectangle left
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0, 0, 1);
glBegin(GL_POLYGON);
glVertex2i(54, 70);// top left
glVertex2i(55, 72); //top right
glVertex2i(59, 50); // buttom right
glVertex2i(58, 50); // buttom left
glEnd();
glFlush();
}
我稍微调整了你的代码:
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
是我的 window 透视相机设置的分辨率,hdc
是我的上下文。我还发现你在交换缓冲区后调用 flush
我之前会调用它。
[Edit1] 完整代码
我正在使用 BDS2006 C++ 因此代码使用 VCL(仅用于创建 window 和事件)没有 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 东西(这不是无论如何都用过)
我正在尝试使用 OpenGl 库在 C++ 中绘制形状 我写了下面的代码,但我得到的只是下面的形状):
但是我需要使用 glRotatef 来获得这个形状吗:?我该如何使用它?
这是我的代码:)
#include <Windows.h>
#include <GL\glew.h>
#include <GL\freeglut.h>
#include <iostream>
#include <math.h>
using namespace std;
float angle, radius, xx1, yy1;
int main(int argc, char** argv) {
void Transform(void);
void circle(void);
void shape(void);
void init(void);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400, 300);
glutInitWindowPosition(50, 100);
glutCreateWindow("MyShape");
init();
glutDisplayFunc(Transform);
glutMainLoop();
return 0;
}
void init(void) {
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
void Transform(void){
void shape();
void circle();
shape();
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glColor3f(1, 0, 0);
glScalef(1.5, 1.5, 0);
circle();
shape();
glPopMatrix();
glutSwapBuffers();
glFlush();
}
void circle(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 0); /* draw filled red circle*/
xx1 = 60; yy1 = 40; radius = 20;
glBegin(GL_TRIANGLE_FAN);
for (angle = 0; angle <= 360; angle++)
glVertex2f(xx1 + sin(angle)*radius, yy1 + cos(angle)*radius);
glEnd();
glFlush();
}
void shape(void) {
// Main rectangle
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0, 0, 1);
glBegin(GL_POLYGON);
glVertex2i(55, 75);// left
glVertex2i(60, 85); // top center
glVertex2i(65, 75); // right
glVertex2i(61, 50);// buttom right
glVertex2i(59, 50);// buttom left
glEnd();
//rectangle right
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0, 0, 1);
glBegin(GL_POLYGON);
glVertex2i(65, 72);// top left
glVertex2i(66, 69); //top right
glVertex2i(62, 50); // buttom right
glVertex2i(61, 50); // buttom left
glEnd();
//rectangle left
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(0, 0, 1);
glBegin(GL_POLYGON);
glVertex2i(54, 70);// top left
glVertex2i(55, 72); //top right
glVertex2i(59, 50); // buttom right
glVertex2i(58, 50); // buttom left
glEnd();
glFlush();
}
我稍微调整了你的代码:
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
是我的 window 透视相机设置的分辨率,hdc
是我的上下文。我还发现你在交换缓冲区后调用 flush
我之前会调用它。
[Edit1] 完整代码
我正在使用 BDS2006 C++ 因此代码使用 VCL(仅用于创建 window 和事件)没有 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 东西(这不是无论如何都用过)