Esempio n. 1
0
void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // „Ƕ„Ç£„É≥„Éâ„Ƕ„ÅÆËÉåÊôØ„Çí°ó„Çä„ŧ„Å∂„Å? & Èö†Èù¢Âá¶ÁêÅEÇíÂèØËÉΩ„Å´„Åô„Çã
    glEnable(GL_DEPTH_TEST);    // Èö†Èù¢Âá¶ÁêÅEñãÂß?
    glEnable(GL_NORMALIZE);
    glEnable(GL_LIGHTING);
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
    
    glPushMatrix();
    glTranslatef(0.0, 1.0, 0.0);
    polarview();    // „Éù„ÅE„É©„ɺ„Éì„É•„ɺ„Å∏„ÅÆ„Éì„É•„ɺ„ǧ„É≥„Ç∞§âÊèõ
    glPushMatrix();
    glLightfv(GL_LIGHT0, GL_POSITION, light0);
    glPopMatrix();
    
    shading(5);
    drawGround2D();
    
    shading(6);
    glDisable(GL_LIGHTING);
    drawGrass();
    glEnable(GL_LIGHTING);
    
    shading(5);
    drawPlant();
    
    if (rainFlag == GL_TRUE)
        drawRain();
    
    glDisable(GL_LIGHTING);
    
    glDisable(GL_DEPTH_TEST);
    
    drawCloud();
    
    if (thunderFlag == GL_TRUE && rainFlag == GL_TRUE) {
        if (lightningnum == 0 || lightningnum == 4)
            lightning();
        lightningnum++;
        if (lightningnum == 5) {
            lightningnum = 0;
            thunderFlag = GL_FALSE;
        }
        if (rand() % 10 == 4)
            fallFlag = GL_TRUE;
    }
    else thunderFlag = GL_FALSE;
    
    glPopMatrix();
    glutSwapBuffers();
}
Esempio n. 2
0
bool SceneNode::hit(const Ray& ray, double &tmin, Shading &s) {
    // transform ray so in object co-ordinates
    Ray local_ray(ray);
    local_ray.direction = m_invtrans * ray.direction;
    local_ray.origin = m_invtrans * ray.origin;

    Shading shading(s.world);
    double t;
    tmin = 10E24;
    Vector3D normal;
    Material *mat;
    for (ChildList::const_iterator it = m_children.begin(); it != m_children.end(); it++) {
        
        SceneNode *object = (*it);
        if (object->hit(local_ray, t, shading) && (t < tmin)) {
            tmin = t;
            normal = shading.hit_normal;
            mat = shading.material;
        }
    }

    if (shading.hit_object) {
        s.hit_object = true;
        s.t = tmin;
        s.hit_normal = m_invtrans.transpose() * normal;
        s.material = mat;
        return true;
    }
    return false;
}
Esempio n. 3
0
bool Mesh::hit(const Ray& ray, double &tmin, Shading &s) const
{
    Ray local_ray(ray);
    Shading shading(s.world);
    double t;
    tmin = 10E24;
    Vector3D normal;

    // check bounding box first
    Shading shading2(s.world);
    bool was_bound = m_boundbox->hit(ray,tmin,shading2);
    if (!m_boundbox->hit(ray,tmin,shading2)) {
        return false;
    }

    tmin = 10E24;
    for (unsigned int i=0; i<m_triangles.size(); i++) {
        
        Triangle triangle = m_triangles[i];
        if (triangle.hit(local_ray, t, shading) && (t < tmin)) {
            shading.hit_object = true;
            tmin = t;
            normal = shading.hit_normal;
        }
    }

    if (shading.hit_object) {
        s.hit_object = true;
        s.t = tmin;
        s.hit_normal = normal;
        return true;
    }
    return false;

}
Esempio n. 4
0
// Ray tracing
int rayTracing(Ray ray, SPHERE sphere, POLY4 poly, float lrp[3], float ip)
{
	float P;
	Point3dPtr n;
	Point3dPtr interp;

	int C;
	float * kd = (float*)malloc(sizeof(*kd));

	n = (Point3dPtr)malloc(sizeof(Point3d));
	interp = (Point3dPtr)malloc(sizeof(Point3d));

	P = rayObjectIntersection(ray, sphere, poly, n, interp, kd);

	if (P != 0.0)
	{
		C = shading(lrp, n, interp, kd, ip);
		return C;
	}
	else
		return 0;
	free(n);
	free(interp);
	free(kd);
}
Esempio n. 5
0
Material::Material(Material_t tag)
    : tag(tag),
      vertexShader(this),
      fragmentShader(this),
      index0AttributeName(this)
{
    mId = Material::MaterialIdCount++;

    mUuid = Math::generateUUID();

    mName = "";

    side() = kFrontSide;

    opacity() = 1.0f;
    transparent() = false;

    blending() = kNormalBlending;

    blendSrc() = kSrcAlphaFactor;
    blendDst() = kOneMinusSrcAlphaFactor;
    blendEquation() = kAddEquation;

    depthTest() = true;
    depthWrite() = true;

    polygonOffset() = false;
    polygonOffsetFactor() = 0;
    polygonOffsetUnits() = 0;

    // mAlphaTest = 0;

    overdraw() = 0; // Overdrawn pixels (typically between 0 and 1) for fixing antialiasing gaps in CanvasRenderer

    visible() = true;

    needsUpdate() = true;

    // By default, bind position to attribute index 0. In WebGL, attribute 0
    // should always be used to avoid potentially expensive emulation.
    index0AttributeName("position");

    linewidth() = 1.0f;
    metal() = false;
    perPixel() = true;
    shading() = kNoShading;
	vertexColors() = kNoColors;
    wireframe() = false;
    wireframeLinewidth() = 1.0f;
}
Esempio n. 6
0
// OpenGL initialization
void init() {

    program = glCreateProgram();
    // Load shaders and use the resulting shader program
    Shader shading(program, "glsl/shader.vert", "glsl/shader.frag");

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glCullFace(GL_BACK);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    // initally create a cube
    r1 = Rectangle(xyz<GLfloat>{-0.5, +0.5, +0.0}, xyz<GLfloat>{-0.5, -0.5, +0.0},
                   xyz<GLfloat>{+0.5, -0.5, +0.0}, xyz<GLfloat>{+0.5, +0.5, +0.0});

    r2 = Rectangle(xyz<GLfloat>{-0.25, +0.25, +0.0}, xyz<GLfloat>{-0.25, -0.25, +0.0},
                   xyz<GLfloat>{+0.25, -0.25, +0.0}, xyz<GLfloat>{+0.25, +0.25, +0.0});
}
Esempio n. 7
0
void CFWL_WidgetTP::DrawAxialShading(CFX_Graphics* pGraphics,
                                     FX_FLOAT fx1,
                                     FX_FLOAT fy1,
                                     FX_FLOAT fx2,
                                     FX_FLOAT fy2,
                                     FX_ARGB beginColor,
                                     FX_ARGB endColor,
                                     CFX_Path* path,
                                     int32_t fillMode,
                                     CFX_Matrix* pMatrix) {
  if (!pGraphics || !path)
    return;

  CFX_PointF begPoint(fx1, fy1);
  CFX_PointF endPoint(fx2, fy2);
  CFX_Shading shading(begPoint, endPoint, false, false, beginColor, endColor);
  pGraphics->SaveGraphState();
  CFX_Color color1(&shading);
  pGraphics->SetFillColor(&color1);
  pGraphics->FillPath(path, fillMode, pMatrix);
  pGraphics->RestoreGraphState();
}
Esempio n. 8
0
CalibrationData CalibratorLocHom::calibrate()
{
    QSettings settings("SLStudio");

    //Checkerboard parameters
    float checkerSize = settings.value("calibration/checkerSize").toFloat();
    std::cout << "checkerSize== "<< checkerSize <<std::endl;
    unsigned int checkerRows = settings.value("calibration/checkerRows").toInt();
    unsigned int checkerCols = settings.value("calibration/checkerCols").toInt();

    // Number of saddle points on calibration pattern
    cv::Size patternSize(checkerCols,checkerRows);

    // Number of calibration sequences
    unsigned nFrameSeq = frameSeqsFromFile.size();

    vector<cv::Mat> up(nFrameSeq), vp(nFrameSeq), shading(nFrameSeq), mask(nFrameSeq);

    // Decode frame sequences
    std::cout << "Decode frames: Num="<< nFrameSeq<< ", and begin.....>> ";
    for(unsigned int i=0; i<nFrameSeq; i++)
    {
        //vector<cv::Mat> frames = frameSeqs[i];
        vector<cv::Mat> frames;
        vector<std::string> framesFromFile= frameSeqsFromFile[i];
        for(unsigned int m=0; m<framesFromFile.size();m++)
        {
            cv::Mat curFrame = cv::imread(framesFromFile[m],CV_LOAD_IMAGE_GRAYSCALE);            
            curFrame = curFrame.clone();
            frames.push_back(curFrame);
        }

        for(unsigned int f=0; f<frames.size(); f++){
            decoder->setFrame(f, frames[f]);
            #if 0
                cv::imwrite(QString("m_frames_%1_%2.png").arg(i,2,10,QChar('0')).arg(f).toStdString(), frames[f]);
            #endif
        }

        decoder->decodeFrames(up[i], vp[i], mask[i], shading[i]);

        std::cout << i << ",";

        #if 0
            cvtools::writeMat(shading[i], QString("shading[%1].mat").arg(i).toLocal8Bit());
            cvtools::writeMat(up[i], QString("up[%1].mat").arg(i).toLocal8Bit());
            cvtools::writeMat(vp[i], QString("vp[%1].mat").arg(i).toLocal8Bit());
        #endif
    }
    std::cout << "-->end||."<<std::endl;

    unsigned int frameWidth = up[0].cols;
    unsigned int frameHeight = up[0].rows;

    // Generate local calibration object coordinates [mm]
    std::cout << "Generate local calibration object coordinates"<<std::endl;
    vector<cv::Point3f> Qi;
    for (int h=0; h<patternSize.height; h++)
        for (int w=0; w<patternSize.width; w++)
            Qi.push_back(cv::Point3f(checkerSize * w, checkerSize* h, 0.0));

    // Find calibration point coordinates for camera and projector
    std::cout<< "Find calibration point coordinates for camera and projector!" <<std::endl;

    vector< vector<cv::Point2f> > qc, qp;
    vector< vector<cv::Point3f> > Q;

    for(unsigned int i=0; i<nFrameSeq; i++)
    {

        //std::cout << i << " 1" << std::endl;
        vector<cv::Point2f> qci;
        // Aid checkerboard extraction by slight blur
        //cv::GaussianBlur(shading[i], shading[i], cv::Size(5,5), 2, 2);
        // Extract checker corners

        std::cout << i << ": findChessboardCorners......" << std::endl;
        bool success = cv::findChessboardCorners(shading[i], patternSize, qci,
                                                 cv::CALIB_CB_ADAPTIVE_THRESH+CV_CALIB_CB_NORMALIZE_IMAGE+CALIB_CB_FAST_CHECK );
        std::cout << " cv::findChessboardCorners: sucess = " << success << std::endl;

        if(!success)
            std::cout << "Calibrator: could not extract chess board corners on frame seqence " << i << std::endl << std::flush;
        else
        {
            std::cout << i << ": cornerSubPix......" << std::endl;
            // Refine corner locations
            cv::cornerSubPix(shading[i], qci, cv::Size(5, 5), cv::Size(1, 1),
                             cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 20, 0.01));
        }
        // Draw colored chessboard
        cv::Mat shadingColor;
        cv::cvtColor(shading[i], shadingColor, cv::COLOR_GRAY2RGB);
        cv::drawChessboardCorners(shadingColor, patternSize, qci, success);

#if 1
        QString filename = QString("am_shadingColor%1.bmp").arg(i, 2, 10, QChar('0'));
        cv::imwrite(filename.toStdString(), shadingColor);
//        filename = QString("am_shadingColor%1.png").arg(i, 2, 10, QChar('0'));
//        cv::imwrite(filename.toStdString(), shadingColor);
#endif

        //Emit chessboard results
        emit newSequenceResult(shadingColor, i, success);

        if(success)
        {
            // Vectors of accepted points for current view
            vector<cv::Point2f> qpi_a;
            vector<cv::Point2f> qci_a;
            vector<cv::Point3f> Qi_a;

            // Loop through checkerboard corners
            for(unsigned int j=0; j<qci.size(); j++)
            {

                const cv::Point2f &qcij = qci[j];

                // Collect neighbor points
                const unsigned int WINDOW_SIZE = 10;
                std::vector<cv::Point2f> N_qcij, N_qpij;

                // avoid going out of bounds
                unsigned int starth = max(int(qcij.y+0.5)-WINDOW_SIZE, 0u);
                unsigned int stoph  = min(int(qcij.y+0.5)+WINDOW_SIZE, frameHeight-1);
                unsigned int startw = max(int(qcij.x+0.5)-WINDOW_SIZE, 0u);
                unsigned int stopw  = min(int(qcij.x+0.5)+WINDOW_SIZE, frameWidth-1);

                for(unsigned int h=starth; h<=stoph; h++)
                {
                    for(unsigned int w=startw; w<=stopw; w++)
                    {
                        // stay within mask
                        if(mask[i].at<bool>(h,w))
                        {
                            N_qcij.push_back(cv::Point2f(w, h));

                            float upijwh = up[i].at<float>(h,w);
                            float vpijwh = vp[i].at<float>(h,w);
                            N_qpij.push_back(cv::Point2f(upijwh, vpijwh));
                        }
                    }
                }
                //std::cout << i << " findHomography " << N_qcij.size() << " " << N_qpij.size() << std::endl;
                // if enough valid points to build homography
                if(N_qpij.size() >= 50)
                {
//                    std::cout << i << " findHomography" << std::endl;
                    // translate qcij into qpij using local homography
                    cv::Mat H = cv::findHomography(N_qcij, N_qpij, cv::LMEDS);
                    if(!H.empty())
                    {
                        cv::Point3d Q = cv::Point3d(cv::Mat(H*cv::Mat(cv::Point3d(qcij.x, qcij.y, 1.0))));
                        cv::Point2f qpij = cv::Point2f(Q.x/Q.z, Q.y/Q.z);

                        qpi_a.push_back(qpij);
                        qci_a.push_back(qci[j]);
                        Qi_a.push_back(Qi[j]);
                    }
                }
            }

            if(!Qi_a.empty())
            {
                // Store projector corner coordinates
                qp.push_back(qpi_a);

                // Store camera corner coordinates
                qc.push_back(qci_a);

                // Store world corner coordinates
                Q.push_back(Qi_a);
            }
        }
    }

    if(Q.size() < 1){
        std::cerr << "Error: not enough calibration sequences!" << std::endl;
        CalibrationData nanData;
        return nanData;
    }

    //calibrate the camera
    std::cout<< "calibrate the camera!" <<std::endl;

    cv::Mat Kc, kc;
    std::vector<cv::Mat> cam_rvecs, cam_tvecs;
    cv::Size frameSize(frameWidth, frameHeight);
    double cam_error = cv::calibrateCamera(Q, qc, frameSize, Kc, kc, cam_rvecs, cam_tvecs, cv::CALIB_FIX_ASPECT_RATIO + cv::CALIB_FIX_PRINCIPAL_POINT + cv::CALIB_FIX_K2 + cv::CALIB_FIX_K3 + cv::CALIB_ZERO_TANGENT_DIST,
                                           cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 50, DBL_EPSILON));

    //calibrate the projector
    std::cout<< "calibrate the projector!" <<std::endl;
    cv::Mat Kp, kp;
    std::vector<cv::Mat> proj_rvecs, proj_tvecs;
    cv::Size screenSize(screenCols, screenRows);
    double proj_error = cv::calibrateCamera(Q, qp, screenSize, Kp, kp, proj_rvecs, proj_tvecs, cv::CALIB_FIX_ASPECT_RATIO + cv::CALIB_FIX_K2 + cv::CALIB_FIX_K3 + cv::CALIB_ZERO_TANGENT_DIST,
                                            cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 50, DBL_EPSILON));

    //stereo calibration
    std::cout<< "stereo calibrate!" <<std::endl;
    cv::Mat Rp, Tp, E, F;
    //Opencv2.x version
    //double stereo_error = cv::stereoCalibrate(Q, qc, qp, Kc, kc, Kp, kp, frameSize, Rp, Tp, E, F,
      //                                        cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 100, DBL_EPSILON), cv::CALIB_FIX_INTRINSIC);

    //Opencv3.x version
    double stereo_error = cv::stereoCalibrate(Q, qc, qp, Kc, kc, Kp, kp, frameSize, Rp, Tp, E, F,
                                              cv::CALIB_FIX_INTRINSIC,cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 100, DBL_EPSILON));

    CalibrationData calData(Kc, kc, cam_error, Kp, kp, proj_error, Rp, Tp, stereo_error);

    calData.print(std::cout);

    // Determine per-view reprojection errors:
    std::vector<float> cam_error_per_view(Q.size());
    cam_error_per_view.resize(Q.size());
    std::vector<float> proj_error_per_view(Q.size());
    proj_error_per_view.resize(Q.size());
    for(unsigned int i = 0; i < (unsigned int)Q.size(); ++i){
        int n = (int)Q[i].size();

        vector<cv::Point2f> qc_proj;
        cv::projectPoints(cv::Mat(Q[i]), cam_rvecs[i], cam_tvecs[i], Kc, kc, qc_proj);
        float err = 0;
        for(int j=0; j<qc_proj.size(); j++){
            cv::Point2f d = qc[i][j] - qc_proj[j];
            err += cv::sqrt(d.x*d.x + d.y*d.y);
        }
        cam_error_per_view[i] = (float)err/n;

        vector<cv::Point2f> qp_proj;
        cv::projectPoints(cv::Mat(Q[i]), proj_rvecs[i], proj_tvecs[i], Kp, kp, qp_proj);
        err = 0;
        for(int j=0; j<qc_proj.size(); j++){
            cv::Point2f d = qp[i][j] - qp_proj[j];
            err += cv::sqrt(d.x*d.x + d.y*d.y);
        }
        proj_error_per_view[i] = (float)err/n;

        std::cout << "Seq error " << i+1 << " cam:" << cam_error_per_view[i] << " proj:" << proj_error_per_view[i] << std::endl;
    }

    return calData;
//                CalibrationData nanData;
//                return nanData;
}
Esempio n. 9
0
//投影された三角形abcにラスタライズ、クリッピングでシェーディングを行う関数
//引数a, b, cは投影平面上の3点
//eg)
//double a = {1.0, 2.0};
//nは法線ベクトル
//Aは投影前の3点からなる三角形平面上の任意の点の座標.
//(3点A、B、Cのうちいずれでも良いがmain関数内のAを使うものとする.)
void shading(double *a, double *b, double *c, double *n, double *A){
    //3点が1直線上に並んでいるときはシェーディングができない
    if(lineOrNot(a, b, c) == 1){
        //塗りつぶす点が無いので何もしない. 
    }
    else{
        //y座標の値が真ん中点をp、その他の点をq、rとする
        //y座標の大きさはr <= p <= qの順
        double p[2], q[2], r[2];
        if(b[1] <= a[1] && a[1] <= c[1]){
            memcpy(p, a, sizeof(double) * 2);
            memcpy(q, c, sizeof(double) * 2);
            memcpy(r, b, sizeof(double) * 2);
        }
        else{
            if(c[1] <= a[1] && a[1] <= b[1]){
                memcpy(p, a, sizeof(double) * 2);
                memcpy(q, b, sizeof(double) * 2);
                memcpy(r, c, sizeof(double) * 2);
            }
            else{
                if(a[1] <= b[1] && b[1] <= c[1]){
                    memcpy(p, b, sizeof(double) * 2);
                    memcpy(q, c, sizeof(double) * 2);
                    memcpy(r, a, sizeof(double) * 2);
                }
                else{
                    if(c[1] <= b[1] && b[1] <= a[1]){
                        memcpy(p, b, sizeof(double) * 2);
                        memcpy(q, a, sizeof(double) * 2);
                        memcpy(r, c, sizeof(double) * 2);
                    }
                    else{
                        if(b[1] <= c[1] && c[1] <= a[1]){
                            memcpy(p, c, sizeof(double) * 2);
                            memcpy(q, a, sizeof(double) * 2);
                            memcpy(r, b, sizeof(double) * 2);
                        }
                        else{
                            if(a[1] <= c[1] && c[1] <= b[1]){
                                memcpy(p, c, sizeof(double) * 2);
                                memcpy(q, b, sizeof(double) * 2);
                                memcpy(r, a, sizeof(double) * 2);
                            }
                            else{
                                printf("エラーat2055\n");
                                printf("\na[1]=%f\tb[1]=%f\tc[1]=%f\n", a[1], b[1], c[1]);
                                perror(NULL);
                            }
                        }
                    }
                }
            }
        }
        //分割可能な三角形かを判定
        if(p[1] == r[1] || p[1] == q[1]){
            //分割できない

            //長さが1の光源方向ベクトルを作成する
            //光源方向ベクトルの長さ
            double length_l =
                sqrt(pow(light_dir[0], 2.0) +
                     pow(light_dir[1], 2.0) +
                     pow(light_dir[2], 2.0));
            
            double light_dir_vec[3];
            light_dir_vec[0] = light_dir[0] / length_l;
            light_dir_vec[1] = light_dir[1] / length_l;
            light_dir_vec[2] = light_dir[2] / length_l;
                            
            //2パターンの三角形を特定
            if(p[1] == r[1]){
                //x座標が p <= r となるように調整
                if(r[0] <  p[0]){
                    double temp[2];
                    memcpy(temp, r, sizeof(double) * 2);
                    memcpy(r, p, sizeof(double) * 2);
                    memcpy(p, temp, sizeof(double) * 2);
                }
                
                //debug
                if(r[0] == p[0]){
                  perror("エラーat958");
                }
                
                //シェーディング処理
                //三角形pqrをシェーディング
                //y座標はp <= r
                //debug
                if(r[1] < p[1]){
                    perror("エラーat1855");
                }

                /* 点(j, i)のシェーディング============================================= */
                int i;
                i = ceil(p[1]);
                for(i;
                    p[1] <= i && i <= q[1];
                    i++){

                    //撮像平面からはみ出ていないかのチェック
                    if(0 <= i
                       &&
                       i <= (HEIGHT - 1)){
                           double x1 = func1(p, q, i);
                           double x2 = func1(r, q, i);
                           int j;
                           j = ceil(x1);
                           
                           for(j;
                               x1 <= j && j <= x2 && 0 <= j && j <= (WIDTH - 1);
                               j++){


                               /* 鏡面反射を計算 */
                               
                               //描画する点の投影前の空間内の座標.
                               double p_or[3];
 
                               p_or[0] =
                                   (j-(WIDTH/2))
                                   *
                                   ((n[0]*A[0]) + (n[1]*A[1]) + (n[2]*A[2]))
                                   /
                                   ((n[0]*(j-(WIDTH/2))) + (n[1]*(i-(HEIGHT/2))) + n[2]*FOCUS);
                               
                               p_or[1] =
                                   (i-(HEIGHT/2))
                                   *
                                   ((n[0]*A[0]) + (n[1]*A[1]) + (n[2]*A[2]))
                                   /
                                   ((n[0]*(j-(WIDTH/2))) + (n[1]*(i-(HEIGHT/2))) + n[2]*FOCUS);
                               
                              p_or[2] =
                                   FOCUS
                                   *
                                   ((n[0]*A[0]) + (n[1]*A[1]) + (n[2]*A[2]))
                                   /
                                   ((n[0]*(j-(WIDTH/2))) + (n[1]*(i-(HEIGHT/2))) + n[2]*FOCUS);

                              /* eは描画中の点pから視点位置へ向かうベクトルを計算 */
                              //視点方向は原点に固定
                              double e[3];
                              e[0] = -1 * p_or[0];
                              e[1] = -1 * p_or[1];
                              e[2] = -1 * p_or[2];
                              double length_e =
                                  sqrt(pow(e[0], 2.0) +
                                       pow(e[1], 2.0) +
                                       pow(e[2], 2.0));
                              e[0] = (e[0] / length_e);
                              e[1] = (e[1] / length_e);
                              e[2] = (e[2] / length_e);
                              
                              /* iは光源から描画中の点pへの入射光ベクトルを計算 */ 
                              //平行光源のため光源方向は
                              //const double light_dir[3] = {-1.0, -1.0, 2.0};
                              //を用いる
                              double i_vec[3];
                              i_vec[0] = light_dir[0];
                              i_vec[1] = light_dir[1];
                              i_vec[2] = light_dir[2];
                              double length_i =
                                  sqrt(pow(i_vec[0], 2.0) +
                                       pow(i_vec[1], 2.0) +
                                       pow(i_vec[2], 2.0));
                              i_vec[0] = (i_vec[0] / length_i);
                              i_vec[1] = (i_vec[1] / length_i);
                              i_vec[2] = (i_vec[2] / length_i);
                              
                              /* sベクトルを計算 */
                              double s[3];
                              s[0] = e[0] - i_vec[0];
                              s[1] = e[1] - i_vec[1];
                              s[2] = e[2] - i_vec[2];
                              double s_length =
                                  sqrt(pow(s[0], 2.0) +
                                       pow(s[1], 2.0) +
                                       pow(s[2], 2.0));
                              s[0] = (s[0] / s_length);
                              s[1] = (s[1] / s_length);
                              s[2] = (s[2] / s_length);
                              
                              //内積sn
                              double sn =
                                  ((s[0] * n[0]) + (s[1] * n[1]) + (s[2] * n[2]));
                              
                              if(sn <= 0){sn = 0;}
                              
                              /* 法線ベクトルnと光源方向ベクトルの内積 */
                              double ip =
                                  (n[0] * i_vec[0]) +
                                  (n[1] * i_vec[1]) +
                                  (n[2] * i_vec[2]);
                              
                              if(0 <= ip){ip = 0;} 
                                                 
                              //zがzバッファの該当する値より大きければ描画を行わない(何もしない)
                              if(z_buf[i][j] < p_or[2]){}
                              
                              else{
                                  image[i][j][0] =
                                      (-1 * ip * diffuse_color[0] * light_rgb[0] * MAX)
                                      + (pow(sn, shininess) * specular_color[0] * light_rgb[0] * MAX)
                                      ;
                                  
                                  image[i][j][1] =
                                      (-1 * ip * diffuse_color[1] * light_rgb[1] * MAX)
                                      + (pow(sn, shininess) * specular_color[1] * light_rgb[1] * MAX)
                                      ;
                                  
                                  image[i][j][2] =
                                      (-1 * ip * diffuse_color[2] * light_rgb[2] * MAX)
                                      + (pow(sn, shininess) * specular_color[2] * light_rgb[2] * MAX)
                                      ;
                                  
                                  //zバッファの更新
                                  z_buf[i][j] = p_or[2];
                              }
                           }
                           /* 点(j, i)のシェーディングここまで============================================= */
                    }
                    //はみ出ている場合は描画しない
                    else{}
                }
                
            }
            
            if(p[1] == q[1]){
                //x座標が p < q となるように調整
                if(q[0] <  p[0]){
                    double temp[2];
                    memcpy(temp, q, sizeof(double) * 2);
                    memcpy(q, p, sizeof(double) * 2);
                    memcpy(p, temp, sizeof(double) * 2);
                }
         
                //debug
                if(q[0] == p[0]){
                    perror("エラーat1011");
                }
                
                //シェーディング処理
                //三角形pqrをシェーディング
                //y座標はp <= q    
                //debug
                if(q[1] < p[1]){
                    perror("エラーat1856");
                }
                
                int i;
                i = ceil(r[1]);

                for(i;
                    r[1] <= i && i <= p[1];
                    i++){

                    //撮像部分からはみ出ていないかのチェック
                    if( 0 <= i &&
                        i <= (HEIGHT - 1)){
                        double x1 = func1(p, r, i);
                        double x2 = func1(q, r, i);
                        
                        int j;
                        j = ceil(x1);
                        
                        for(j;
                            x1 <= j && j <= x2 && 0 <= j && j <= (WIDTH - 1);
                            j++){

                            /* 鏡面反射を適用 */
                            //描画する点の投影前の空間内の座標.
                            double p_or[3];
                            
                            p_or[0] =
                                (j-(WIDTH/2))
                                *
                                ((n[0]*A[0]) + (n[1]*A[1]) + (n[2]*A[2]))
                                /
                                ((n[0]*(j-(WIDTH/2))) + (n[1]*(i-(HEIGHT/2))) + n[2]*FOCUS);
                            
                            p_or[1] =
                                (i-(MAX/2))
                                *
                                ((n[0]*A[0]) + (n[1]*A[1]) + (n[2]*A[2]))
                                /
                                ((n[0]*(j-(WIDTH/2))) + (n[1]*(i-(HEIGHT/2))) + n[2]*FOCUS);
                            
                            p_or[2] =
                                FOCUS
                                *
                                ((n[0]*A[0]) + (n[1]*A[1]) + (n[2]*A[2]))
                                /
                                ((n[0]*(j-(WIDTH/2))) + (n[1]*(i-(HEIGHT/2))) + n[2]*FOCUS);
                            
                            /* 描画中の点pから視点位置へ向かう単位方向ベクトルe計算 */
                            //視点方向は原点に固定
                            double e[3];
                            e[0] = -1 * p_or[0];
                            e[1] = -1 * p_or[1];
                            e[2] = -1 * p_or[2];
                            double length_e =
                                sqrt(pow(e[0], 2.0) +
                                     pow(e[1], 2.0) +
                                     pow(e[2], 2.0));
                            e[0] = (e[0] / length_e);
                            e[1] = (e[1] / length_e);
                            e[2] = (e[2] / length_e);
                            
                            /* 光源から描画中の点pへの入射光ベクトルiを計算 */
                            //平行光源のため光源方向は
                            //const double light_dir[3] = {-1.0, -1.0, 2.0};
                            //を用いる
                            double i_vec[3];
                            i_vec[0] = light_dir[0];
                            i_vec[1] = light_dir[1];
                            i_vec[2] = light_dir[2];
                            double length_i =
                                sqrt(pow(i_vec[0], 2.0) +
                                     pow(i_vec[1], 2.0) +
                                     pow(i_vec[2], 2.0));
                            i_vec[0] = (i_vec[0] / length_i);
                            i_vec[1] = (i_vec[1] / length_i);
                            i_vec[2] = (i_vec[2] / length_i);
                            
                            /* sベクトルを計算 */
                            double s[3];
                            s[0] = e[0] - i_vec[0];
                            s[1] = e[1] - i_vec[1];
                            s[2] = e[2] - i_vec[2];
                            double s_length =
                                sqrt(pow(s[0], 2.0) + pow(s[1], 2.0) + pow(s[2], 2.0));
                            s[0] = (s[0] / s_length);
                            s[1] = (s[1] / s_length);
                            s[2] = (s[2] / s_length);
                            
                            //内積sn
                            double sn = ((s[0] * n[0]) +
                                         (s[1] * n[1]) +
                                         (s[2] * n[2]));
                            if(sn <= 0){sn = 0;}

                            //拡散反射
                            /* 法線ベクトルnと光源方向ベクトルの内積を計算 */
                            double ip =
                                (n[0] * i_vec[0]) +
                                (n[1] * i_vec[1]) +
                                (n[2] * i_vec[2]);
                            
                            if(0 <= ip){ip = 0;}
                            
                           
                            //zがzバッファの該当する値より大きければ描画を行わない(何もしない)
                            if(z_buf[i][j] < p_or[2]){}
                        
                            else{
                            
                                image[i][j][0] =
                                    (-1 * ip * diffuse_color[0] * light_rgb[0] * MAX)
                                    + (pow(sn, shininess) * specular_color[0] * light_rgb[0] * MAX)
                                    ;
                                
                                image[i][j][1] =
                                    (-1 * ip * diffuse_color[1] * light_rgb[1] * MAX)
                                    + (pow(sn, shininess) * specular_color[1] * light_rgb[1] * MAX)
                                    ;
                                
                                image[i][j][2] =
                                    (-1 * ip * diffuse_color[2] * light_rgb[2] * MAX)
                                    + (pow(sn, shininess) * specular_color[2] * light_rgb[2] * MAX)
                                    ;

                                z_buf[i][j] = p_or[2];
                            }
                        }
                    }
                    //撮像平面からはみ出る部分は描画しない
                    else{}      
                }
            }
            
        }
        //分割できる
        //分割してそれぞれ再帰的に処理
        //分割後の三角形はpp2qとpp2r
        else{
            double p2[2];
            p2[0] = func1(q, r, p[1]);
            p2[1] = p[1];
            //p2のほうがpのx座標より大きくなるようにする
            if(p2[0] < p[0]){
                double temp[2];
                memcpy(temp, p2, sizeof(double) * 2);
                memcpy(p2, p, sizeof(double) * 2);
                memcpy(p, temp, sizeof(double) * 2);
            }
            //分割しても同一平面上なので法線ベクトルと
            //平面上の任意の点は同じものを使える.
            shading(p, p2, q, n, A);
            shading(p, p2, r, n, A);
        }
    }
}
Esempio n. 10
0
int main (int argc, char *argv[]){
    /* VRML読み込み========================================================= */
    int i;
    FILE *fp;
    Polygon poly;
    Surface surface;

    fp = fopen(argv[1], "r");
    read_one_obj(fp, &poly, &surface);

    fprintf(stderr,"%d vertice are found.\n",poly.vtx_num);
    fprintf(stderr,"%d triangles are found.\n",poly.idx_num);

    //i th vertex
    for ( i = 0 ; i < poly.vtx_num ; i++ ) {
        fprintf(stdout,"%f %f %f # %d th vertex\n",
                poly.vtx[i*3+0], poly.vtx[i*3+1], poly.vtx[i*3+2],
                i);
    }

    //i th triangle
    for ( i = 0 ; i < poly.idx_num ; i++ ) {
        fprintf(stdout,"%d %d %d # %d th triangle\n",
                poly.idx[i*3+0], poly.idx[i*3+1], poly.idx[i*3+2],
                i);
    }

    /* material info */
    fprintf(stderr, "diffuseColor %f %f %f\n", surface.diff[0], surface.diff[1], surface.diff[2]);
    fprintf(stderr, "specularColor %f %f %f\n", surface.spec[0], surface.spec[1], surface.spec[2]);
    fprintf(stderr, "ambientIntensity %f\n", surface.ambi);
    fprintf(stderr, "shininess %f\n", surface.shine);
    /* VRML読み込みここまで========================================================= */

    FILE *fp_ppm;
    char *fname = argv[2];
    fp_ppm = fopen(argv[2], "w");
    
    //ファイルが開けなかったとき
    if( fp_ppm == NULL ){
        printf("%sファイルが開けません.\n", fname);
        return -1;
    }
    
    //ファイルが開けたとき
    else{
        //描画領域を初期化
        for(int i = 0; i < 256; i++){
            for(int j = 0; j < 256; j++){
                image[i][j][0] = 0.0 * MAX;
                image[i][j][1] = 0.0 * MAX;
                image[i][j][2] = 0.0 * MAX;
            }
        }

         //zバッファを初期化
        for(int i = 0; i < 256; i++){
            for(int j = 0; j < 256; j++){
                z_buf[i][j] = DBL_MAX;
            }
        }

        //diffuse_colorの格納 
        diffuse_color[0] = surface.diff[0];
        diffuse_color[1] = surface.diff[1];
        diffuse_color[2] = surface.diff[2];

        //shininessの格納
        //!!!!!!!!!!!!!注意!!!!!!!!!!!!!!!!
        //(実験ページの追加情報を参照)
        //各ファイルのshininessの値は
        //av4 0.5
        //av5 0.5
        //iiyama1997 1.0
        //aa053 1.0
        //av007 0.34       
        shininess = surface.shine * 128;

        //speculorColorの格納
        specular_color[0] = surface.spec[0];
        specular_color[1] = surface.spec[1];
        specular_color[2] = surface.spec[2];

        //投影された後の2次元平面上の各点の座標を格納する領域
        double projected_ver_buf[3][2];

        //シェーディング
        //三角形ごとのループ
        for(int i = 0; i < poly.idx_num; i++){
            //各点の透視投影処理
            for(int j = 0; j < 3; j++){ 
                double xp = poly.vtx[(poly.idx[i*3+j])*3 + 0];
                double yp = poly.vtx[(poly.idx[i*3+j])*3 + 1];
                double zp = poly.vtx[(poly.idx[i*3+j])*3 + 2];
                double zi = FOCUS;

                //debug 
                if(zp == 0){
                    printf("\n(%f\t%f\t%f) i=%d, j=%d\n", xp, yp, zp, i, j);
                    perror("\nエラー0934\n");
                    //break;
                }
                
                double xp2 = xp * (zi / zp);
                double yp2 = yp * (zi / zp);
                double zp2 = zi;
                
                //座標軸を平行移動
                projected_ver_buf[j][0] = (MAX / 2) + xp2;
                projected_ver_buf[j][1] = (MAX / 2) + yp2;
            }
            
            double a[2], b[2], c[2];
            a[0] = projected_ver_buf[0][0];
            a[1] = projected_ver_buf[0][1];
            b[0] = projected_ver_buf[1][0];
            b[1] = projected_ver_buf[1][1];
            c[0] = projected_ver_buf[2][0];
            c[1] = projected_ver_buf[2][1];

            double A[3], B[3], C[3];
            A[0] = poly.vtx[(poly.idx[i*3+0])*3 + 0];
            A[1] = poly.vtx[(poly.idx[i*3+0])*3 + 1];
            A[2] = poly.vtx[(poly.idx[i*3+0])*3 + 2];
            
            B[0] = poly.vtx[(poly.idx[i*3+1])*3 + 0];
            B[1] = poly.vtx[(poly.idx[i*3+1])*3 + 1];
            B[2] = poly.vtx[(poly.idx[i*3+1])*3 + 2];
            
            C[0] = poly.vtx[(poly.idx[i*3+2])*3 + 0];
            C[1] = poly.vtx[(poly.idx[i*3+2])*3 + 1];
            C[2] = poly.vtx[(poly.idx[i*3+2])*3 + 2];

            //ベクトルAB, ACから外積を計算して
            //法線ベクトルnを求める
            double AB[3], AC[3], n[3];
            AB[0] = B[0] - A[0];
            AB[1] = B[1] - A[1];
            AB[2] = B[2] - A[2];
            
            AC[0] = C[0] - A[0];
            AC[1] = C[1] - A[1];
            AC[2] = C[2] - A[2];

            n[0] = (AB[1] * AC[2]) - (AB[2] * AC[1]);
            n[1] = (AB[2] * AC[0]) - (AB[0] * AC[2]);
            n[2] = (AB[0] * AC[1]) - (AB[1] * AC[0]);

            //長さを1に調整
            double length_n =
                sqrt(pow(n[0], 2.0) +
                     pow(n[1], 2.0) +
                     pow(n[2], 2.0));
        
            n[0] = n[0] / length_n;
            n[1] = n[1] / length_n;
            n[2] = n[2] / length_n;

            //平面iの投影先の三角形をシェーディング
            shading(a, b, c, n, A);
        }
  
        //ヘッダー出力
        fputs(MAGICNUM, fp_ppm);
        fputs("\n", fp_ppm);
        fputs(WIDTH_STRING, fp_ppm);
        fputs(" ", fp_ppm);
        fputs(HEIGHT_STRING, fp_ppm);
        fputs("\n", fp_ppm);
        fputs(MAX_STRING, fp_ppm);
        fputs("\n" ,fp_ppm);

        //imageの出力
        for(int i = 0; i < 256; i++){
            for(int j = 0; j < 256; j++){
                char r[256];
                char g[256];
                char b[256];
                char str[1024];
                
                sprintf(r, "%d", (int)round(image[i][j][0]));
                sprintf(g, "%d", (int)round(image[i][j][1]));
                sprintf(b, "%d", (int)round(image[i][j][2]));
                sprintf(str, "%s\t%s\t%s\n", r, g, b);
                fputs(str, fp_ppm); 
            }
        }
    }
    fclose(fp_ppm);
    fclose(fp);
    
    printf("\nppmファイル %s に画像を出力しました.\n", fname );
    return 1;
}
Esempio n. 11
0
int main(int argc, char** args)
{
	GLFWwindow* window = setup();

	//------------------------------------------
	//-------- View-Projection settings --------
	//------------------------------------------
	glm::vec3 cameraPos = glm::vec3(5.0f, 1.0f, 0.0f);

	glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.01f, 20.0f);
	glm::mat4 View = glm::lookAt(cameraPos, //Position 
								glm::vec3(0.0f, 0.0f, 0.0f), 	//Look direction
								glm::vec3(0.0f, 1.0f, 0.0f) );	//Up

	//Pre-multiply projection and view
	glm::mat4 vpMatrix = Projection * View;

	//---------------------------
	//-------- Lighting ---------
	//---------------------------
	PointLight p[2];
	p[0].pos = glm::vec3(0.0f, 0.0f, +3.0f);
	p[0].intensity = 2.0f;
	p[0].falloff = 1.0f;

	p[1].pos = glm::vec3(0.0f, 0.0f, -3.0f);
	p[1].intensity = 2.0f;
	p[1].falloff = 1.0f;

	glm::vec3 p0 = glm::vec3(0.0f, 0.0f, +3.0f);
	glm::vec3 p1 = glm::vec3(0.0f, +4.0f, 0.0f);

	float angle = 0.0f;

	//----------------------------------
	//-------- Geometry setting --------
	//----------------------------------
	if(argc != 3)
	{
		std::cout<<"Wrong input! Usage: "<<std::endl<<std::endl;
		std::cout<<"	./render path/to/file.obj gouraud|flat"<<std::endl<<std::endl;
		return 0;
	}

	std::string filepath(args[1]);
	std::string shading(args[2]);

	Object obj;
	obj.load(filepath, std::string("./shaders/") + shading);
	obj.setViewProjection(&vpMatrix);

	do
	{
		//Clear screen -> this function also clears stencil and depth buffer
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

		//Rotate lights
		glm::mat4 rot1 = glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 1.0f, 0.0f));
		glm::mat4 rot2 = glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 0.0f, 1.0f));
		p[0].pos = glm::vec3( rot1 * glm::vec4(p0, 1.0f) );
		p[1].pos = glm::vec3( rot2 * glm::vec4(p1, 1.0f) );
		angle += 0.05f; if(angle >= 6.28) angle = 0.0f;

		obj.draw(cameraPos, p, 2);

		//Swap buffer and query events
		glfwSwapBuffers(window);
		glfwPollEvents();

	} while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && 
			!glfwWindowShouldClose(window));

	//Drop GLFW device
	glfwTerminate();

	return 0;
}
Esempio n. 12
0
void CMapDEM::draw()
{

    IMap::overlay_e overlay = status->getOverlayType();

    if(CMapDEMSlopeSetup::self() && (overlay != old_overlay))
    {
        if(overlay == IMap::eSlope)
        {
            CMapDEMSlopeSetup::self()->registerDEMMap(this);
        }
        else
        {
            CMapDEMSlopeSetup::self()->registerDEMMap(0);
        }
    }

    if(overlay == IMap::eNone)
    {
        old_overlay = overlay;
        pixBuffer.fill(Qt::transparent);
        return;
    }

    // check if old area matches new request
    // kind of a different way to calculate the needRedraw flag

    projXY p1, p2;
    float my_xscale, my_yscale;

    getArea_n_Scaling_fromBase(p1, p2, my_xscale, my_yscale);

    if(    overlay == old_overlay
        && p1.u == old_p1.u && p1.v == old_p1.v
        && p2.u == old_p2.u && p2.v == old_p2.v
        && my_xscale == old_my_xscale && my_yscale == old_my_yscale
        )
    {
        if(!needsRedraw)
        {
            return;
        }
    }

    old_p1          = p1;
    old_p2          = p2;
    old_my_xscale   = my_xscale;
    old_my_yscale   = my_yscale;
    old_overlay     = overlay;

    pixBuffer.fill(Qt::transparent);

    if(pjsrc == 0) return;

    /*
        Calculate area of DEM data to be read.
    */

    projXY _p1 = p1;
    projXY _p2 = p2;

    // 1. convert top left and bottom right point into the projection system used by the DEM data
    pj_transform(pjtar, pjsrc, 1, 0, &_p1.u, &_p1.v, 0);
    pj_transform(pjtar, pjsrc, 1, 0, &_p2.u, &_p2.v, 0);

    // determine intersection rect
    projXY r1 = { qMax(_p1.u, xref1), qMin(_p1.v, yref1) };
    projXY r2 = { qMin(_p2.u, xref2), qMax(_p2.v, yref2) };

    if (r1.u > _p2.u || r1.v < _p2.v || r2.u < _p1.u || r2.v > _p1.v)
    {
        // no interscetion
        return;
    }

    // 2. get floating point offset of topleft corner
    double xoff1_f = (r1.u - xref1) / xscale;
    double yoff1_f = (r1.v - yref1) / yscale;

    // 3. truncate floating point offset into integer offset
    int xoff1 = xoff1_f;
    int yoff1 = yoff1_f;

    // 4. get floating point offset of bottom right corner
    double xoff2_f = (r2.u - xref1) / xscale;
    double yoff2_f = (r2.v - yref1) / yscale;

    // 5. qRound up (!) floating point offset into integer offset
    int xoff2 = ceil(xoff2_f);
    int yoff2 = ceil(yoff2_f);

    /*
        The defined area into DEM data (xoff1,yoff1,xoff2,yoff2) covers a larger or equal
        area in world coordinates [m] than the current viewport.

        Next the width and height of the area in the DEM data and the corresponding sceen
        size is calculated.
    */

    /*
        Calculate the width and the height of the area. Extend width until it's a multiple of 4.
        This will be of advantage as QImage will process 32bit aligned bitmaps much faster.
    */
    unsigned int w1 = (xoff2 - xoff1 + 3) & ~0x03;
    unsigned int h1 = (yoff2 - yoff1);

    // bail out if this is getting too big
    if(w1 > 10000 || h1 > 10000) return;

    // now calculate the actual width and height of the viewport
    unsigned int w2 = w1 * xscale / my_xscale;
    unsigned int h2 = h1 * yscale / my_yscale;

    // as the first point off the DEM data will not match exactly the given top left corner
    // the bitmap has to be drawn with an offset.
    int pxx = ((xoff1_f - xoff1) * xscale - (r1.u - _p1.u)) / my_xscale;
    int pxy = ((yoff1_f - yoff1) * yscale - (r1.v - _p1.v)) / my_yscale;

    // read 16bit elevation data from GeoTiff
    QVector<qint16> data(w1*h1);

    GDALRasterBand * pBand;
    pBand = dataset->GetRasterBand(1);
    CPLErr err = pBand->RasterIO(GF_Read, xoff1, yoff1, qMin(w1, xsize_px - xoff1), qMin(h1, ysize_px - yoff1), data.data(), w1, h1, GDT_Int16, 0, 0);
    if(err == CE_Failure)
    {
        return;
    }

    QImage img(w1,h1,QImage::Format_Indexed8);

    if(overlay == IMap::eShading)
    {
        shading(img,data.data(), my_xscale, my_yscale);
    }
    else if(overlay == IMap::eContour)
    {
        contour(img,data.data(), my_xscale, my_yscale);
    }
    else if(overlay == IMap::eSlope)
    {
        slope(img,data.data(), xoff1, yoff1);
    }
    else
    {
        qWarning() << "Unknown shading type";
        return;
    }

    // Finally scale the image to viewport size. QT will do the smoothing
    //img = img.scaled(w2,h2, Qt::IgnoreAspectRatio,Qt::SmoothTransformation);

    QPainter p(&pixBuffer);
    p.drawImage(-pxx, -pxy, img.scaled(w2,h2, Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
}
Esempio n. 13
0
void drawPlant()
{
    int i;
    glEnable(GL_LIGHTING);
    shading(4);
    glPushMatrix();
    glTranslatef(0.0, -5.0 + plantHeight / 2, 0.0);
    glScalef(0.85, 0.85, 0.85);
    glRotatef(2 * wind, 0.0, 0.0, -1.0);
    glTranslatef(0.0, -plantHeight / 2., 0.0);
    glRotatef(falltheta - 1.0, 0.0, 0.0, -1.0);
    glPushMatrix();
    glRotatef(90, -1, 0, 0);
    
    gluCylinder(gluNewQuadric(), plantWidth, plantWidth, plantHeight, 10, 10);
    
    if (grow>1){
        shading(3);
        glPushMatrix();
        glRotatef(90, -1, 0, 0);
        glRotatef(100.0, 0.0, 1.0, 0.0);
        glTranslatef(plantWidth, -plantHeight / 2.5, 0.0);
        glRotatef(10 * sin(2 * PI*(randrotation[GRASSAREA - 6] % 100 + 1) / 100 + thetawind*PI / 180.0)*wind, 0.0, 0.0, 1.0);
        glRotatef(90, 1, 0, 0);
        gluDisk(gluNewQuadric(), 0.0, diskR, 10, 10);
        glPopMatrix();
        
        glPushMatrix();
        glRotatef(90, -1, 0, 0);
        glRotatef(-45.0, 0.0, 1.0, 0.0);
        glTranslatef(plantWidth, -plantHeight / 2., 0.0);
        glRotatef(10 * sin(2 * PI*(randrotation[GRASSAREA - 7] % 100 + 1) / 100 + thetawind*PI / 180.0)*wind, 0.0, 0.0, 1.0);
        glRotatef(90, 1, 0, 0);
        gluDisk(gluNewQuadric(), 0.0, diskR, 10, 10);
        glPopMatrix();
        
        glPushMatrix();
        glRotatef(90, -1, 0, 0);
        glRotatef(170.0, 0.0, 1.0, 0.0);
        glTranslatef(plantWidth, -plantHeight / 5., 0.0);
        glRotatef(10 * sin(2 * PI*(randrotation[GRASSAREA - 8] % 100 + 1) / 100 + thetawind*PI / 180.0)*wind, 0.0, 0.0, 1.0);
        glRotatef(90, 1, 0, 0);
        gluDisk(gluNewQuadric(), 0.0, diskR, 10, 10);
        glPopMatrix();
    }
    
    glPopMatrix();
    
    glTranslatef(0.0, plantHeight - 0.2, 0.0);
    
    if (falltheta <= 70)
        glTranslatef(0.3*wind, 0.0, 0.0);
    else
        glTranslatef(-0.1*pow(2.71, -t4 / 10)*sin(t4*PI / 4), 0.0, 0.0);
    
    if (grow>2) {
        for (i = 0; i<5; i++){
            glPushMatrix();
            glRotatef((float)i*360. / 5., 0.0, 1.0, 0.0);
            if (falltheta <= 70)
                glTranslatef(0.0, 0.05*sin(2 * PI*(randrotation[GRASSAREA - i] % 100 + 1) / 100 + thetawind*PI / 180.0)*wind, 0.0);
            glTranslatef(growleaves*0.1 + plantWidth, 0.2*movey[i], 0.0);
            glScalef(1. + .5*scalex[i], 0.9, 1. + .2*scalez[i]);
            glutSolidSphere(leafR, 10, 10);
            glPopMatrix();
        }
    }
    
    glPopMatrix();
    glDisable(GL_LIGHTING);
}
Esempio n. 14
0
RTColor RTRayTracer::traceRay(RTRay &ray, int depth, RTLight light)
{

    RTColor color(135,206,250);

    if(depth>scene.getMaxDepth()) {

        RTColor zero(0,0,0);
        return zero; //BLACK

    }


    std::vector<RTObject*> objects = this->scene.getPrimitives();

    RTObject *closestObject=NULL;
    RTVector hitPoint,closestPoint;
    double t,nearest=INF;

    //percorre objetos da cena
    for(unsigned int io=0; io<objects.size(); io++) {
        //testa a inte  rseção
        if(!objects[io]->intersect(ray,t))
            continue;
        else { //hit
            hitPoint = ray.getPos()+(ray.getDir()*t);
            t= hitPoint.getNorma();
            if(t<nearest) {
                nearest = t;
                closestObject=objects[io];
                closestPoint=hitPoint;
            }
        }
    }

    if(nearest==INF) { //nao intersecionou
        return color;
    }

    RTColor reflectColor,refracColor,objColor;
    int surfaceType=closestObject->getBrdf()->getSurfaceType();

    double fogFactor=0;

    //verifica se existe fog na cena
    if(scene.getHasFog()) { //calcula o fator fog
        fogFactor=(scene.getFog().getZ_end()-closestPoint.getZ())/(scene.getFog().getZ_end()-scene.getFog().getZ_start());
        fogFactor=(fogFactor>1.0)?1.0:((fogFactor<0)?0:fogFactor); //clamp
        //fogFactor=pow(M_E,-scene.getFog().getDensity()*closestPoint.getZ());
    }

    objColor= shading(closestObject, closestPoint, light);

    double reflectivePercentage = closestObject->getBrdf()->getKr();
    double refractivePercentage = 0;
    bool isInside=false;
    double refraIndex=closestObject->getBrdf()->getRefracIndex();

    if(surfaceType==REFLECTIVE||surfaceType==REFRACTIVE) {



        RTVector eyedir = -((ray.getPos()*1)-closestPoint);  //d
        eyedir.normalize();
        RTVector normal = closestObject->normalOfHitPoint(closestPoint);//N


        if(surfaceType==REFRACTIVE) { //aplica fresnel


            if(closestObject->getObjTag()==SPHERE) { //verifica se o raio de refração segue para dentro da esfera
                RTSphere *sp= dynamic_cast<RTSphere*>(closestObject);
                double centerDist =sqrt(pow(ray.getPos().getX() - sp->getCenter().getX(), 2)
                                        + pow(ray.getPos().getY() - sp->getCenter().getY(), 2)
                                        + pow(ray.getPos().getZ() - sp->getCenter().getZ(), 2));
                isInside=(centerDist<sp->getRadius());
            }


            reflectivePercentage=FresnelTerm(eyedir,normal,refraIndex,isInside); //R
            refractivePercentage=1-reflectivePercentage; //(1-R)
        }

        if(reflectivePercentage>0) { //calcula reflexão

            RTRay reflectionRay=genReflectionRay(eyedir,normal,closestPoint);
            reflectColor=(traceRay(reflectionRay,depth+1,light));
        }

        if(refractivePercentage>0) {

            double refraIndex=closestObject->getBrdf()->getRefracIndex();
            RTRay refracRay=genRefractRay(eyedir,normal,closestPoint,refraIndex,isInside);
            refracColor=(traceRay(refracRay,depth+1,light));
        }

    }


    if(surfaceType==REFRACTIVE&&!isInside) {

        color=reflectColor*reflectivePercentage+refracColor*(refractivePercentage);
    }
    else {
        int kloc=(surfaceType==REFRACTIVE)?0:1;
        color=reflectColor*reflectivePercentage+refracColor*refraIndex+objColor*kloc;
        color=color/(reflectivePercentage+refractivePercentage+kloc);

    }

    if(scene.getHasFog())
        color=(color*fogFactor)+(scene.getFog().getFogColor()*((1-fogFactor)));

    return color;

}