顯示具有 Week09 標籤的文章。 顯示所有文章
顯示具有 Week09 標籤的文章。 顯示所有文章

2018年1月16日 星期二

Week9

1 下載processing 3
2 貼上Bump maping 的程式碼產生以下結果

3 下載一張圖片拉入編譯器並用程式顯示圖片,如下圖

4 加入draw的函式使圖片跟著滑鼠移動,如下圖


5 貼上馬力歐小遊戲的程式碼,用以上方式設定馬力歐、磚塊、問號磚塊的圖片會產生簡單的馬力歐小遊戲,可以用鍵盤左右和上鍵控制馬力歐移動和跳躍

2018年1月13日 星期六

計圖筆記WEEK09

Bump Mapping


https://www.openprocessing.org/sketch/249457 下載code執行


在Processing中匯入圖片


1.將圖片拖曳到編輯器中  並加入程式碼
PImage img=loadImage("圖片檔名");size(長,寬);image(img,0,0,長,寬);

2.讓照片跟著滑鼠移動

PImage img;

void setup()
{
   img=loadImage("pchu.jpg");
   size(500,500);
}

void draw()
{
image(img,mouseX,mouseY);
}

馬力歐 Processing 


int [][]map={{0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             { 0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,1,1,2,2,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {1,1,1,1,1,1,1,1,1,1,1,1,1,1},};
PImage imgMario,imgBrick,imgBrick2;
void setup()
{
  size(800,600);
  imgMario=loadImage("mario.png");
  imgBrick=loadImage("Brick_Block.png");
  imgBrick2=loadImage("5da98730977895279f05af2eb7bd7516.png");
}
float marioX=200, marioY=100,marioVX=0,marioVY=0;
boolean marioOnFloor=false;
void draw()
{
  background(255);
  for(int x=0;x<14;x++)
  {
    for(int y=0;y<11;y++)
    {
      if(map[y][x]==1) image(imgBrick,  x*50,y*50,50,50);
      if(map[y][x]==2) image(imgBrick2, x*50,y*50,50,50);
    }
  }
  image(imgMario,marioX,marioY,100,100);
  marioY+=marioVY; marioX+=marioVX;
  marioVY+=0.98;
  if(marioY>=400){marioY=400;marioVY=0;marioOnFloor=true;}
}
void keyPressed(){
  if(keyCode==UP && marioOnFloor){marioVY=-15;marioOnFloor=false;}
  if(keyCode==RIGHT) marioVX=5;
  if(keyCode==LEFT) marioVX=-5;
}
void keyReleased(){
  if(keyCode==RIGHT || keyCode==LEFT) marioVX=0;
}

2018年1月12日 星期五

Week 9 陳泱竹

一、Bump Mapping:(利用Processing 編寫)
     (1)利用https://www.openprocessing.org/sketch/249457來獲得程式碼
     (2)在Processing貼上程式碼:

       (3)做出矩形且上色:
            size(200,200);
            fill(#832121);
            rect(50,50,100,100);
     
      (4)加入圖片:
           PImage img=loadImage("1.png");
           size(960,640);
           fill(#832121);
           image(img,0,0,960,640);
      (5)移動圖片:
           PImage img;
           void setup()
          {
                size(960,640);
                img=loadImage("1.png");
          }
          void draw()
         {
                background(255);//設定背景顏色 若沒有圖片會重疊
                image(img,mouseX,mouseY,96,64);
         }







我只是一只可愛的麻雀(._.)Week09 筆記

本周主題:Bump Mapping


何謂Bump Mapping??
=> https://www.openprocessing.org/sketch/249457


1. 下載moodle的 processing-3.3.6-windows64.zip 解壓縮並執行processing.exe

2. 從剛才上面的網址中複製他的code貼到軟體中



3. 在random中填上255


執行結果


PS--- 有些電腦的GPU不支援

4. color的地方多加一個f 可以變成網頁那樣的圖案


*畫出簡單的幾何圖形*


畫一個簡單的四方形

size(200,200); //create a 200*200 window
fill(#FC24C3); //fill #FC24C3 color
rect(10,10,50,50); //draw a 50*50 rectangle in position 10,10



*如何顯示一張圖片*



要記得把圖片放在processing程式的資料夾裡

讀進一張圖
PImage img=loadImage("bluerabbit.jpg");
size(250,128);    //設定視窗大小
image(img,0,0,250,128); //設定圖片大小跟位置(圖片大小會讓圖片拉伸)



*跟著滑鼠連續的圖片*

PImage img;
void setup(){
  img=loadImage("bluerabbit.jpg");
  size(600,600);
}
void draw(){
   image(img,mouseX,mouseY);
}




*做一個簡單的馬力歐程式*





↓成果




<可以修改程式碼去研究每個功用哦>



int [][]map={{0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,1,1,2,2,1,1,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {1,1,1,1,1,1,1,1,1,1,1,1,1,1},
             };
PImage img;
PImage brick;
PImage qmark;
void setup(){
   size(600,600);
  img=loadImage("mario.png");
  brick=loadImage("brick.png");
  qmark=loadImage("qmark.jpg");
}
float marioX=200,marioY=50,marioVY=0,marioVX=0;
boolean marioOnFloor=false;
void draw(){
  background(255); //redraw background
  for(int i=0;i<14;i++){
    for(int j=0;j<11;j++)
  {
    if(map[j][i]==1)image(brick,i*50,j*50,50,50);
    if(map[j][i]==2)image(qmark,i*50,j*50,50,50);}}
  image(img,marioX,marioY,100,100);
  marioY+=marioVY;
  marioX+=marioVX;
  marioVY+=0.98;
  if(marioY>=400) {marioY=400;marioVY=300;marioOnFloor=true;}
}
void keyPressed(){
  if(keyCode==UP && marioOnFloor){marioVY=-20;marioOnFloor=false;}
  if(keyCode==RIGHT) marioVX=15;
  if(keyCode==LEFT) marioVX=-15;
}
void keyReleased(){
  if(keyCode==RIGHT || keyCode==LEFT) marioVX=0;
}

2018年1月11日 星期四

40147027S-Week09

Bump Mapping

  1. https://www.openprocessing.org/sketch/249457 下載code
  2. 執行
Environment Mapping
  1. PImage img;

    void setup()
    {
       img=loadImage("banana.jpg");
       size(600,600);
    }

    void draw()
    {
    image(img,mouseX,mouseY);
    }

2018年1月10日 星期三

abcqq week9

1.Bump mapping
網址:https://www.openprocessing.org/sketch/24945 





























這是 javascript 用P語言寫的


2.在P語言中加入圖片:
程式碼:
PImage img=loadImage("123.jpg");
size(600,600);
image(img,0,0,600,600);


記得要有拖曳的動作,把圖檔拖進去視窗













3.讓圖片可以被滑鼠移動
程式碼:
PImage img;

void setup()
{
   img=loadImage("123.jpg");
   size(600,600);
}

void draw()
{
image(img,mouseX,mouseY);

}


4.馬力歐
PImage imgMario, imgMarioJump, imgBrick;
double marioX=200, marioY=100;
double marioVX=0, marioVY=0;
boolean marioOnFloor = false;
int [][]map = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
               {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
               {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
               {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
               {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
               {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
               {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
               {0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0},
               {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
               {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
               {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
               {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};

void setup(){
  size(800,600);
  imgMario = loadImage("mario.jpg");
  imgMarioJump = loadImage("mariojump.png");
  imgBrick = loadImage("brick.png");
}
void draw(){
  background(255);
  if (map[(int)(marioY/50)][(int)(marioX/50)] != 0){
    marioOnFloor = true;
  }
  if (marioOnFloor == false){
    marioVY += 0.98;
  }
  else if (marioOnFloor == true){
    marioVY = 0;
  }  
  for (int x=0; x<16; x++){
    for (int y=0; y<12; y++){
      if (map[y][x] == 1)
        image(imgBrick, x*50, y*50, 50, 50);
    }
  }
  
  marioX += marioVX;
  marioY += marioVY;
  image(imgBrick, marioX, marioY, 50, 50);
  //image(imgMario, marioX, marioY, 100,100);
}

void keyPressed(){
  if (keyCode == UP)
      marioVY = -15;
  if (keyCode == LEFT)
      marioVX = -5;
  if (keyCode == RIGHT)
      marioVX = 5;
}
void keyReleased(){
  if (keyCode == LEFT || keyCode == RIGHT)
      marioVX = 0;
}

2018年1月4日 星期四

魏建新的第九週學題單

  1. 上週Texture 貼圖、詳解
  2. 多重貼圖
  3. Bump Mapping

在MOODLE的上課軟體下載processing-3.3.6-windows64.zip打開

程式碼:
先RUN網友的程式碼:https://www.openprocessing.org/sketch/249457
把網路的程式碼COPY到processing

PImage img=loadImage("doraemon.jpeg"); 注載入圖片用 doraemon.jpeg為你要用的圖片名
size(600, 600);
image(img, 0,0, 600,600);

PImage img; 注用來呈現中BUG的圖片
void setup(){
  size(1280, 800);
  img=loadImage("error.jpg");
}

void draw(){
  //rect(mouseX, mouseY, 50, 50);  <- 用來畫正方形的碼
  image(img, mouseX,mouseY, 400,250);
}

魏建新的第七週學題單

(1)作業二展示,互評(2)主題: Mouse,Model,打光 ->用mouse調光源(3)主題: Lighting打光,Shading光影




程式碼:void motion(int x,int y){
    light_position[0]= (x-150)/150.0*2;
    light_position[1]= -(y-150)/150.0*2;
    glLightfv(GL_LIGHT0,GL_POSITION,light_position);
    glutPostOverlayRedisplay();
}

GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };  注:剛孕const 

圖例:


2017年12月21日 星期四

[耍廢]WEEK09

1.p語言
至moodle下載processing-3.3.6-windows64.zip
解壓縮後執行如下





Bump Mapping 凹凸貼圖 

https://www.openprocessing.org/sketch/249457
code來源

// Processing.jsでバンプマッピング

BumpMappedBox myBox;
void setup() {
  size(200, 200, P3D);

  myBox = new BumpMappedBox(100,
    createTexture(),
    createHeightMapImage());
}

void draw() {
  background(0xff);
  camera();
  noStroke();
  pushMatrix();
    translate(.5 * width, .5 * height);

    float baseAngle = radians(millis() * 0.015);
    rotateX(baseAngle);
    rotateZ(baseAngle);
    rotateY(baseAngle);
   
    myBox.render();  
  popMatrix();
}

PImage createTexture() {
  
  int step = 0x20;
  PImage tex = createImage(0x80, 0x80, RGB);
  tex.loadPixels();
  
  for(int i = 0; i < tex.width; i++) {
    for(int j = 0; j < tex.height; j++) {
      tex.set(i, j, 
        (floor(i / step) + floor(j / step)) % 2 == 0 ?
          color(0xcc) : color(0xff));
    }
  }
  tex.updatePixels();
  return tex;
}

PImage createHeightMapImage() {
  int step = 0x20;
  PImage tex = createImage(0x80, 0x80, RGB);
  tex.loadPixels();
  
  for(int i = 0; i < tex.pixels.length; i++) {
    tex.pixels[i] = color(0xfff - random(255));//與原code不同處
  }
  for(int i = step; i < tex.width -1; i += step) {
    for(int j = 0; j < tex.height; j++) {
      tex.pixels[i + j * tex.width] = 0xff << 0x16;
    }
  }
  for(int i = 0; i < tex.width; i++) {
    for(int j = step; j < tex.height; j += step) {
      tex.pixels[i + j * tex.width] = 0xff << 0x16;
    }
  }
  tex.updatePixels();
  return tex;
}

// ----------------------------------------

interface Renderable {
  void render();
}

// ----------------------------------------

abstract class RenderHelper implements Renderable {
  private final int NUM_TEXTURE_COORDS_DEFAULT = 4;

  protected final int DIFFUSE_COLOR   = 0x7f;
  protected final PVector LIGHT_DIRECTION = new PVector(0, 0, -1);
  protected final PVector ZERO_VECTOR     = new PVector(0, 0, 0);

  protected PVector eyePoint = new PVector(.5 * width, 
                                           .5 * height, 
                                           .5 * height / tan(PI / 6.0));
  protected PVector _origin = new PVector();
  protected PVector _normal = new PVector();
  protected PImage  _originalTexture;

  protected PVector[] _worldVertices;
  protected PVector[] _localVertices;
  protected PVector[] _originalTextureCoords;

  private PImage  _texture;
  private boolean _isBack = false;
  
  public abstract void render();
  
  public void setEyePoint(PVector p) {
    if(p != null) {
      eyePoint.set(p);
    } else {
      setEyePoint(0, 0, 0);
    }
  }
  public void setEyePoint(float x, float y, float z) {
    eyePoint.set(x, y, z);
  }
  
  protected void initVertices(int numVertices) {
    if(numVertices < 1) return;
    
    _worldVertices = new PVector[numVertices];
    _localVertices = new PVector[numVertices];
    
    for(int i = 0; i < numVertices; i++) {
      _worldVertices[i] = new PVector();
      _localVertices[i] = new PVector();
    }
  }
  
  protected void initTextureCoords() {
    _originalTextureCoords = new PVector[NUM_TEXTURE_COORDS_DEFAULT];
    for(int i = 0; i < _originalTextureCoords.length; i++) {
      _originalTextureCoords[i] = new PVector(i < NUM_TEXTURE_COORDS_DEFAULT / 2        ? 0 : 1, 
                                      i % (NUM_TEXTURE_COORDS_DEFAULT - 1) == 0 ? 0 : 1);
    }
  }
  
  protected void initTextureCoords(int numVertices) {
    _originalTextureCoords = new PVector[numVertices];
    
    for(int i = 0; i < numVertices; i++) {
      _originalTextureCoords[i] = new PVector();
    }
  }
  
  protected PVector[] updateWorldVertices(PVector[] localVertices, PVector[] destWorldVertices) {
    for(int i = 0; i < destWorldVertices.length; i++) {
      updateWorldVertex(localVertices[i], destWorldVertices[i]);
    }
    return destWorldVertices;
  }
  
  protected PVector[] updateWorldVertices() {
    return updateWorldVertices(_localVertices, _worldVertices);
  }
  
  protected PVector updateWorldVertex(PVector localVertex, PVector destWorldVertex) {
    destWorldVertex.set(
      modelX(localVertex.x, localVertex.y, localVertex.z), 
      modelY(localVertex.x, localVertex.y, localVertex.z),
      modelZ(localVertex.x, localVertex.y, localVertex.z));      
    return destWorldVertex;
  }
  
  protected PVector updateWorldVertex(PVector localVertex) {
    return new PVector (
      modelX(localVertex.x, localVertex.y, localVertex.z), 
      modelY(localVertex.x, localVertex.y, localVertex.z),
      modelZ(localVertex.x, localVertex.y, localVertex.z));      
  }
  
  protected PVector updateOrigin(PVector center) {
    updateWorldVertex(center, _origin);
    return _origin;
  }
  
  protected PVector updateOrigin() {
    return updateOrigin(ZERO_VECTOR);
  }
  
  protected PVector updateNormalVector(PVector v1, PVector v2) {
    _normal.set(v1.cross(v2));
    _normal.normalize();
    return _normal;
  }
  
  private PVector _ = new PVector();
  protected int getDefaultTintColor() {
    subVec(_origin, eyePoint, _);
    _isBack = 0 < _normal.dot(_);
    float arg = (_isBack ? 1.0 : -1.0) * _normal.dot(LIGHT_DIRECTION);
    return (int)(arg * (0xff - DIFFUSE_COLOR) + DIFFUSE_COLOR);
  }
  
  protected void subVec(PVector p1, PVector p2, PVector dest) {
    dest.set(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z);
  }
  

  protected void renderWithoutShade(PVector[] worldVertices, PVector[] textureCoords) {
    if(!checkArgsBeforeRender(_originalTexture, 
                              worldVertices, 
                              textureCoords)) return;
    getDefaultTintColor();
    if(_isBack) return;
    
    if(!setupRenderTexture()) return;
    _texture.resize(_texture.width, _texture.height);
    renderMain(0xff, _texture, worldVertices, textureCoords);
  }
  
  protected void renderWithShade(PVector[] worldVertices, PVector[] textureCoords) {
    if(!checkArgsBeforeRender(_originalTexture, 
                              worldVertices, 
                              textureCoords)) return;

    int tintColor = getDefaultTintColor();
    if(_isBack) return;
    renderMain(tintColor, _originalTexture, worldVertices, textureCoords);
  }

  private boolean checkArgsBeforeRender(PImage originalTexture, PVector[] worldVertices, PVector[] textureCoords) {
    if(_originalTexture == null || worldVertices == null || textureCoords == null) return false;
    if(textureCoords.length < worldVertices.length) return false;
    if(_originalTexture.get(0, 0) == 0) return false;
    return true;
  }
  
  private boolean setupRenderTexture() {
    // 毎回 createImage しないとうまくレンダリングされない...    
    _texture = createImage(_originalTexture.width, _originalTexture.height, RGB);
    
    updateTexture(_originalTexture, _texture);
    return !(_texture == null || _texture.get(0, 0) == 0);
  }
  
  protected void updateTexture(PImage originalTexture, PImage destUpdatedTexture) {
    destUpdatedTexture.loadPixels();
    for(int i = 0; i < originalTexture.pixels.length; i++) {
      destUpdatedTexture.pixels[i] = originalTexture.pixels[i];
    }
    destUpdatedTexture.updatePixels();
  }
  
  private void renderMain(int tintColor, PImage textureImage, PVector[] worldVertices, PVector[] textureCoords) {
    pushMatrix();
      resetMatrix();
      camera();
      noLights();
      beginShape();
        textureMode(NORMAL);
        texture(textureImage);
        tint(tintColor);
        for(int i = 0; i < worldVertices.length; i++) {
          vertex(worldVertices[i].x, worldVertices[i].y, worldVertices[i].z, 
                 textureCoords[i].x, textureCoords[i].y);
        }
      endShape(CLOSE);
    popMatrix();    
  }
  
  protected void renderWithShade() {
    renderWithShade(_worldVertices, _originalTextureCoords);
  }
  
  protected void renderWithoutShade() {
    renderWithoutShade(_worldVertices, _originalTextureCoords);
  }
}

// ----------------------------------------

class BoxWithTexture extends RenderHelper {
  protected final int NUM_VERTICES    = 8;
  protected final int NUM_PLANES      = 6;
  protected final int NUM_SIDE_PLANES = 4;
  protected final int NUM_VERTICES_PER_PLANE = 4;
  
  protected float _width;
  protected float _height;
  protected float _depth;
  
  protected PVector[]   _centers = new PVector[NUM_PLANES];
  protected PVector[][] _surface = new PVector[NUM_PLANES][NUM_VERTICES_PER_PLANE];  
  
  public BoxWithTexture(float size, PImage tex) {
    this(size, size, size, tex);
  }
  
  public BoxWithTexture(float w, float h, float d, PImage tex) {
    _width   = w;
    _height  = h;
    _depth   = d;
    _originalTexture = tex;  

    setupSurface();
  }
  
  private void setupSurface() {
    float halfWidth  = .5 * _width;
    float halfHeight = .5 * _height;
    float halfDepth  = .5 * _depth;
    
    initTextureCoords();
    initVertices(NUM_VERTICES);
    for(int i = 0; i < NUM_VERTICES; i++) {
      int j = i < NUM_VERTICES_PER_PLANE ? 
                i : i - NUM_VERTICES_PER_PLANE;
                
      _localVertices[i].set(j % 3 == 0 ? -halfWidth  : halfWidth, 
                            i < 4      ? -halfHeight : halfHeight,
                            i % 4 < 2  ? -halfDepth  : halfDepth);
    }
    
    setupSide(halfWidth, halfDepth);
    setupTopAndBottom(halfHeight);

  }
  
  private void setupSide(float halfWidth, float halfDepth) {
    for(int i = 0; i < NUM_SIDE_PLANES; i++) {
      float _x = halfWidth * (i % 2 == 0 ? 0 : i < 2 ?  1 : -1);
      float _z = halfDepth * (i % 2 != 0 ? 0 : i < 2 ? -1 :  1);
      _centers[i] = new PVector(_x, 0, _z);

      for(int j = 0; j < NUM_VERTICES_PER_PLANE; j++) {        
        int surplus = j % (NUM_VERTICES_PER_PLANE - 1);
        int index = surplus != 0 ? 
                    (i + surplus + (NUM_VERTICES_PER_PLANE - 1)) % 
                      NUM_VERTICES_PER_PLANE + 
                        NUM_VERTICES_PER_PLANE :
                    (i + (j < NUM_VERTICES_PER_PLANE / 2 ? 0 : 1)) % 
                      NUM_VERTICES_PER_PLANE;
        _surface[i][j] = _worldVertices[index];
      }
    }
  }
  
  private void setupTopAndBottom(float halfHeight) {
    for(int i = NUM_SIDE_PLANES; i < _centers.length; i++) {
      float _y = halfHeight * (i == NUM_SIDE_PLANES ? -1 : 1);
      _centers[i] = new PVector(0, _y, 0);
      
      for(int j = 0; j < NUM_VERTICES_PER_PLANE; j++) {        
        int index = i == NUM_SIDE_PLANES ? j : NUM_VERTICES - (j + 1);
        _surface[i][j] = _worldVertices[index];
      } 
    }
  }
  
  public void render() {
    updateWorldVertices();
    for(int i = 0; i < _surface.length; i++) {
      updateOrigin(_centers[i]);       
      updateNormalVector(PVector.sub(_surface[i][1], _surface[i][0]), 
                         PVector.sub(_surface[i][3], _surface[i][0]));
      renderWithShade(_surface[i], _originalTextureCoords);
    }
  }
}

// ----------------------------------------

class BumpMappedPlane extends RenderHelper { 
  private final int NUM_VERTICES = 4;

  private float  _width;
  private float  _height;
  private PImage _heightMap;
  private PVector[][] _normalMap; // 法線マップ
  
  public BumpMappedPlane(float w, float h, PImage tex, PImage hMap) {
    _width   = w;
    _height  = h;
    
    _originalTexture = tex;  
    _heightMap       = hMap;

    float halfWidth  = .5 * _width;
    float halfHeight = .5 * _height;
    
    initTextureCoords();
    initVertices(NUM_VERTICES);
    for(int i = 0; i < NUM_VERTICES; i++) {
      _localVertices[i].set(i < 2      ? -halfWidth  : halfWidth, 
                            i % 3 == 0 ? -halfHeight : halfHeight, 0);
    }
  }
  
  PVector _worldNormal = new PVector();
  PImage  _dummyTexture;
  
  public void render() {
    if(_originalTexture.get(0, 0) != 0) {
      if (_normalMap == null) {
        _normalMap = createNormalMap(_heightMap);
      }
    }

    updateOrigin();
    updateWorldVertices();
    updateNormalVector(PVector.sub(_worldVertices[1], _worldVertices[0]), 
                       PVector.sub(_worldVertices[3], _worldVertices[0]));
    renderWithoutShade();
  }
  
  protected PVector zeroVec = new PVector();
  
  protected void updateTexture(PImage originalTexture, PImage destUpdatedTexture) {
    destUpdatedTexture.loadPixels();
    int imgWidth = destUpdatedTexture.width;

    for(int i = 0; i < _normalMap.length; i++) {
      for(int j = 0; j < _normalMap[0].length; j++) {
        updateWorldVertex(_normalMap[i][j], _worldNormal);
        _worldNormal.sub(_origin);
        float arg = _worldNormal.dot(LIGHT_DIRECTION);
        
        float coef = (arg * (0xff - DIFFUSE_COLOR) / 0xff) + (DIFFUSE_COLOR / 0xff);
        int originalColor = originalTexture.pixels[j * imgWidth + i];
        int b = (int)(coef * (originalColor         & 0xff));
        int g = (int)(coef * (originalColor >>  0x8 & 0xff));
        int r = (int)(coef * (originalColor >> 0x10 & 0xff));
        
        destUpdatedTexture.pixels[j * imgWidth + i] = 0xff << 0x18 | r << 0x10 | g << 0x8 | b;
      }
    }
    destUpdatedTexture.updatePixels();
  }
  
  private float dU(PImage heightMap, int i, int j) {
    if(i < 1) return dU(heightMap, 1, j);
    if(!(i < heightMap.width-1)) return dU(heightMap, heightMap.width - 2, j);

    return .5 * (getHeight(heightMap, i+1,j) - getHeight(heightMap, i-1,j));
  }
  
  private float dV(PImage heightMap, int i, int j) {
    if(j < 1) return dV(heightMap, i, 1);
    if(!(j < heightMap.height-1)) return dV(heightMap, i, heightMap.height - 2);

    return .5 * (getHeight(heightMap, i, j+1) - getHeight(heightMap, i,j-1));
  }
  
  private int getHeight(PImage heightMap, int i, int j) {
    return 0xff & heightMap.pixels[i + j * heightMap.width];
  }
  
  private PVector[][] createNormalMap(PImage heightMapImage) {
    int mapWidth  = heightMapImage.width;
    int mapHeight = heightMapImage.height;
    
    PVector[][] normalMap = new PVector[mapWidth][mapHeight];
    PVector v1 = new PVector();
    PVector v2 = new PVector();
    
    for(int i = 0; i < mapWidth; ++i) {
      for(int j = 0; j < mapHeight; ++j) {
                 
        v1.set(1.0, 0, dU(heightMapImage, i, j));
        v1.normalize();
        v2.set(0, 1.0, dV(heightMapImage, i, j));
        v2.normalize();

        normalMap[i][j] = v1.cross(v2);
        normalMap[i][j].normalize();
      }
    }
    return normalMap;
  }
}

// ----------------------------------------

class BumpMappedBox implements Renderable {
  private BumpMappedPlane[] _surface = new BumpMappedPlane[6];
  private float _size;
  
  BumpMappedBox(float boxSize, PImage tex, PImage hMap) {
    _size = boxSize;
    for(int i = 0; i < 6; i++) {
      _surface[i] = new BumpMappedPlane( _size, _size, tex, hMap);
    }
  }
 
  void render() {
    pushMatrix();
    for(int i = 0; i < 4; i++) {
      rotateY(i * HALF_PI);
      
      pushMatrix();
      translate(0, 0, -.5 * _size);
      _surface[i].render();
      popMatrix();
    }
    popMatrix();

    pushMatrix();
      rotateX(HALF_PI);
      for(int i = 4; i < 6; i++) {
        rotateX(i * PI);   
        pushMatrix();
          translate(0, 0, -.5 * _size);
          _surface[i].render();
        popMatrix();
      }
    popMatrix();
  }
}

執行結果




Environment Mapping 環境貼圖

下載一張圖片並匯入processing 3中
PImage img;

void setup(){
  // setting window size
  size(1280, 800);
  
  // processing image load a image
  img = loadImage("a.PNG");
}

void draw(){
  // show image ( image, x, y, width, height)
  image(img, mouseX, mouseY);//圖隨滑鼠移動
}
結果

3.簡易馬力歐遊戲


找瑪莉歐,問號方塊和普通磚塊的圖,存為mario, brick1, brick2
並複製以下程式碼貼上
int [][]map={{0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,1,1,2,2,1,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
             {1,1,1,1,1,1,1,1,1,1,1,1,1,1}};

PImage imgMario, imgBrick, imgBrick2;
void setup(){
  size(800, 600);
  imgMario=loadImage("mario.png");
  imgBrick=loadImage("brick.png");
  imgBrick2=loadImage("brick2.png");
}

float marioX=200, marioY=100, marioVX=0, marioVY=0;
boolean marioOnFloor=false;
void draw(){
  background(255);
  for(int x=0;x<14;x++){
    for(int y=0;y<11;y++){
      if(map[y][x]==1) image(imgBrick, x*50, y*50, 50,50);
      if(map[y][x]==2) image(imgBrick2, x*50, y*50, 50,50);
    }
  }
  image(imgMario, marioX, marioY, 50,50);
  marioY += marioVY; marioX += marioVX;
  marioVY += 0.98;
  if(marioY>=500-50)
  {marioY=500-50; marioVY=0; marioOnFloor=true;}
}
void keyPressed(){
  if(keyCode==UP && marioOnFloor) {marioVY=-15; marioOnFloor=false;}
  if(keyCode==RIGHT) marioVX=5;
  if(keyCode==LEFT) marioVX=-5;
}
void keyReleased(){
  if(keyCode==RIGHT || keyCode==LEFT) marioVX=0;
}