1

我一直在做 Mandelbrot 设置并尝试缩放,但缩放模式变得非常麻烦。当我缩放时,它会完美缩放,但图像尺寸会缩小到原来的一半。下次我再次缩放时,图片尺寸会增加并尝试跳过查看窗口。代码在 c++/opengl 中。在发布到这里之前,我试图让我的代码有点干净。

#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

double dividecubesby  = 700;
double left = -2.0;
double right = 2.0;
double bottom = -2.0;
double top = 2.0;
int maxiteration = 128;
int zoomlevel = 3;
double baseSize = 4.0;
double SizeReal;
double SizeImage;
double xco=0.0;
double yco=0.0;

void whatcoordinate(int x,int y)
{
    int xp=x;
    int yp=y;
    double delta1 = (right-left);
    double tempx;   
    double tempy;
    double delta=0.0;   
    double l = dividecubesby/2;

    delta = delta1/dividecubesby;

    if((xp > l) && (yp < l))
    {
        tempx = xp*delta;
        tempy = yp*delta;

        xco = right - tempx;
        yco = top - tempy;

        if(xco <0)xco=xco*-1;
        if(yco <0)yco=yco*-1;
    }
    else if( (x < l) && (y < l))
    {
        tempx = xp*delta;
        tempy = yp*delta;

        xco = right - tempx;
        yco = top - tempy;

        if(xco >0)xco=xco*-1;
        if(yco <0) yco =yco*-1;
    }
    else if((x < l) && (y > l))
    {
        tempx = xp*delta;
        tempy = yp*delta;

        xco = right - tempx;
        yco = top - tempy;

        if(xco >0)xco=xco*-1;
        if(yco >0)yco=yco*-1;
    }
    else if((x > l) && (y > l))
    {
        tempx = xp*delta;
        tempy = yp*delta;

        xco = right - tempx;
        yco = right - tempy;

        if(xco <0)xco=xco*-1;
        if(yco >0)yco=yco*-1;
    }
}

void keyPressed(unsigned char key, int x, int y)
{
    switch(key)
    {
    case 'z':
        printf("z pressed  x= %d, y= %d \n",x,y);

        whatcoordinate(x,y);

        SizeReal = (pow(2.0, (-zoomlevel)))*baseSize;
        SizeImage = (pow(2.0, (-zoomlevel)))*baseSize;

        baseSize = right-left;

        left   =  xco- (SizeReal/2);
        right  =  xco + (SizeReal/2);
        bottom = yco - (SizeReal/2);
        top    = yco + (SizeReal/2);    
        dividecubesby = dividecubesby+500;      
        maxiteration  = maxiteration+500; 
        zoomlevel=zoomlevel+1;

        glutPostRedisplay();

        break;
    }
}

int mandtest(double Cr, double Ci)
{
    double Zr = 0.0;
    double Zi = 0.0;
    int times = 0;
    double temp;
    Zr = Zr+Cr;
    Zi = Zi+Ci;

    while ((((Zr*Zr)+(Zi*Zi))<=4) && (times < maxiteration))
    {
        temp = (Zr*Zr)-(Zi*Zi);
        Zi = 2*Zr*Zi;

        Zr = temp+Cr;
        Zi = Zi+Ci;                

        times = times+1;  

    }

    return times;
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f,1.0f,1.0f);
    double deltax = ((right - left)/(dividecubesby-1));//this means length/700 
    double deltay = ((top- bottom)/(dividecubesby-1));// this means length/700

    gluOrtho2D(left,right,bottom,top);
    glBegin(GL_POINTS);

    for(double x= left;x<=right;x += deltax )
    {
        for(double y= bottom; y<=top;y +=  deltay )
        {
            if((mandtest(x,y))==maxiteration)
            {
                glColor3f(1.0f,1.0f,1.0f); 
                glVertex2f(x,y);
            }
            else 
            {
                glColor3f((float)mandtest(x,y)/10,0.0f,(float)mandtest(x,y)/30);
                glVertex2f(x,y);
            }
        }
    }
    glEnd();

    glFlush();
}

void init()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
}

int main(int argc, char ** argv)
{   
    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(dividecubesby,dividecubesby);
    glutCreateWindow("A Simple OpenGL Windows Application with GLUT");
    init();
    glutDisplayFunc(display);
    glutKeyboardFunc(keyPressed);
    glutMainLoop();

    return 0;
}

执行时

1)在此处输入图像描述

2)在此处输入图像描述

3)在此处输入图像描述

4

2 回答 2

2

我认为您不应该在每次重新渲染时使用 gluOrtho2D(left,right,bottom,top) 更改视图转换。只需给他们(初始)固定值。视图将保持不变,就像您在图 1) 中看到的一样。您应该只转换您传递给 Mandelbrot 函数的坐标。

正如@genpfault 提到的:考虑使用纹理。这样更有效率。

于 2012-10-30T20:14:48.570 回答
2

问题已通过放置解决

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

就在 gluOrtho2D(left,right,bottom,top) 的上方;在显示函数中这是用于初始化的。这在 opengl 超级圣经书的第 2 章中得到了很好的解释。

1)在此处输入图像描述

2)在此处输入图像描述

3)在此处输入图像描述

于 2012-11-06T15:45:39.543 回答