| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2073 人关注过本帖
标题:关于opengl绘制圆角矩形,大小圆角要用不同的绘制方法
只看楼主 加入收藏
xyzdwf
Rank: 2
等 级:论坛游民
威 望:1
帖 子:52
专家分:10
注 册:2017-1-9
结帖率:88.89%
收藏
已结贴  问题点数:10 回复次数:8 
关于opengl绘制圆角矩形,大小圆角要用不同的绘制方法
我是相邻像素去绘制,这样虽然在大圆角的时候比较圆润,但是到个位数圆角就感觉比较差,是不是圆角到个位数了就要用角度 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);
}

搜索更多相关主题的帖子: int sqrt 绘制 pow void 
2021-07-31 14:27
我善治鬼
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:107
专家分:181
注 册:2015-2-16
收藏
得分:10 
不知道是不是你想要的画圆角矩形效果, 每一个角度设置一个顶点, 可以设置角的宽度半径和高度半径

程序代码:

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



图片附件: 游客没有浏览图片的权限,请 登录注册
2021-07-31 18:24
xyzdwf
Rank: 2
等 级:论坛游民
威 望:1
帖 子:52
专家分:10
注 册:2017-1-9
收藏
得分:0 
回复 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编辑过]

2021-07-31 18:55
我善治鬼
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:107
专家分:181
注 册:2015-2-16
收藏
得分:0 
将 glBegin(GL_POLYGON);
改为 glBegin(GL_LINE_LOOP);
就行了, 只是边框有点大
凑合用可以的
2021-07-31 19:32
xyzdwf
Rank: 2
等 级:论坛游民
威 望:1
帖 子:52
专家分:10
注 册:2017-1-9
收藏
得分:0 
为什么啥也出不来
图片附件: 游客没有浏览图片的权限,请 登录注册

程序代码:
#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();
}
2021-07-31 20:38
我善治鬼
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:107
专家分:181
注 册:2015-2-16
收藏
得分:0 
glOrtho()前面还要加
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
的, 我省略了, 你加上试试
图片附件: 游客没有浏览图片的权限,请 登录注册



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

2021-07-31 21:18
我善治鬼
Rank: 5Rank: 5
等 级:贵宾
威 望:17
帖 子:107
专家分:181
注 册:2015-2-16
收藏
得分:0 
最好将你的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;
}


2021-07-31 21:21
xyzdwf
Rank: 2
等 级:论坛游民
威 望:1
帖 子:52
专家分:10
注 册:2017-1-9
收藏
得分:0 
回复 7楼 我善治鬼
万分感谢确实可以了
图片附件: 游客没有浏览图片的权限,请 登录注册
2021-07-31 22:42
xyzdwf
Rank: 2
等 级:论坛游民
威 望:1
帖 子:52
专家分:10
注 册:2017-1-9
收藏
得分:0 
自己又弄了个,能控制线条宽度的
图片附件: 游客没有浏览图片的权限,请 登录注册

程序代码:
#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));
}
2021-07-31 23:00
快速回复:关于opengl绘制圆角矩形,大小圆角要用不同的绘制方法
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.024702 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved