Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Jogl и тени, реализация затемнения планет 
:(
    Опции темы
SniyLSD
  Дата 24.1.2011, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 28.5.2008

Репутация: нет
Всего: нет



Всем доброго времени суток!
 У меня задание нарисовать динамическую 3-х мерную систему земля-луна с затенением земли луной и наоборот.
С первой частью - нарисовать планету со спутником, натянуть текстуры и заставить их передвигаться по орбитам я сделал.
но со вторым я в растерянности. 
Прошу помощи реализовать затенение. код 4-х классов:
код правда ужасный smile , переделывать не успеваю, так как преподаватель вдруг затребовал на этой неделе сдать работы.
И еще кажется нужно исправить отображение фона, а то он как-то некорректно выводится.. но это все потом. Буду очень рад, если поможете написать класс отрисовки теней.

ЗЫ. Просьба не отсылать к мануалам, так как на их изучение нужно время которого у меня сейчас и так мало  smile 
Главный класс
Код

package Pack_class;

import java.awt.BorderLayout;
import javax.media.opengl.DebugGL;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import javax.swing.JFrame;

import com.sun.opengl.util.FPSAnimator;
import com.sun.opengl.util.texture.Texture;

/**
 SniyLSD 
 24.01.11
 */
public class Kursovik extends GLCanvas implements GLEventListener {

    /** Serial version UID. */
    private static final long serialVersionUID = 1L;

    /** The GL unit (helper class). */
    private GLU glu;

    /** The frames per second setting. */
    private int fps = 60;

    /** The OpenGL animator. */
    private FPSAnimator animator;


    private Texture earthTexture;
    private Texture moonTexture;
    private Texture backgr;
    
    public Kursovik(GLCapabilities capabilities, int width, int height) {
        addGLEventListener(this);
    }


    private static GLCapabilities createGLCapabilities() {
        GLCapabilities capabilities = new GLCapabilities();
        capabilities.setRedBits(8);
        capabilities.setBlueBits(8);
        capabilities.setGreenBits(8);
        capabilities.setAlphaBits(8);
        return capabilities;
    }

    public void init(GLAutoDrawable drawable) {
        drawable.setGL(new DebugGL(drawable.getGL()));
        final GL gl = drawable.getGL();

        // Enable z- (depth) buffer for hidden surface removal. 
        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glDepthFunc(GL.GL_LEQUAL);

        // Enable smooth shading.
        gl.glShadeModel(GL.GL_SMOOTH);

        // Define "clear" color.
        gl.glClearColor(0f, 0f, 0f, 0f);

        // We want a nice perspective.
        gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);

        // Create GLU.
        glu = new GLU();

        // Load earth texture.
        earthTexture = LoadTexture.Load("earth.jpg");
        moonTexture  = LoadTexture.Load("moon.jpg");
        backgr         = LoadTexture.Load("stars.jpg");
        // Start animator.
        animator = new FPSAnimator(this, fps);
        animator.start();
    }

    public void display(GLAutoDrawable drawable) {
        
     if (!animator.isAnimating()) {
            return;
        }
        final GL gl = drawable.getGL();
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        // Set camera.
        setCamera(gl, glu, 30, 0, 0);
        // Prepare light parameters.
        float SHINE_ALL_DIRECTIONS = 0;
        float[] lightPos = {50, 0, 0, SHINE_ALL_DIRECTIONS};
        float[] lightColorAmbient = {0.2f, 0.2f, 0.2f, 1f};
        float[] lightColorSpecular = {0.8f, 0.8f, 0.8f, 1f};

        // Set light parameters.
        gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightPos, 0);
        gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, lightColorAmbient, 0);
        gl.glLightfv(GL.GL_LIGHT1, GL.GL_SPECULAR, lightColorSpecular, 0);

        // Enable lighting in GL.
        gl.glEnable(GL.GL_LIGHT1);
        gl.glEnable(GL.GL_LIGHTING);

        // Set material properties.
        float[] rgba = {1f, 1f, 1f};
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, rgba, 0);
        gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, rgba, 0);
        gl.glMaterialf(GL.GL_FRONT, GL.GL_SHININESS, 0.5f);
        
        Background.DrawBackground(backgr, gl);     
        Planets.DrawPlanetEarth(earthTexture, gl, glu);
        Planets.DrawPlanetMoon(moonTexture, gl, glu, true);
    }

    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        final GL gl = drawable.getGL();
        gl.glViewport(0, 0, width, height);
    }

    public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
        throw new UnsupportedOperationException("Changing display is not supported.");
    }


    private void setCamera(GL gl, GLU glu, float distance, float x, float y) {
        // Change to projection matrix.
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();

        // Perspective.
        float widthHeightRatio = (float) getWidth() / (float) getHeight();
        
        glu.gluPerspective(60, widthHeightRatio, 1, 1000);
        glu.gluLookAt(30,0 ,-20, 0, 0, 0, 0, 0, -1);

        // Change back to model view matrix.
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    public final static void main(String[] args) {
        GLCapabilities capabilities = createGLCapabilities();
        Kursovik canvas = new Kursovik(capabilities, 800,600);
        JFrame frame = new JFrame("Курсовая работа system Earth-Moon, Moon shadow");
        frame.getContentPane().add(canvas, BorderLayout.CENTER);
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        canvas.requestFocus();
        
    }       
}


Класс Background
Код

package Pack_class;

import javax.media.opengl.GL;

import com.sun.opengl.util.texture.Texture;

public class Background {
    
    public static void DrawBackground(Texture background, GL gl){
        
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glPushMatrix();
        gl.glOrtho(0, 1, 0, 1, 0, 1);

        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPushMatrix();
        gl.glLoadIdentity();
        
        // No depth buffer writes for background.
        gl.glDepthMask( false );
        
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
        gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
        gl.glBindTexture( GL.GL_TEXTURE_2D, background.getTextureObject() );
        gl.glBegin( GL.GL_QUADS ); 
              gl.glTexCoord2f( -500f, -500f );
              gl.glVertex2f( -500f, -500f );
              gl.glTexCoord2f( -500f, 500f );
              gl.glVertex2f( -500f, 500f );
              gl.glTexCoord2f( 500f, 500f );
              gl.glVertex2f( 500f, 500f );
              gl.glTexCoord2f( 500f, -500f );
              gl.glVertex2f( 500f, -500f );
        gl.glEnd();

        gl.glDepthMask( true );

        gl.glPopMatrix();
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glPopMatrix();
        gl.glMatrixMode(GL.GL_MODELVIEW);
    }

}



Класс LoadTexture
Код

package Pack_class;

import java.io.File;
import java.io.IOException;

import com.sun.opengl.util.texture.Texture;
import com.sun.opengl.util.texture.TextureIO;

public class LoadTexture {


    public static Texture Load (String name){
        Texture texture = null;
            try {
                texture = TextureIO.newTexture(new File(name), false);
            } catch (IOException e) {
                System.out.println("Ошибка открытия файла " + name);
                System.out.println(e);
            }
            return texture;
    }

}


Класс Planets
Код

package Pack_class;

import javax.media.opengl.GL;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;

import com.sun.opengl.util.texture.Texture;

public class Planets {
    
    private static float satelliteAngle = 0;    
    
    public static void DrawPlanetEarth(Texture earthTexture, GL gl, GLU glu){
        long millis = System.currentTimeMillis();
        double earth1 = (double) (millis % 1000000) / 100000 * 360;
        earthTexture.enable();
        earthTexture.bind();
        gl.glPushMatrix();
        GLUquadric earth = glu.gluNewQuadric();
        gl.glRotated(earth1, 0, 0,-1);
        glu.gluQuadricTexture(earth, true);
        glu.gluQuadricDrawStyle(earth, GLU.GLU_FILL);
        glu.gluQuadricNormals(earth, GLU.GLU_FLAT);
        glu.gluQuadricOrientation(earth, GLU.GLU_OUTSIDE);
        float radius = 6.378f;
        int slices = 128;
        int stacks = 128;
        glu.gluSphere(earth, radius, slices, stacks);
        glu.gluDeleteQuadric(earth);
        gl.glPopMatrix();
        
    }
    
    public static void DrawPlanetMoon(Texture moonTexture, GL gl, GLU glu, boolean light){
            moonTexture.bind();
            gl.glPushMatrix();
            long millis = System.currentTimeMillis();
            double moon1 = (double) (millis % 100) / 100000 * 360;
            // Compute satellite position.
            satelliteAngle = (float) ((satelliteAngle - 0.25) % 360f);
            float distance = 20.000f;
            if (!light){ distance = 6.f;}
            float x = (float) Math.sin(Math.toRadians(satelliteAngle)) * distance;
            float y = (float) Math.cos(Math.toRadians(satelliteAngle)) * distance;
            float z = 0;
            gl.glTranslatef(x, y, z);
            gl.glRotatef(satelliteAngle, 0, 0, -1);
            gl.glRotatef(45f, 0, 0, 0);
            
            if (light) 
            {
            gl.glEnable (GL.GL_LIGHTING); 
            gl.glEnable (GL.GL_LIGHT0); 
            gl.glColor3d(1, 0.3, 0.5); 
            }
            
            GLUquadric moon = glu.gluNewQuadric();
            gl.glRotated(moon1, 0, 0,-0.2);
            glu.gluQuadricTexture(moon, light);
            glu.gluQuadricDrawStyle(moon, GLU.GLU_FILL);
            glu.gluQuadricNormals(moon, GLU.GLU_FLAT);
            glu.gluQuadricOrientation(moon, GLU.GLU_OUTSIDE);
            float radius = 1.6f;
            int slices = 64;
            int stacks = 64;
            glu.gluSphere(moon, radius, slices, stacks);
            glu.gluDeleteQuadric(moon);
            
            if (light){
             gl.glDisable (GL.GL_LIGHT0); 
             gl.glDisable (GL.GL_LIGHTING); 
            }
            gl.glPopMatrix();
        
    }

}




Если будет нужно, я прикреплю файлы проекта (писалось все это  в EasyEclipse Desktop Java)
PM MAIL   Вверх
EgorTheBlade
Дата 24.1.2011, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 141
Регистрация: 5.12.2009

Репутация: нет
Всего: -1



Можете сделать простой вариант.
Луна слева- закрасить в черный цвет левый бок земли.
Луна справа - закрасить левый бок  луны т.к земля отбрасывает тень на неё.
Надеюсь,вы поняли что я хотел сказать.
PM MAIL Skype   Вверх
SniyLSD
Дата 24.1.2011, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 28.5.2008

Репутация: нет
Всего: нет



Если честно - то не очень... 
Основная проблема - я не знаю как рассчитать, где должна лечь тень. Шары рисовал методом gluSphere
и как наложить тень - то же не вкурсе(
PM MAIL   Вверх
EgorTheBlade
Дата 25.1.2011, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 141
Регистрация: 5.12.2009

Репутация: нет
Всего: -1



 Нет такого метода?
 Если объект А (Луна) находится в координатах (X,Y) то закрасить половину объекта Б(Земля).
PM MAIL Skype   Вверх
SniyLSD
Дата 25.1.2011, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 28.5.2008

Репутация: нет
Всего: нет



Такого метода не встречал. Может попробовать с помощью буфера трафарета?
Правда у меня сфера, а не плоскость. Поможет ли это?

Это сообщение отредактировал(а) SniyLSD - 25.1.2011, 10:33
PM MAIL   Вверх
SniyLSD
Дата 26.1.2011, 04:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 28.5.2008

Репутация: нет
Всего: нет



Ладно, следующий вопрос - как мне применяя буфер трафарета спроецировать луну на землю так, чтобы тень рисовалась на поверхности земли?
PM MAIL   Вверх
math64
Дата 26.1.2011, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 8
Всего: 72



Насколько я понимаю, нужно создать объект Солнце - источник света (у тебя есть Земля, Луна, звёзды) - и тогда тень сама нарисуется.
PM   Вверх
Amp
Дата 26.1.2011, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 886
Регистрация: 17.2.2009

Репутация: 3
Всего: 17



Цитата(SniyLSD @  26.1.2011,  04:54 Найти цитируемый пост)
Ладно, следующий вопрос - как мне применяя буфер трафарета спроецировать луну на землю так, чтобы тень рисовалась на поверхности земли? 

Посмотри в гугле по фразе "shadow volumes". Вкратце - исходя из положения источника света и объекта, который отбрасывает тень, строится некая фигура, которая определяет границы тени (для сферы она будет в виде цилиндра или конуса, ось которого проходит через центр сферы и точки, где находится источник света). Далее, с помощью манипуляций с буфером трафарета и отрисовкой полупрозрачного полигона на весь экран, добиваются эффекта тени. В итоге - будет самозатенение (как раз для полушария) и тень на других объектах.

Для сфер все сильно упрощается, т.к. не надо реализовывать алгоритм нахождение контура тени на объекте - это будет окружность. В итоге надо просто построить конус (или цилиндр, в случае если лучи воображаемого источника света считаются параллельными), который уходит в бесконечность и применить буфер трафарета, чтобы вырезать часть полупрозрачного полигона.
PM MAIL   Вверх
SniyLSD
Дата 26.1.2011, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 32
Регистрация: 28.5.2008

Репутация: нет
Всего: нет



Вот это уже ближе!  smile И еще, как воспользоваться буфером трафарета для отсечения необходимого, насколько я помню - он представляет собой массив пикселей, который заполняется значениями с текующей точки обзора камеры, послойно ("0" - первый слой, "1" - второй слой и т.д.) числа определяют контур обьекта. Так ведь? Тогда я немного не понимаю, как это можно реализовать с помощью трафарета. smile 
У вас есть возможность написать маленький пример статичной системы с тенью основанной на этом методе? smile 
Думаю не только мне это пригодится. Информации в интернете по jogl на русском языке маловато, если не сказать, что вообще нету. 
PM MAIL   Вверх
Amp
Дата 28.1.2011, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 886
Регистрация: 17.2.2009

Репутация: 3
Всего: 17



То, как и что будет писаться в буфер определяется параметрами функций glStencilFunc/Op/Mask. По ссылке приведена блок-схема с подробным заданием параметров для stencil buffer-а http://www.opengl.org/resources/code/sampl.../rts/index.html
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0751 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.