标题:关于opengl绘制圆角矩形,大小圆角要用不同的绘制方法
取消只看楼主
xyzdwf
Rank: 2
等 级:论坛游民
威 望:1
帖 子:52
专家分:10
注 册:2017-1-9
结帖率:88.89%
已结贴  问题点数:10 回复次数:4 
关于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
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
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
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



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-506366-1-1.html




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

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