Уроки, алгоритмы, программы, примеры

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

У меня проблема вот с этим: gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);. Вылезает ошибка: CS1061 "object" не содержит определения "GL_COLOR_BUFFER_BIT", и не удалось найти доступный метод расширения "GL_COLOR_BUFFER_BIT",...
Большое спасибо. Единственный код который прошел без каких либо ошибок. Ура!!!
Скажите пожалуйста, подскажите алгоритм по которому по заданным точкам можно определить тип многогранника, скажем это куб или прямоугольный параллелепипед. Нашел теорию по этим фигурам: https://www.mat... https://www.mat... Акцентировать внимание...
Всем у кого не работает. файл wizard.script Ещё одно упоминание Glut32 в строке "if (!VerifyLibFile(dir_nomacro_lib, _T("glut32"), _T("GLUT's"))) return false;" меняем на "if (!VerifyLibFile(dir_nomacro_lib, _T("freeglut"), _T("GLUT's"))) return...
Не получается, емаё

Счетчики и рейтинг

Рейтинг@Mail.ru Яндекс.Метрика
Скриншот к примеру
Среда программирования: 
NetBeans 7.4

В классе Mandelbrot хранятся переменные вектора позиции и вращения.

Сама програма очень проста и состоит из следующего кода:

    public Mandelbrot() {
        createDisplay();
        setUpOpenGL();
        setUpMandelbrot();
        delta = getDelta(); // start timer
        while(!Display.isCloseRequested()) {
            draw();
            processInput();
            Display.sync(60);
            Display.update();
            delta = getDelta();
        }
        Display.destroy();
    }

Функции:
createDisplay() создает экран
setUpOpenGL() инициализирует OpenGL
setUpMandelbrot() строит множество Мндельброта

и основной цикл:
draw(); вызов перересовки всех элементов
processInput(); обработать клавиатуру и мышь
Display.sync(60); Display.update(); delta = getDelta(); 60 кадров в секунду, обновить экран и таймер

Само построение множества делается при помощи OpenGL List, для того чтобы его каждый раз не пересчитывать:

        mandelbrotDisplayList = glGenLists(1);
        glNewList(mandelbrotDisplayList, GL_COMPILE);
        glBegin(GL_QUADS);
 
        for (float y = -bound; y < bound; y += step) {
            for (float x = -bound; x < bound; x += step) {
                float X = 0;
                float Y = 0;
                int iter = 0;
                while (X*X + Y*Y < 4 && iter < maxIter) {
                    float xtemp = X*X - Y*Y + x;
                    Y = 2*X*Y + y;
                    X = xtemp;
                    iter++;
                }
                if (iter == 1000) continue;
                int r = (40 * iter) % 256;
                int g = (80 * iter) % 256;
                int b = (120 * iter) % 256;
                glColor3f(r/256.0f, g/256.0f, b/256.0f);
                glVertex3f(x, y, iter/1000.0f);
                glVertex3f(x + step, y, iter/1000.0f);
                glVertex3f(x + step, y + step, iter/1000.0f);
                glVertex3f(x, y + step, iter/1000.0f);
            }
        }
 
        glEnd();
        glEndList();

Исходники прикреплены. Для запуска приложения на компьютере необходимо, чтобы была установлена Java. Запускать файл Mandelbrot.jar

Код программы: 

package net.ilyi;
 
import static org.lwjgl.util.glu.GLU.gluPerspective;
import static org.lwjgl.opengl.GL11.*;
import java.nio.ByteBuffer;
import org.lwjgl.opengl.*;
import org.lwjgl.input.*;
import org.lwjgl.*;
 
import org.newdawn.slick.Color;
import java.nio.FloatBuffer;
import org.lwjgl.util.vector.Vector3f;
 
public class Mandelbrot {
    private static final int DISPLAY_WIDTH = 1270;
    private static final int DISPLAY_HEIGHT = 720;
    private Vector3f position = new Vector3f(0.0f, 0.0f, 0.0f);
    private Vector3f rotation = new Vector3f(90.0f, 0.0f, 0.0f);
    private int mandelbrotDisplayList;
    private int delta;
 
    public static void main(String[] args) {
        new Mandelbrot();
    }
 
    public Mandelbrot() {
        createDisplay();
        setUpOpenGL();
        setUpMandelbrot();
        delta = getDelta(); // start timer
        while(!Display.isCloseRequested()) {
            draw();
            processInput();
            Display.sync(60);
            Display.update();
            delta = getDelta();
        }
        Display.destroy();
    }
 
    private void createDisplay() {
        try {
            Display.setDisplayMode(new DisplayMode(DISPLAY_WIDTH, DISPLAY_HEIGHT));
            Display.setTitle("Mandelbrot");
 
            ByteBuffer[] iconBuffer = new ByteBuffer[1]; // no icon
            iconBuffer[0] = BufferUtils.createByteBuffer(1);
            Display.setIcon(iconBuffer);
 
            Display.create();
        } catch (LWJGLException ex) {
            ex.printStackTrace();
        }
    }
 
    private void setUpOpenGL() {
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(90, (float)DISPLAY_WIDTH/DISPLAY_HEIGHT, 0.01F, 250.0f);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
 
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
        glEnable(GL_ALPHA_TEST);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
 
        setUpFog();
    }
 
    private void setUpFog() {
        glEnable(GL_FOG);
        Color fogColor = new Color(0.0f, 0.0f, 0.0f, 1.0f);
 
        FloatBuffer fogColours = BufferUtils.createFloatBuffer(4);
        fogColours.put(new float[]{fogColor.r, fogColor.g, fogColor.b, fogColor.a});
        glClearColor(fogColor.r, fogColor.g, fogColor.b, fogColor.a);
        fogColours.flip();
        glFog(GL_FOG_COLOR, fogColours);
        glFogi(GL_FOG_MODE, GL_LINEAR);
        glHint(GL_FOG_HINT, GL_NICEST);
        glFogf(GL_FOG_START, 10.0f);
        glFogf(GL_FOG_END, 250.0f);
        glFogf(GL_FOG_DENSITY, 0.005f);
    }
 
    private final float bound = 2.0f;
    private float step = bound / 400.0f;
    private final int maxIter = 1000;
    private void setUpMandelbrot() {
        mandelbrotDisplayList = glGenLists(1);
        glNewList(mandelbrotDisplayList, GL_COMPILE);
        glBegin(GL_QUADS);
 
        for (float y = -bound; y < bound; y += step) {
            for (float x = -bound; x < bound; x += step) {
                float X = 0;
                float Y = 0;
                int iter = 0;
                while (X*X + Y*Y < 4 && iter < maxIter) {
                    float xtemp = X*X - Y*Y + x;
                    Y = 2*X*Y + y;
                    X = xtemp;
                    iter++;
                }
                if (iter == 1000) continue;
                int r = (40 * iter) % 256;
                int g = (80 * iter) % 256;
                int b = (120 * iter) % 256;
                glColor3f(r/256.0f, g/256.0f, b/256.0f);
                glVertex3f(x, y, iter/1000.0f);
                glVertex3f(x + step, y, iter/1000.0f);
                glVertex3f(x + step, y + step, iter/1000.0f);
                glVertex3f(x, y + step, iter/1000.0f);
            }
        }
 
        glEnd();
        glEndList();
    }
 
    private void draw() {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glCallList(mandelbrotDisplayList);
    }
 
    private void processInput() {
        glLoadIdentity();
        glRotatef(rotation.x, -1.0f, 0.0f, 0.0f);
        glRotatef(rotation.y,  0.0f, 1.0f, 0.0f);
        glRotatef(rotation.z,  0.0f, 0.0f, 1.0f);
        glTranslatef(-position.x, -position.y, -position.z);
 
        // mouse rotation
        float mouseSpeed = 0.16f;
        if (Mouse.isGrabbed()) {
            float mouseDX = Mouse.getDX() * mouseSpeed;
            float mouseDY = Mouse.getDY() * mouseSpeed;
 
            // horizontal rotation
            rotation.z += mouseDX;
            if (rotation.z >= 360.0f)
                rotation.z -= 360.0f;
            else if (rotation.z < 0.0f)
                rotation.z += 360.0f;
 
            // vertical rotation
            float maxLookDown = 5.0f;
            float maxLookUp = 175.0f;
            rotation.x += mouseDY;
            if (rotation.x < maxLookDown)
                rotation.x = maxLookDown;
            else if (rotation.x > maxLookUp)
                rotation.x = maxLookUp;
        }
 
        // mouse clicks
        while (Mouse.next()) {
            if (Mouse.isButtonDown(0))
                Mouse.setGrabbed(true);
            if (Mouse.isButtonDown(1))
                Mouse.setGrabbed(false);
        }
 
        // buttons
        boolean keyUp = Keyboard.isKeyDown(Keyboard.KEY_UP) || Keyboard.isKeyDown(Keyboard.KEY_W);
        boolean keyDown = Keyboard.isKeyDown(Keyboard.KEY_DOWN) || Keyboard.isKeyDown(Keyboard.KEY_S);
        boolean keyLeft = Keyboard.isKeyDown(Keyboard.KEY_LEFT) || Keyboard.isKeyDown(Keyboard.KEY_A);
        boolean keyRight = Keyboard.isKeyDown(Keyboard.KEY_RIGHT) || Keyboard.isKeyDown(Keyboard.KEY_D);
        boolean flyUp = Keyboard.isKeyDown(Keyboard.KEY_SPACE);
        boolean flyDown = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL);
        boolean moveFaster = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT);
        boolean moveSlower = Keyboard.isKeyDown(Keyboard.KEY_LMENU);
 
        // movement speed
        float walkingSpeed = 0.0004f;
        if (moveFaster && !moveSlower)
            walkingSpeed *= 20f;
        if (moveSlower && !moveFaster)
            walkingSpeed /= 10f;
 
        // horizontal movement (trigonometry)
        if (keyUp || keyRight || keyLeft || keyDown) {
            float angle = rotation.z + directionAngle(keyUp, keyRight, keyDown, keyLeft);
            float hyp = walkingSpeed * delta;
            float opp = hyp * (float) Math.sin(Math.toRadians(angle));
            float adj = hyp * (float) Math.cos(Math.toRadians(angle));
            position.x += opp;
            position.y += adj;
        }
 
        // vertical movement
        if (flyUp && !flyDown)
            position.z += walkingSpeed * delta;
        if (flyDown && !flyUp)
            position.z -= walkingSpeed * delta;
 
        // reset button
        while (Keyboard.next()) {
            if (Keyboard.isKeyDown(Keyboard.KEY_C)) {
                position = new Vector3f(0, 0, 0);
                rotation = new Vector3f(0, 0, 0);
            }
        }
    }
 
    /**
     * Returns proper angle for key combinations
     * @param keyUp Forward button.
     * @param keyRight Right button.
     * @param keyDown Down button.
     * @param keyLeft Left button.
     * @return Angle to add in degrees.
     */
    private float directionAngle(boolean keyUp, boolean keyRight, boolean keyDown, boolean keyLeft) {
        if (keyUp && !keyRight && !keyDown && !keyLeft)
            return 0.0f;
        else if (keyUp && keyRight && !keyDown && !keyLeft)
            return 45.0f;
        else if (!keyUp && keyRight && !keyDown && !keyLeft)
            return 90.0f;
        else if (!keyUp && keyRight && keyDown && !keyLeft)
            return 135.0f;
        else if (!keyUp && !keyRight && keyDown && !keyLeft)
            return 180.0f;
        else if (!keyUp && !keyRight && keyDown && keyLeft)
            return 225.0f;
        else if (!keyUp && !keyRight && !keyDown && keyLeft)
            return 270.0f;
        else
            return 315.0f;
    }
 
    /**
     * Get delta-time value used in movement calculation.
     * @return delta-value.
     */
    private static long prevTime;
    public static int getDelta() {
        long currTime = (Sys.getTime() * 1000) / Sys.getTimerResolution();
        int delta = (int)(currTime - prevTime);
        prevTime = currTime;
        return delta;
    }
}

Прикрепленный файлРазмер
Mandelbrot.zip1.94 Мб