2D shape in C++ by using the OpenGl library

孤人 提交于 2019-12-12 05:26:19

问题


I am trying to draw a shape in C++ by using the OpenGl library I've written the following code , but all what I achieved is the following shape ):

but do I need to use glRotatef to get this shape :? and how can I use it ?

this is my code :)

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

回答1:


I adapted your code a bit:

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

So I added for loop and the rotation around shape center to it. Here result:

The xs,ys is resolution of my window for the perspective camera settings and hdc is my context. Also I spotted that you call flush after swapping buffers I would call it before.

[Edit1] Full code

I am using BDS2006 C++ so the code uses VCL (just for creating window and events) no GLUT or anything That part you have to change to match your platform... The app is just single clean Form with single timer on it.

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

The gl_simple.h is just used for creating GL context so you can ignore the VAO and GLSL stuff. Here the source file:

//---------------------------------------------------------------------------
#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 this file is taken from:

  • complete GL+GLSL+VAO/VBO C++ example

The M_PI=3.1415926535897932384626433832795 is constant defined in

#include <math.h> 

Which you should have already included as you are using sin,cos functions from it.

The GLEW.c is wrangler for OpenGL extensions and as you using just OpenGL 1.0 you do not need it ... but of coarse once you remove the include you need to delete also all VAO/VBO and GLSL stuff from this file (which is not used anyway)



来源:https://stackoverflow.com/questions/43576668/2d-shape-in-c-by-using-the-opengl-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!