注册 登录
编程论坛 C图形专区

关于opengl绘制圆角矩形,大小圆角要用不同的绘制方法

xyzdwf 发布于 2021-07-31 14:27, 1941 次点击
我是相邻像素去绘制,这样虽然在大圆角的时候比较圆润,但是到个位数圆角就感觉比较差,是不是圆角到个位数了就要用角度 sin cos去绘制比较好?
怎么做才比较完美

程序代码:

#define FREEGLUT_STATIC
#include <stdio.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glut.h>

/** type defines **/

/** props defines **/
static int wwidth = 0;
static int wheight = 0;
/** funs defines **/
void opengl_resize(int w, int h);
void opengl_mouse_event(int button,int state,int x,int y);

void opengl_drawrect( int x, int y, int w, int h, int r);
void opengl_fillrect(int x, int y, int w, int h, int r);

void opengl_display();
float opengl_onelizedA(int a);
float opengl_onelizedB(int b);


int main(int argc, char ** argv)
{
    glutInit(&argc, argv);
   
    glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
    glutInitWindowPosition(300, 200);
    glutInitWindowSize(1000, 700);
    glutCreateWindow("simple");
   
    glutDisplayFunc(opengl_display);
    glutReshapeFunc(opengl_resize);
    glutMouseFunc(opengl_mouse_event);
   
   
    glutMainLoop();
}

/** funs impl **/

void opengl_resize(int w, int h)
{
    glViewport(0, 0, w, h);
    wwidth = w;
    wheight = h;
    printf("window resize ... width=%d, height=%d\n", wwidth, wheight);
}
void opengl_mouse_event(int button,int state,int x,int y){
    printf("mouse_event running... button=%d, state=%d, x=%d, y=%d\n", button, state, x, y);
}

void opengl_drawrect(int x, int y, int w, int h, int r)
{
   
}

void opengl_fillrect(int x, int y, int w, int h, int r)
{
    glColor4f(1.0f, 0.0f, 0.0f, 0.1f);
    if(0 == r){
        glBegin(GL_POLYGON);
            glVertex2f(opengl_onelizedA(x), opengl_onelizedB(y+h));
            glVertex2f(opengl_onelizedA(x), opengl_onelizedB(y));
            glVertex2f(opengl_onelizedA(x+w), opengl_onelizedB(y));
            glVertex2f(opengl_onelizedA(x+w), opengl_onelizedB(y+h));
        glEnd();
        
    }else{
        glBegin(GL_POLYGON);
            glVertex2f(opengl_onelizedA(x+r), opengl_onelizedB(y+h));
            glVertex2f(opengl_onelizedA(x+r), opengl_onelizedB(y));
            glVertex2f(opengl_onelizedA(x+w-r), opengl_onelizedB(y));
            glVertex2f(opengl_onelizedA(x+w-r), opengl_onelizedB(y+h));
        glEnd();
        
        glBegin(GL_POLYGON);
            glVertex2f(opengl_onelizedA(x), opengl_onelizedB(y+h-r));
            glVertex2f(opengl_onelizedA(x), opengl_onelizedB(y+r));
            glVertex2f(opengl_onelizedA(x+w), opengl_onelizedB(y+r));
            glVertex2f(opengl_onelizedA(x+w), opengl_onelizedB(y+h-r));
        glEnd();
        for(int i=0; i<r; i++){
            glBegin(GL_TRIANGLES);
                glVertex2f(opengl_onelizedA(x+r), opengl_onelizedB(y+r));
                glVertex2f(opengl_onelizedA(x+i), opengl_onelizedB( y+(r-floor(sqrt(pow(r,2)-pow(r-i,2)))) ));
                glVertex2f(opengl_onelizedA(x+i+1), opengl_onelizedB( y+(r-floor(sqrt(pow(r,2)-pow(r-i-1,2)))) ));
            glEnd();
            glBegin(GL_TRIANGLES);
                glVertex2f(opengl_onelizedA(x+w-r), opengl_onelizedB(y+r));
                glVertex2f(opengl_onelizedA(x+w-r+i), opengl_onelizedB( y+r-ceil(sqrt(pow(r,2)-pow(i,2))) ));
                glVertex2f(opengl_onelizedA(x+w-r+i+1), opengl_onelizedB( y+r-ceil(sqrt(pow(r,2)-pow(i+1,2))) ));
            glEnd();
            glBegin(GL_TRIANGLES);
                glVertex2f(opengl_onelizedA(x+w-r), opengl_onelizedB(y+h-r));
                glVertex2f(opengl_onelizedA(x+w-r+i), opengl_onelizedB( y+h-r+ceil(sqrt(pow(r,2)-pow(i,2))) ));
                glVertex2f(opengl_onelizedA(x+w-r+i+1), opengl_onelizedB(y+h-r+ceil(sqrt(pow(r,2)-pow(i+1,2))) ));
            glEnd();
            glBegin(GL_TRIANGLES);
                glVertex2f(opengl_onelizedA(x+r), opengl_onelizedB(y+h-r));
                glVertex2f(opengl_onelizedA(x+i), opengl_onelizedB( y+h-r+floor(sqrt(pow(r,2)-pow(r-i,2))) ));
                glVertex2f(opengl_onelizedA(x+i+1), opengl_onelizedB( y+h-r+floor(sqrt(pow(r,2)-pow(r-i-1,2))) ));
            glEnd();
        }
        
    }
}

void opengl_display()
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
   
    opengl_fillrect(100, 100, 500, 500, 3);
   
   
    glFlush();


}


GLfloat opengl_onelizedA(int a)
{
    GLfloat m = a * 1.0;
    GLfloat n = wwidth * 1.0;
    return (2 * m / n) - 1;
}

GLfloat opengl_onelizedB(int b)
{
    GLfloat m = b * 1.0;
    GLfloat n = wheight * 1.0;
    return 1 - (2 * m / n);
}

8 回复
#2
我善治鬼2021-07-31 18:24
不知道是不是你想要的画圆角矩形效果, 每一个角度设置一个顶点, 可以设置角的宽度半径和高度半径

程序代码:


#include <stdio.h>
#include <math.h>
#include <Windows.h>
#include <GL/GL.h>
#pragma comment(lib, "OPENGL32.LIB")


#define pi        3.1415


void 画圆角矩形(double 左, double 顶, double 右, double 底, double 角宽, double 角高)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3ub(255, 255, 0);
    glBegin(GL_POLYGON);
    for (int i = 0; i < 90; i++) {
        double x = cos(i * pi / 180.0) * 角宽, y = sin(i * pi / 180.0) * 角高;
        glVertex2d(左 - x, 顶 - y);
        glVertex2d(右 + x, 顶 - y);
        glVertex2d(右 + x, 底 + y);
        glVertex2d(左 - x, 底 + y);
    }
    glEnd();
    glFlush();
}


int main()
{
    PIXELFORMATDESCRIPTOR pf = { 0 };
    HDC dc = GetDC(GetConsoleWindow());
    SetPixelFormat(dc, ChoosePixelFormat(dc, &pf), &pf);
    HGLRC rc = wglCreateContext(dc);
    wglMakeCurrent(dc, rc);
    glViewport(0, 0, 1000, 500);
    glOrtho(0, 1000, 500, 0, 100, -100);
    while (1) 画圆角矩形(100, 100, 200, 150, 30, 20);
    return 0;
}



只有本站会员才能查看附件,请 登录
#3
xyzdwf2021-07-31 18:55
回复 2楼 我善治鬼
用角度循环画,大圆角是不是会粗糙点,应为都是90份的画
另外圆角边框 有代码没,我只画了四条直边,圆角感觉也挺麻烦
只有本站会员才能查看附件,请 登录

程序代码:

void opengl_drawrect(int x, int y, int w, int h, int r)
{
    glColor4f(0.0f, 1.0f, 0.0f, 0.1f);
    if(0 == r){
        glBegin(GL_LINE_LOOP);
            glVertex2f(opengl_onelizedA(x), opengl_onelizedB(y+h));
            glVertex2f(opengl_onelizedA(x), opengl_onelizedB(y));
            glVertex2f(opengl_onelizedA(x+w), opengl_onelizedB(y));
            glVertex2f(opengl_onelizedA(x+w), opengl_onelizedB(y+h));
        glEnd();
    }else{
        int d = 1;
        glBegin(GL_LINES);
            glVertex2f(opengl_onelizedA(x+r), opengl_onelizedB(y));
            glVertex2f(opengl_onelizedA(x+w-r), opengl_onelizedB(y));
            glVertex2f(opengl_onelizedA(x+r), opengl_onelizedB(y+w));
            glVertex2f(opengl_onelizedA(x+w-r), opengl_onelizedB(y+w));
            glVertex2f(opengl_onelizedA(x), opengl_onelizedB(y+r));
            glVertex2f(opengl_onelizedA(x), opengl_onelizedB(y+w-r));
            glVertex2f(opengl_onelizedA(x+w), opengl_onelizedB(y+r));
            glVertex2f(opengl_onelizedA(x+w), opengl_onelizedB(y+w-r));
        glEnd();
        
    }
}




[此贴子已经被作者于2021-7-31 18:59编辑过]

#4
我善治鬼2021-07-31 19:32
将 glBegin(GL_POLYGON);
改为 glBegin(GL_LINE_LOOP);
就行了, 只是边框有点大
凑合用可以的
#5
xyzdwf2021-07-31 20:38
为什么啥也出不来
只有本站会员才能查看附件,请 登录

程序代码:

#define FREEGLUT_STATIC
#include <stdio.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glut.h>

/** type defines **/

/** props defines **/
static int wwidth = 1000;
static int wheight = 700;

/** funs defines **/
void opengl_display();
void opengl_resize(int w, int h);
void opengl_mouse_event(int button,int state,int x,int y);

void opengl_drawrect(int x, int y, int w, int h, int r);
void opengl_fillrect(int x, int y, int w, int h, int r);


int main(int argc, char ** argv)
{
    glutInit(&argc, argv);
   
    glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
    glutInitWindowPosition(300, 200);
    glutInitWindowSize(wwidth, wheight);
    glutCreateWindow("simple");
    glViewport(0, 0, wwidth, wheight);
    glOrtho(0, wwidth, wheight, 0, 100, -100);
   
    glutDisplayFunc(opengl_display);
    glutReshapeFunc(opengl_resize);
    glutMouseFunc(opengl_mouse_event);
   
   
    glutMainLoop();
}

/** funs impls **/

void opengl_display()
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
   
    opengl_fillrect(100, 100, 300, 200, 10);
    opengl_drawrect(400, 400, 200, 100, 10);
   
    glFlush();


}

void opengl_resize(int w, int h)
{
    glViewport(0, 0, w, h);
    glOrtho(0, w, h, 0, 100, -100);
    wwidth = w;
    wheight = h;
    printf("window resize ... width=%d, height=%d\n", wwidth, wheight);
}

void opengl_mouse_event(int button,int state,int x,int y){
    printf("mouse_event running... button=%d, state=%d, x=%d, y=%d\n", button, state, x, y);
}

void opengl_drawrect(int x, int y, int w, int h, int r)
{
    glColor3ub(255, 255, 0);
    glBegin(GL_LINE_LOOP);
    for (int i = 0; i < 90; i++) {
        double xx = cos(i * M_PI / 180.0) * r, yy = sin(i * M_PI / 180.0) * r;
        glVertex2d(x - xx, y - yy);
        glVertex2d(x+w + xx, y - yy);
        glVertex2d(x+w + xx, y+h + yy);
        glVertex2d(x - xx, y+h + yy);
    }
    glEnd();
}

void opengl_fillrect(int x, int y, int w, int h, int r)
{
    glColor3ub(0, 255, 0);
    glBegin(GL_POLYGON);
    for (int i = 0; i < 90; i++) {
        double xx = cos(i * M_PI / 180.0) * r, yy = sin(i * M_PI / 180.0) * r;
        glVertex2d(x - xx, y - yy);
        glVertex2d(x+w + xx, y - yy);
        glVertex2d(x+w + xx, y+h + yy);
        glVertex2d(x - xx, y+h + yy);
    }
    glEnd();
}
#6
我善治鬼2021-07-31 21:18
glOrtho()前面还要加
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
的, 我省略了, 你加上试试
只有本站会员才能查看附件,请 登录



[此贴子已经被作者于2021-7-31 21:24编辑过]

#7
我善治鬼2021-07-31 21:21
最好将你的GLUT初始化改为我的初始化函数
程序代码:



int main()
{
    PIXELFORMATDESCRIPTOR pf = { 0 };
    HWND wd = GetConsoleWindow();
    HDC dc = GetDC(wd);
    SetPixelFormat(dc, ChoosePixelFormat(dc, &pf), &pf);
    HGLRC rc = wglCreateContext(dc);
    wglMakeCurrent(dc, rc);

    RECT Client = { 0 };
    while (1) {
        opengl_display();

        GetClientRect(wd, &Client);
        if (Client.right != wwidth || Client.bottom != wheight) {
            wwidth = Client.right;
            wheight = Client.bottom;
            glViewport(0, 0, wwidth, wheight);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glOrtho(0, wwidth, wheight, 0, 100, -100);
        }
    }
    return 0;
}


#8
xyzdwf2021-07-31 22:42
回复 7楼 我善治鬼
万分感谢确实可以了
只有本站会员才能查看附件,请 登录
#9
xyzdwf2021-07-31 23:00
自己又弄了个,能控制线条宽度的
只有本站会员才能查看附件,请 登录

程序代码:

#define FREEGLUT_STATIC
#include <stdio.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glut.h>

///** type defines **/

///** props defines **/
static int wwidth = 1000;
static int wheight = 700;

///** funs defines **/
void opengl_resize(int w, int h);
void opengl_mouse_event(int button,int state,int x,int y);

void opengl_drawrect(int x, int y, int w, int h, int r);
void opengl_fillrect(int x, int y, int w, int h, int r);
void opengl_rect(int x, int y, int w, int h, int r, GLenum mode);

void opengl_display();
GLfloat opengl_onelizedA(int a);
GLfloat opengl_onelizedB(int b);

void v2f(int x, int y);

int main(int argc, char ** argv)
{
    glutInit(&argc, argv);
   
    glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
    glutInitWindowPosition(300, 200);
    glutInitWindowSize(wwidth, wheight);
    glutCreateWindow("simple");
    glViewport(0, 0, wwidth, wheight);
   
    glutDisplayFunc(opengl_display);
    glutReshapeFunc(opengl_resize);
    glutMouseFunc(opengl_mouse_event);
   
   
    glutMainLoop();
}

///** funs impls **/

void opengl_display()
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
   
    opengl_fillrect(100, 100, 300, 200, 20);
    opengl_drawrect(400, 400, 200, 100, 20);
   
    glFlush();


}

void opengl_resize(int w, int h)
{
    glViewport(0, 0, w, h);
    wwidth = w;
    wheight = h;
    printf("window resize ... width=%d, height=%d\n", wwidth, wheight);
}

void opengl_mouse_event(int button,int state,int x,int y){
    printf("mouse_event running... button=%d, state=%d, x=%d, y=%d\n", button, state, x, y);
}

void opengl_drawrect(int x, int y, int w, int h, int r)
{
    //线条抗锯齿,线条还变宽,没用不如不抗
   
//glEnable(GL_LINE_SMOOTH);
   
//glHint(GL_LINE_SMOOTH,GL_NICEST);
   
//线宽
   
//glLineWidth(1);
   
//glPointSize(点的直径);
    glColor4f(0.0f, 1.0f, 0.0f, 0.1f);
    opengl_rect(x, y, w, h, r, GL_LINE_LOOP);
    glDisable(GL_LINE_SMOOTH);
}

void opengl_fillrect(int x, int y, int w, int h, int r)
{
    //多边形抗锯齿
    glEnable(GL_POLYGON_SMOOTH);
    glHint(GL_POLYGON_SMOOTH,GL_NICEST);
    glColor4f(1.0f, 0.0f, 0.0f, 0.1f);
    opengl_rect(x, y, w, h, r, GL_POLYGON);
    glDisable(GL_POLYGON_SMOOTH);
}

void opengl_rect(int x, int y, int w, int h, int r, GLenum mode)
{
    if(0 == r){
        glBegin(mode);
            v2f(x, y+h);
            v2f(x, y);
            v2f(x+w, y);
            v2f(x+w, y+h);
        glEnd();
    }else{
        int d = 1;
        glBegin(mode);
            for(int i=0; i<r+1; i+=d){
                v2f(x+i, y+r-floor(sqrt( pow(r,2) - pow(r-i,2) )));
            }
            v2f(x+r, y);
            v2f(x+w-r, y);
            for(int i=0; i<r+1; i+=d){
                v2f(x+w-r+i, y+r-floor(sqrt( pow(r,2) - pow(i,2) )));
            }
            v2f(x+w, y+r);
            v2f(x+w, y+h-r);
            for(int i=0; i<r+1; i+=d){
                v2f(x+w-i, y+h-r+floor(sqrt( pow(r,2) - pow(r-i,2) )));
            }
            v2f(x+w-r, y+h);
            v2f(x+r, y+h);
            for(int i=0; i<r+1; i+=d){
                v2f(x+r-i, y+h-r+floor(sqrt( pow(r,2) - pow(i,2) )));
            }
            v2f(x, y+h-r);
            v2f(x, y+r);
        glEnd();
        
    }
}

GLfloat opengl_onelizedA(int a)
{
    GLfloat m = a * 1.0;
    GLfloat n = wwidth * 1.0;
    return (2 * m / n) - 1;
}

GLfloat opengl_onelizedB(int b)
{
    GLfloat m = b * 1.0;
    GLfloat n = wheight * 1.0;
    return 1 - (2 * m / n);
}

void v2f(int x, int y)
{
    glVertex2f(opengl_onelizedA(x), opengl_onelizedB(y));
}
1