⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 G3D游戏引擎的库
💻 CPP
字号:
/**
  @file shader/main.cpp

  Example of G3D shaders and GUIs.
  @author Morgan McGuire, morgan@cs.williams.edu
 */
#include <G3D/G3DAll.h>
#include <GLG3D/GLG3D.h>

class App : public GApp {
private:
    /** Lighting environment */
    LightingRef         lighting;
    SkyParameters       skyParameters;
    SkyRef              sky;

    /** For dragging the model */
    ThirdPersonManipulatorRef manipulator;
    IFSModelRef         model;

    /** Material properties and shader */
    ShaderRef           phongShader;
    float               reflect;
    float               shine;
    float               diffuse;
    float               specular;
    int                 diffuseColorIndex;
    int                 specularColorIndex;
    Array<GuiCaption>   colorList;

    void makeGui();
    void makeColorList(GFontRef iconFont);
    void configureShaderArgs(const LightingRef localLighting);

public:

    App(const GApp::Settings& settings = GApp::Settings());

    virtual void onInit();
    virtual void onGraphics(RenderDevice* rd, Array<PosedModelRef>& posed3D, Array<PosedModel2DRef>& posed2D);
};

App::App(const GApp::Settings& settings) : GApp(settings), reflect(0.1f), shine(20.0f), diffuse(0.6f), specular(0.5f) {}

void App::onInit() {
    window()->setCaption("G3D Shader Demo");

    // Called before the application loop beings.  Load data here
    // and not in the constructor so that common exceptions will be
    // automatically caught.
    sky = Sky::fromFile(dataDir + "sky/");

    skyParameters = SkyParameters(G3D::toSeconds(11, 00, 00, AM));
    lighting = Lighting::fromSky(sky, skyParameters, Color3::white());

    // This simple demo has no shadowing, so make all lights unshadowed
    lighting->lightArray.append(lighting->shadowedLightArray);
    lighting->shadowedLightArray.clear();
    setDesiredFrameRate(60);

#   ifdef G3D_WIN32
        if (! fileExists("phong.pix", false) && fileExists("G3D.sln", false)) {
            // Running in the solution directory
            chdir("../demos/shader/data-files");
        }
        toneMap->setEnabled(true);
#   else
        toneMap->setEnabled(false);
#   endif

    phongShader = Shader::fromFiles("phong.vrt", "phong.pix");
    model = IFSModel::fromFile(System::findDataFile("teapot.ifs"));

    makeColorList(GFont::fromFile(System::findDataFile("icon.fnt")));
    makeGui();

    // Color 1 is red
    diffuseColorIndex = 1;
    // Last color is white
    specularColorIndex = colorList.size() - 1;
    
    defaultCamera.setPosition(Vector3(1.0f, 1.0f, 2.5f));
    defaultCamera.lookAt(Vector3::zero());

    // Add axes for dragging and turning the model
    manipulator = ThirdPersonManipulator::create();
    addWidget(manipulator);

    // Turn off the default first-person camera controller and developer UI
    defaultController->setActive(false);
    developerWindow->setVisible(false);
}

void App::makeColorList(GFontRef iconFont) {
    // Characters in icon font that make a solid block of color
    const char* block = "gggggg";

    float size = 18;
    int N = 10;
    colorList.append(GuiCaption(block, iconFont, size, Color3::black(), Color4::clear()));
    for (int i = 0; i < N; ++i) {
        colorList.append(GuiCaption(block, iconFont, size, Color3::rainbowColorMap((float)i / N), Color4::clear()));
    }
    colorList.append(GuiCaption(block, iconFont, size, Color3::white(), Color4::clear()));
}

void App::makeGui() {
    GuiThemeRef skin = GuiTheme::fromFile(System::findDataFile("osx.skn"), debugFont);
    GuiWindow::Ref gui = GuiWindow::create("Material Parameters", skin);
    
    GuiPane* pane = gui->pane();
    pane->addDropDownList("Diffuse", &diffuseColorIndex, &colorList);
    pane->addSlider("Intensity", &diffuse, 0.0f, 1.0f);
    
    pane->addDropDownList("Specular", &specularColorIndex, &colorList);
    pane->addSlider("Intensity", &specular, 0.0f, 1.0f);
    
    pane->addSlider("Shininess", &shine, 1.0f, 100.0f);
    pane->addSlider("Reflectivity", &reflect, 0.0f, 1.0f);
    
    addWidget(gui);
}

void App::onGraphics(RenderDevice* rd, Array<PosedModelRef>& posed3D, Array<PosedModel2DRef>& posed2D) {
    toneMap->beginFrame(rd);

    LightingRef   localLighting = toneMap->prepareLighting(lighting);
    SkyParameters localSky      = toneMap->prepareSkyParameters(skyParameters);
    
    rd->setProjectionAndCameraMatrix(defaultCamera);

    rd->setColorClearValue(Color3(0.1f, 0.5f, 1.0f));
    rd->clear(false, true, true);
    sky->render(rd, localSky);

    //////////////////////////////////////////////////////////////////////
    // Shader example

    rd->pushState();
        // Pose our model based on the manipulator axes
        PosedModel::Ref posedModel = model->pose(manipulator->frame());
        
        // Enable the sahder
        configureShaderArgs(localLighting);
        rd->setShader(phongShader);

        // Send model geometry to the graphics card
        rd->setObjectToWorldMatrix(posedModel->coordinateFrame());
        posedModel->sendGeometry(rd);
    rd->popState();

    //////////////////////////////////////////////////////////////////////
    // Normal rendering loop boilerplate

    // Process the installed widgets.

    Array<PosedModel::Ref> opaque, transparent; 

    // Use fixed-function lighting for the 3D widgets for convenience.
    rd->pushState();
        rd->enableLighting();
        rd->setLight(0, localLighting->lightArray[0]);
        rd->setAmbientLightColor(localLighting->ambientAverage());

        // 3D
        if (posed3D.size() > 0) {
            Vector3 lookVector = renderDevice->getCameraToWorldMatrix().lookVector();
            PosedModel::sort(posed3D, lookVector, opaque, transparent);

            for (int i = 0; i < opaque.size(); ++i) {
                opaque[i]->render(renderDevice);
            }

            for (int i = 0; i < transparent.size(); ++i) {
                transparent[i]->render(renderDevice);
            }
        }
    rd->popState();

    // Don't apply the tone map to the 2D widgets
    toneMap->endFrame(rd);

    PosedModel2D::sortAndRender(rd, posed2D);

    sky->renderLensFlare(rd, localSky);
}

void App::configureShaderArgs(const LightingRef lighting) {
	const GLight& light = lighting->lightArray[0]; 

	phongShader->args.set("wsLight", light.position.xyz().direction());
	phongShader->args.set("lightColor", light.color);
	phongShader->args.set("wsEyePosition", defaultCamera.coordinateFrame().translation);
	phongShader->args.set("ambientLightColor", lighting->ambientAverage());

	Color3 color = colorList[diffuseColorIndex].color(Color3::white()).rgb();
	phongShader->args.set("diffuseColor", color);
	phongShader->args.set("diffuse", diffuse);

	color = colorList[specularColorIndex].color(Color3::white()).rgb();
	phongShader->args.set("specularColor", color);
	phongShader->args.set("specular", specular);
	phongShader->args.set("shine", shine);
	phongShader->args.set("reflect", reflect);

	phongShader->args.set("environmentMap", lighting->environmentMap);
	phongShader->args.set("environmentMapColor", lighting->environmentMapColor);
}

G3D_START_AT_MAIN();

int main(int argc, char** argv) {
    return App().run();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -