Source

dbsdev / sources / opengl2_samples / test7_simplerenderer / main.cpp

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <cmath>
using namespace std;

#include "glfw_utils.h"

#include "logger.h"

#include "GLCamera.h"
#include "GLTimer.h"
#include "GLTransform.h"
#include "GLTrackball.h"
#include "GLTrackballManipulator.h"

#include "vertex.h"

#include "mathutils.h"

#include "vboutils.h"

#include "GLShapes.h"
#include "GLShader.h"
#include "GLMaterial.h"
#include "GLMesh.h"
#include "GLMeshTools.h"

#include "GLRenderer.h"




int width = 1000;
int height = 500;    

GLCamera     camera;
GLTrackballManipulatorf trackball;

// timer
GLTimer timer;
GLTimer fpsTimer;
unsigned int frames = 0;

bool autorotate = true;

GLRenderer *renderer = 0;

// ////////// //
// scene data //
// ////////// //

std::vector<GLMesh*> meshes;



// ///////// //
// FUNCTIONS //
// ///////// //


void initScene( void )
{
    GLMesh *mesh = NULL;
    for (unsigned int i=0; i<meshes.size(); i++)
    {
		mesh = meshes[i];
        // init materials
        for (unsigned int i=0; i<mesh->submeshes.size(); i++)
        {
            initializeMaterial(mesh->submeshes[i].material);
        }
    }
}



void drawGraphics( void )
{ 
    if (autorotate)
    {
        // update camera position
        double currTime = timer.getElapsedTime();
        float posx = float(4.0*sin(currTime/3));
        float posz = float(4.0*cos(currTime/3));
        float posy = 2.0f+float(1.0*cos(currTime/2));

        camera.transform.setPosition(Vector3f(posx,posy,posz));
        camera.transform.lookAt(Vector3f(0.0,0.0,0.0),Vector3f(0.0,1.0,0.0),AXIS_ZNEG);
    }
    else // use trackball to manage camera
    {
        Matrix4f trackballTransf = trackball.getTransformation();
        camera.transform.setTransformationMatrix(trackballTransf);
        //camera.transform.translate(Vector3f(0.0f,0.0f,10.0f));
    }

    // add render data
    for (unsigned int i=0; i<meshes.size(); i++)
    {
        for (unsigned int j=0; j<meshes[i]->submeshes.size(); j++)
        {
            const GLSubMesh &sm = meshes[i]->submeshes[j];
            renderer->addRenderData( sm.material->shader->name,
                                     sm.material->name,
                                     sm.vertices,
                                     sm.indices );
        }
        
    }

    // render
    renderer->render(&camera);
}


// update camera position/orientation using the virtual trackball
void updateTrackball( void )
{
    // update trackball data using current context
    ContextData &ctx = glfw_getContextData();
    // normalize mouse pos
    float aspectRatio = ctx.width/ctx.height;
    float w = aspectRatio>1.0f ? (float)ctx.height : (float)ctx.width;
    float nx = 2.0f*((float)ctx.mouse_posx-ctx.width/2.0f)/w;
    float ny = 2.0f*((float)ctx.mouse_posy-ctx.height/2.0f)/w;

    if (ctx.mouse_button==MOUSE_BUTTON_LEFT && !ctx.dragging)
    {
        trackball.beginDrag(nx,ny);
    }
    if (ctx.dragging)
    {
        trackball.drag(nx,ny);
    }
    // logInfo("%4d %4d %4d %4d %4d %4d %c\n",  ctx.width,
    //                                          ctx.height,
    //                                          ctx.mouse_posx,
    //                                          ctx.mouse_posy,
    //                                          ctx.mouse_button,
    //                                          ctx.mouse_wheel,
    //                                          ctx.current_key);
}


int main( int argc, char *argv[] )
{
#ifdef __Debug__
int dbidx = 0;
std::cout << "enter a number:";
std::cin >> dbidx;
#endif //__Debug__

    // Initialize GLFW and Glee
    if( !glfw_Init(width,height) )
    {
        exit( EXIT_FAILURE );
    }

    // load mesh
    meshes.push_back(meshtools::createPrefabBox( Vector3f(1.0f,1.0f,1.0f), Vector4f(0.5f,0.5f,0.5f,1.0f) ) );
    // meshes.push_back(meshtools::createMeshFromFile( "transformer-bumblebee.3DS" ) );
    // meshes.push_back(meshtools::createMeshFromFile( "grayson.3DS" ) );

    // setup some materials
    GLShader *shader0 = materialsystem::getOrCreateShaderFromFiles("matte","simple_sh.vert", "simple_sh.frag");
    GLMaterial *mat0 = materialsystem::getOrCreateMaterial("matte","matte");

    GLShader *shader1 = materialsystem::getOrCreateShaderFromFiles("normal_tex","normal_sh_tex.vert", "normal_sh_tex.frag");
    GLMaterial *mat1 = materialsystem::getOrCreateMaterial("normal","normal_tex");
      mat1->textures[GLMaterial::evTextureDiffuse] = "Concrete.jpg";
      mat1->textures[GLMaterial::evTextureNormal] = "normal1.png";

    GLShader *shader2 = materialsystem::getOrCreateShaderFromFiles("simple_tex","simple_sh_tex.vert", "simple_sh_tex.frag");
    GLMaterial *mat2 = materialsystem::getOrCreateMaterial("diffuse","simple_tex");
      mat2->textures[GLMaterial::evTextureDiffuse] = "mucca_texture.png";

    GLMaterial* materials[3];
      materials[0] = mat0;
      materials[1] = mat1;
      materials[2] = mat2;
    // create an array of boxes
    float xw = 10.0f, xstep = 1.5f;
    float yw = 10.0f, ystep = 1.5f;
    float zw = 10.0f, zstep = 1.5f;
    srand(1234);
    for (float xpos = -xw; xpos<=10.0f; xpos+=xstep)
        for (float ypos = -yw; ypos<=10.0f; ypos+=ystep)
            for (float zpos = -zw; zpos<=10.0f; zpos+=zstep)
            {
                static int i=0;
                i++;
                GLMesh *m = meshtools::createPrefabBox( Vector3f(0.5f,0.5f,0.5f), materials[i%3] );
                  GLTransformf tr;
                  float randOffs = (rand()%100)/100.0;
                  float randRot = (rand()%1000)/1000.0;
                  tr.setPosition(Vector3f(xpos+randOffs,ypos+randOffs,zpos+randOffs));
                  tr.setRotationEuler(xpos/10+randRot,ypos/20+randRot,zpos/30+randRot);
                  applyTransform(m,tr);
                meshes.push_back(m);
            }

    // camera.setOrtho(-15.0f, 15.0f, -5.0f, 5.0f, -5.0f, 5.0f);
    camera.setPerspective(0.1f, 5000.0f, degToRad( 45.0f ));
    glfw_setCamera(&camera);
    // place camera
    camera.transform.setPosition(Vector3f(0.0f,0.0f,3.0f));
    camera.transform.lookAt(Vector3f(0.0,0.0,0.0),Vector3f(0.0,1.0,0.0),AXIS_ZNEG);

    renderer = new GLRenderer();

    // Set clear color to dark blue
    glClearColor(0.3f, 0.0f, 0.2f, 1.0f);
    glEnable(GL_DEPTH_TEST); 

    // init scene	
    initScene();

    //start timer
    timer.start();
    fpsTimer.start();
    // Main loop
	bool running = true;
    while( running ) 
    {
        frames++;
        // OpenGL rendering goes here...
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        
        // update camera with trackball
        updateTrackball();

        // draw graphics
        drawGraphics();

        // Swap front and back rendering buffers
        glfwSwapBuffers();
        // Check if ESC key was pressed or window was closed
        running = !glfwGetKey( GLFW_KEY_ESC ) && glfwGetWindowParam( GLFW_OPENED );

        // manage autorotate
        if (glfwGetKey('A')) {  autorotate = true;  }
        if (glfwGetKey('R')) {  autorotate = false;  trackball.setMode(GLTrackballManipulatorf::evRotate);  }
        if (glfwGetKey('T')) {  autorotate = false;  trackball.setMode(GLTrackballManipulatorf::evPan);  }
        if (glfwGetKey('Z')) {  autorotate = false;  trackball.setMode(GLTrackballManipulatorf::evZoom);  }

        // update fps
        if (frames%100==0)
        {
            logInfo("fps: %6.3f\n",100.0/fpsTimer.getElapsedTime());
            fpsTimer.start();
        }
    }
    
    // measure time and calc fps
    printf("elapsed time: %f - avg FPS: %f\n",timer.getElapsedTime(), (double)frames/timer.getElapsedTime());
    
    // Close window and terminate GLFW
    glfwTerminate();

    // Exit program
    exit( EXIT_SUCCESS );
}