<commit_before>/*=====================================================================

QGroundControl Open Source Ground Control Station

(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

======================================================================*/

/**
 * @file
 *   @brief Implementation of audio output
 *
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
 *
 */

#include <QApplication>
#include <QSettings>
#include <QTemporaryFile>
#include "GAudioOutput.h"
#include "MG.h"

#include <QDebug>

#ifdef Q_OS_MAC
#include <ApplicationServices/ApplicationServices.h>
#endif

// Speech synthesis is only supported with MSVC compiler
#if _MSC_VER
// Documentation: http://msdn.microsoft.com/en-us/library/ee125082%28v=VS.85%29.aspx
#include <sapi.h>

//using System;
//using System.Speech.Synthesis;
#endif

#ifdef Q_OS_LINUX
extern "C" {
#include <flite/flite.h>
    cst_voice *register_cmu_us_kal(const char *voxdir);
};
#endif

#ifdef _MSC_VER
ISpVoice *GAudioOutput::pVoice = NULL;
#endif

/**
 * This class follows the singleton design pattern
 * @see http://en.wikipedia.org/wiki/Singleton_pattern
 * A call to this function thus returns the only instance of this object
 * the call can occur at any place in the code, no reference to the
 * GAudioOutput object has to be passed.
 */
GAudioOutput *GAudioOutput::instance()
{
    static GAudioOutput *_instance = 0;

    if (_instance == 0)
    {
        _instance = new GAudioOutput();
        // Set the application as parent to ensure that this object
        // will be destroyed when the main application exits
        _instance->setParent(qApp);
    }

    return _instance;
}

#define QGC_GAUDIOOUTPUT_KEY QString("QGC_AUDIOOUTPUT_")

GAudioOutput::GAudioOutput(QObject *parent) : QObject(parent),
    voiceIndex(0),
    emergency(false),
    muted(false)
{
    // Load settings
    QSettings settings;
    settings.sync();
    muted = settings.value(QGC_GAUDIOOUTPUT_KEY + "muted", muted).toBool();

#ifdef Q_OS_LINUX
    flite_init();
#endif

#if _MSC_VER
    pVoice = NULL;

    if (FAILED(::CoInitialize(NULL)))
    {
        qDebug("Creating COM object for audio output failed!");
    }

    else
    {

        HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);

        if (SUCCEEDED(hr))
        {
            hr = pVoice->Speak(L"QGC audio output active!", 0, NULL);
            //pVoice->Release();
            //pVoice = NULL;
        }
    }

#endif
    // Initialize audio output
    m_media = new Phonon::MediaObject(this);
    Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
    createPath(m_media, audioOutput);

    // Prepare regular emergency signal, will be fired off on calling startEmergency()
    emergencyTimer = new QTimer();
    connect(emergencyTimer, SIGNAL(timeout()), this, SLOT(beep()));

    switch (voiceIndex)
    {
    case 0:
        selectFemaleVoice();
        break;

    default:
        selectMaleVoice();
        break;
    }
}

GAudioOutput::~GAudioOutput()
{
#ifdef _MSC_VER
    pVoice->Release();
    pVoice = NULL;
    ::CoUninitialize();
#endif
}

void GAudioOutput::mute(bool mute)
{
    if (mute != muted)
    {
        this->muted = mute;
        QSettings settings;
        settings.setValue(QGC_GAUDIOOUTPUT_KEY + "muted", this->muted);
        settings.sync();
        emit mutedChanged(muted);
    }
}

bool GAudioOutput::isMuted()
{
    return this->muted;
}

bool GAudioOutput::say(QString text, int severity)
{
    if (!muted)
    {
        // TODO Add severity filter
        Q_UNUSED(severity);
        bool res = false;

        if (!emergency)
        {

            // Speech synthesis is only supported with MSVC compiler
#ifdef _MSC_VER
            /*SpeechSynthesizer synth = new SpeechSynthesizer();
            synth.SelectVoice("Microsoft Anna");
            synth.SpeakText(text.toStdString().c_str());
            res = true;*/
            /*ISpVoice * pVoice = NULL;
            if (FAILED(::CoInitialize(NULL)))
            {
            	qDebug("Creating COM object for audio output failed!");
            }
            else
            {
            	HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
            	if( SUCCEEDED( hr ) )
            	{
            		hr = */pVoice->Speak(text.toStdWString().c_str(), SPF_ASYNC, NULL);
            /*pVoice->WaitUntilDone(5000);
            pVoice->Release();
            pVoice = NULL;
            }
            }*/
#endif

#ifdef Q_OS_LINUX
            QTemporaryFile file;
            file.setFileTemplate("XXXXXX.wav");

            if (file.open())
            {
                cst_voice *v = register_cmu_us_kal(NULL);
                cst_wave *wav = flite_text_to_wave(text.toStdString().c_str(), v);
                // file.fileName() returns the unique file name
                cst_wave_save(wav, file.fileName().toStdString().c_str(), "riff");
                m_media->setCurrentSource(Phonon::MediaSource(QUrl::fromLocalFile(file.fileName().toStdString().c_str())));
                m_media->play();
                res = true;
            }

#endif

#ifdef Q_OS_MAC
            // Slashes necessary to have the right start to the sentence
            // copying data prevents SpeakString from reading additional chars
            text = "\\" + text;
            QStdWString str = text.toStdWString();
            unsigned char str2[1024] = {};
            memcpy(str2, text.toAscii().data(), str.length());
            SpeakString(str2);
            res = true;
#endif
        }

        return res;
    }

    else
    {
        return false;
    }
}

/**
 * @param text This message will be played after the alert beep
 */
bool GAudioOutput::alert(QString text)
{
    if (!emergency || !muted)
    {
        // Play alert sound
        beep();
        // Say alert message
        say(text, 2);
        return true;
    }

    else
    {
        return false;
    }
}

void GAudioOutput::notifyPositive()
{
    if (!muted)
    {
        // Use QFile to transform path for all OS
        QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/double_notify.wav"));
        //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str()));
        //m_media->play();
    }
}

void GAudioOutput::notifyNegative()
{
    if (!muted)
    {
        // Use QFile to transform path for all OS
        QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/flat_notify.wav"));
        //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str()));
        //m_media->play();
    }
}

/**
 * The emergency sound will be played continously during the emergency.
 * call stopEmergency() to disable it again. No speech synthesis or other
 * audio output is available during the emergency.
 *
 * @return true if the emergency could be started, false else
 */
bool GAudioOutput::startEmergency()
{
    if (!emergency)
    {
        emergency = true;

        // Beep immediately and then start timer
        if (!muted) beep();

        emergencyTimer->start(1500);
        QTimer::singleShot(5000, this, SLOT(stopEmergency()));
    }

    return true;
}

/**
 * Stops the continous emergency sound. Use startEmergency() to start
 * the emergency sound.
 *
 * @return true if the emergency could be stopped, false else
 */
bool GAudioOutput::stopEmergency()
{
    if (emergency)
    {
        emergency = false;
        emergencyTimer->stop();
    }

    return true;
}

void GAudioOutput::beep()
{
    if (!muted)
    {
        // Use QFile to transform path for all OS
        QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/alert.wav"));
        qDebug() << "FILE:" << f.fileName();
        //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str()));
        //m_media->play();
    }
}

void GAudioOutput::selectFemaleVoice()
{
#ifdef Q_OS_LINUX
    //this->voice = register_cmu_us_slt(NULL);
#endif
}

void GAudioOutput::selectMaleVoice()
{
#ifdef Q_OS_LINUX
    //this->voice = register_cmu_us_rms(NULL);
#endif
}

/*
void GAudioOutput::selectNeutralVoice()
{
#ifdef Q_OS_LINUX
    this->voice = register_cmu_us_awb(NULL);
#endif
}*/

QStringList GAudioOutput::listVoices(void)
{
    QStringList l;
#ifdef Q_OS_LINUX2
    cst_voice *voice;
    const cst_val *v;

    printf("Voices available: ");

    for (v = flite_voice_list; v; v = val_cdr(v))
    {
        voice = val_voice(val_car(v));
        QString s;
        s.sprintf("%s", voice->name);
        printf("%s", voice->name);
        l.append(s);
    }

    printf("\n");

#endif
    return l;

}
<commit_msg>Removed windows startup delay on voice output<commit_after>/*=====================================================================

QGroundControl Open Source Ground Control Station

(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

======================================================================*/

/**
 * @file
 *   @brief Implementation of audio output
 *
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
 *
 */

#include <QApplication>
#include <QSettings>
#include <QTemporaryFile>
#include "GAudioOutput.h"
#include "MG.h"

#include <QDebug>

#ifdef Q_OS_MAC
#include <ApplicationServices/ApplicationServices.h>
#endif

// Speech synthesis is only supported with MSVC compiler
#if _MSC_VER
// Documentation: http://msdn.microsoft.com/en-us/library/ee125082%28v=VS.85%29.aspx
#include <sapi.h>

//using System;
//using System.Speech.Synthesis;
#endif

#ifdef Q_OS_LINUX
extern "C" {
#include <flite/flite.h>
    cst_voice *register_cmu_us_kal(const char *voxdir);
};
#endif

#ifdef _MSC_VER
ISpVoice *GAudioOutput::pVoice = NULL;
#endif

/**
 * This class follows the singleton design pattern
 * @see http://en.wikipedia.org/wiki/Singleton_pattern
 * A call to this function thus returns the only instance of this object
 * the call can occur at any place in the code, no reference to the
 * GAudioOutput object has to be passed.
 */
GAudioOutput *GAudioOutput::instance()
{
    static GAudioOutput *_instance = 0;

    if (_instance == 0)
    {
        _instance = new GAudioOutput();
        // Set the application as parent to ensure that this object
        // will be destroyed when the main application exits
        _instance->setParent(qApp);
    }

    return _instance;
}

#define QGC_GAUDIOOUTPUT_KEY QString("QGC_AUDIOOUTPUT_")

GAudioOutput::GAudioOutput(QObject *parent) : QObject(parent),
    voiceIndex(0),
    emergency(false),
    muted(false)
{
    // Load settings
    QSettings settings;
    settings.sync();
    muted = settings.value(QGC_GAUDIOOUTPUT_KEY + "muted", muted).toBool();

#ifdef Q_OS_LINUX
    flite_init();
#endif

#if _MSC_VER
    pVoice = NULL;

    if (FAILED(::CoInitialize(NULL)))
    {
        qDebug("Creating COM object for audio output failed!");
    }

    else
    {

        HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);

        if (SUCCEEDED(hr))
        {
            //hr = pVoice->Speak(L"QGC audio output active!", 0, NULL);
            //pVoice->Release();
            //pVoice = NULL;
        }
    }

#endif
    // Initialize audio output
    m_media = new Phonon::MediaObject(this);
    Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
    createPath(m_media, audioOutput);

    // Prepare regular emergency signal, will be fired off on calling startEmergency()
    emergencyTimer = new QTimer();
    connect(emergencyTimer, SIGNAL(timeout()), this, SLOT(beep()));

    switch (voiceIndex)
    {
    case 0:
        selectFemaleVoice();
        break;

    default:
        selectMaleVoice();
        break;
    }
}

GAudioOutput::~GAudioOutput()
{
#ifdef _MSC_VER
    pVoice->Release();
    pVoice = NULL;
    ::CoUninitialize();
#endif
}

void GAudioOutput::mute(bool mute)
{
    if (mute != muted)
    {
        this->muted = mute;
        QSettings settings;
        settings.setValue(QGC_GAUDIOOUTPUT_KEY + "muted", this->muted);
        settings.sync();
        emit mutedChanged(muted);
    }
}

bool GAudioOutput::isMuted()
{
    return this->muted;
}

bool GAudioOutput::say(QString text, int severity)
{
    if (!muted)
    {
        // TODO Add severity filter
        Q_UNUSED(severity);
        bool res = false;

        if (!emergency)
        {

            // Speech synthesis is only supported with MSVC compiler
#ifdef _MSC_VER
            /*SpeechSynthesizer synth = new SpeechSynthesizer();
            synth.SelectVoice("Microsoft Anna");
            synth.SpeakText(text.toStdString().c_str());
            res = true;*/
            /*ISpVoice * pVoice = NULL;
            if (FAILED(::CoInitialize(NULL)))
            {
            	qDebug("Creating COM object for audio output failed!");
            }
            else
            {
            	HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);
            	if( SUCCEEDED( hr ) )
            	{
            		hr = */pVoice->Speak(text.toStdWString().c_str(), SPF_ASYNC, NULL);
            /*pVoice->WaitUntilDone(5000);
            pVoice->Release();
            pVoice = NULL;
            }
            }*/
#endif

#ifdef Q_OS_LINUX
            QTemporaryFile file;
            file.setFileTemplate("XXXXXX.wav");

            if (file.open())
            {
                cst_voice *v = register_cmu_us_kal(NULL);
                cst_wave *wav = flite_text_to_wave(text.toStdString().c_str(), v);
                // file.fileName() returns the unique file name
                cst_wave_save(wav, file.fileName().toStdString().c_str(), "riff");
                m_media->setCurrentSource(Phonon::MediaSource(QUrl::fromLocalFile(file.fileName().toStdString().c_str())));
                m_media->play();
                res = true;
            }

#endif

#ifdef Q_OS_MAC
            // Slashes necessary to have the right start to the sentence
            // copying data prevents SpeakString from reading additional chars
            text = "\\" + text;
            QStdWString str = text.toStdWString();
            unsigned char str2[1024] = {};
            memcpy(str2, text.toAscii().data(), str.length());
            SpeakString(str2);
            res = true;
#endif
        }

        return res;
    }

    else
    {
        return false;
    }
}

/**
 * @param text This message will be played after the alert beep
 */
bool GAudioOutput::alert(QString text)
{
    if (!emergency || !muted)
    {
        // Play alert sound
        beep();
        // Say alert message
        say(text, 2);
        return true;
    }

    else
    {
        return false;
    }
}

void GAudioOutput::notifyPositive()
{
    if (!muted)
    {
        // Use QFile to transform path for all OS
        QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/double_notify.wav"));
        //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str()));
        //m_media->play();
    }
}

void GAudioOutput::notifyNegative()
{
    if (!muted)
    {
        // Use QFile to transform path for all OS
        QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/flat_notify.wav"));
        //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str()));
        //m_media->play();
    }
}

/**
 * The emergency sound will be played continously during the emergency.
 * call stopEmergency() to disable it again. No speech synthesis or other
 * audio output is available during the emergency.
 *
 * @return true if the emergency could be started, false else
 */
bool GAudioOutput::startEmergency()
{
    if (!emergency)
    {
        emergency = true;

        // Beep immediately and then start timer
        if (!muted) beep();

        emergencyTimer->start(1500);
        QTimer::singleShot(5000, this, SLOT(stopEmergency()));
    }

    return true;
}

/**
 * Stops the continous emergency sound. Use startEmergency() to start
 * the emergency sound.
 *
 * @return true if the emergency could be stopped, false else
 */
bool GAudioOutput::stopEmergency()
{
    if (emergency)
    {
        emergency = false;
        emergencyTimer->stop();
    }

    return true;
}

void GAudioOutput::beep()
{
    if (!muted)
    {
        // Use QFile to transform path for all OS
        QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/alert.wav"));
        qDebug() << "FILE:" << f.fileName();
        //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str()));
        //m_media->play();
    }
}

void GAudioOutput::selectFemaleVoice()
{
#ifdef Q_OS_LINUX
    //this->voice = register_cmu_us_slt(NULL);
#endif
}

void GAudioOutput::selectMaleVoice()
{
#ifdef Q_OS_LINUX
    //this->voice = register_cmu_us_rms(NULL);
#endif
}

/*
void GAudioOutput::selectNeutralVoice()
{
#ifdef Q_OS_LINUX
    this->voice = register_cmu_us_awb(NULL);
#endif
}*/

QStringList GAudioOutput::listVoices(void)
{
    QStringList l;
#ifdef Q_OS_LINUX2
    cst_voice *voice;
    const cst_val *v;

    printf("Voices available: ");

    for (v = flite_voice_list; v; v = val_cdr(v))
    {
        voice = val_voice(val_car(v));
        QString s;
        s.sprintf("%s", voice->name);
        printf("%s", voice->name);
        l.append(s);
    }

    printf("\n");

#endif
    return l;

}
<|endoftext|>


<commit_before>//
// SRTerrain class : a subclass of vtDynTerrainGeom which exposes
//  Stefan Roettger's CLOD algorithm.
//
// utilizes: Roettger's MINI library implementation
// http://wwwvis.informatik.uni-stuttgart.de/~roettger
//
// Copyright (c) 2002 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "SRTerrain.h"

using namespace mini;
#ifdef _MSC_VER
#pragma comment( lib, "libMini.lib" )
#endif

/////////////////////////////////////////////////////////////////////////////

//
// Constructor/destructor
//
SRTerrain::SRTerrain() : vtDynTerrainGeom()
{
	m_fResolution = 10000.0f;
	m_pMini = NULL;
}

SRTerrain::~SRTerrain()
{
	if (m_pMini)
	{
		delete m_pMini;
		m_pMini = NULL;
	}
}

/////////////////////////////////////////////////////////////////////////////

//
// Unfortunately the following statics are required because libMini only
// supports some functionality by callback, and the callback is only a
// simple C function which has no context to tell us which terrain.
//
static vtElevationGrid *s_pGrid;
static SRTerrain *s_pSRTerrain;
static int myfancnt, myvtxcnt;
static float s_fOceanDepth;

void beginfan_vtp()
{
	if (myfancnt++>0)
		glEnd();
	glBegin(GL_TRIANGLE_FAN);
	myvtxcnt-=2;	// 2 vertices are needed to start each fan
}

void fanvertex_vtp(float x, float y, float z)
{
   glVertex3f(x,y,z);
   myvtxcnt++;
}

void notify_vtp(int i, int j, int size)
{
	// check to see if we need to switch texture
	if (s_pSRTerrain->m_iTPatchDim > 1 && size == s_pSRTerrain->m_iBlockSize)
	{
		int a = i / size;
		int b = j / size;
		s_pSRTerrain->LoadBlockMaterial(a, b);
	}
}

short int getelevation_vtp1(int i, int j, int size)
{
	short elev = s_pGrid->GetValue(i, j);
	if (elev == 0)
		return (short) s_fOceanDepth;
	else
		return elev;
}

float getelevation_vtp2(int i, int j, int size)
{
	float elev = s_pGrid->GetFValue(i, j);
	if (elev == 0.0f)
		return s_fOceanDepth;
	else
		return elev;
}

//
// Initialize the terrain data
// fZScale converts from height values (meters) to world coordinates
//
bool SRTerrain::Init(vtElevationGrid *pGrid, float fZScale,
					 float fOceanDepth, int &iError)
{
	// Initializes necessary field of the parent class
	BasicInit(pGrid);

	m_fHeightScale = fZScale;

	// compute n (log2 of grid size)
	// ensure that the grid is size (1 << n) + 1
	int n = vt_log2(m_iColumns - 1);
	int required_size = (1<<n) + 1;
	if (m_iColumns != required_size || m_iRows != required_size)
	{
		iError = TERRAIN_ERROR_NOTPOWER2;
		return false;
	}

	int size = m_iColumns;
	float dim = m_fXStep;
	float cellaspect = m_fZStep / m_fXStep;

	s_pGrid = pGrid;
	s_fOceanDepth = fOceanDepth;

	if (pGrid->IsFloatMode())
	{
		float *image = NULL;
		m_pMini = new ministub(image,
				&size, &dim, fZScale, cellaspect,
				beginfan_vtp, fanvertex_vtp, notify_vtp,
				getelevation_vtp2);
	}
	else
	{
		short *image = NULL;
		m_pMini = new ministub(image,
				&size, &dim, fZScale, cellaspect,
				beginfan_vtp, fanvertex_vtp, notify_vtp,
				getelevation_vtp1);
	}

	m_iDrawnTriangles = -1;
	m_iBlockSize = m_iColumns / 4;
	return true;
}

//
// This will be called once per frame, during the culling pass.
//
// However, libMini does not allow you to call the culling pass
// independently of the rendering pass, so we cannot do culling here.
// Instead, just store the values for later use.
//
void SRTerrain::DoCulling(FPoint3 &eyepos_ogl, IPoint2 window_size, float fov)
{
	// store for later
	m_eyepos_ogl = eyepos_ogl;
	m_window_size = window_size;
	float aspect = (float)window_size.x / window_size.y;
	float fov_y2 = atan(tan (fov/2) / aspect);
	m_fFOVY = fov_y2 * 2.0f * 180 / PIf;
}

void SRTerrain::DoRender()
{
	// Prepare the render state for our OpenGL usage
	PreRender();

	// Render the triangles
	RenderSurface();

	// Clean up
	PostRender();
}

void SRTerrain::LoadSingleMaterial()
{
	// single texture for the whole terrain
	vtMaterial *pMat = GetMaterial(0);
	if (pMat)
	{
		pMat->Apply();
		SetupTexGen(1.0f);
	}
}

void SRTerrain::LoadBlockMaterial(int a, int b)
{
	// we can't change the texture between glBegin/glEnd
	if (myfancnt++>0)
		glEnd();

	// each block has it's own texture map
	int matidx = a*m_iTPatchDim + (m_iTPatchDim-1-b);
	vtMaterial *pMat = GetMaterial(matidx);
	if (pMat)
	{
		pMat->Apply();
		SetupBlockTexGen(a, b);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	}

	glBegin(GL_TRIANGLE_FAN);
}

void SRTerrain::RenderSurface()
{
	s_pSRTerrain = this;

	if (m_iTPatchDim == 1)
		LoadSingleMaterial();

	RenderPass();

	// how to do a second rendering pass
	if (m_bDetailTexture)
	{
		// once again, with the detail texture material
		m_pDetailMat->Apply();

		// the uv tiling is different (usually highly repetitive)
		SetupTexGen(m_fDetailTiling);

		// draw the second pass
		glPolygonOffset(-1.0f, -1.0f);
		glEnable(GL_POLYGON_OFFSET_FILL);
		RenderPass();
		glDisable(GL_POLYGON_OFFSET_FILL);
	}
	DisableTexGen();
}

#define ADAPTION_SPEED	.0001f	// speed at which detail converges

void SRTerrain::RenderPass()
{
	// grab necessary values from the VTP Scene framework
	vtScene *pScene = vtGetScene();
	vtCamera *pCamera = pScene->GetCamera();
	float nearp = pCamera->GetHither();
	float farp = pCamera->GetYon();

	float aspect = (float)m_window_size.x / m_window_size.y;

	float ex = m_eyepos_ogl.x;
	float ey = m_eyepos_ogl.y;
	float ez = m_eyepos_ogl.z;

	// Get up vector and direction vector from camera matrix
	FMatrix4 mat;
	pCamera->GetTransform1(mat);
	FPoint3 up(0.0f, 1.0f, 0.0f), eye_up;
	mat.TransformVector(up, eye_up);
	float ux = eye_up.x;
	float uy = eye_up.y;
	float uz = eye_up.z;

	FPoint3 forward(0.0f, 0.0f, -1.0f), eye_forward;
	mat.TransformVector(forward, eye_forward);
	float dx = eye_forward.x;
	float dy = eye_forward.y;
	float dz = eye_forward.z;

	myfancnt = myvtxcnt = 0;
	int size = m_iColumns;

	// Convert the eye location to the unusual coordinate scheme of libMini.
	ex-=(m_iColumns/2)*m_fXStep;
	ez+=(m_iRows/2)*m_fZStep;

	m_pMini->draw(m_fResolution,
				ex, ey, ez,
				dx, dy, dz,
				ux, uy, uz,
				m_fFOVY, aspect,
				nearp, farp);

	if (myfancnt>0) glEnd();

	// We are drawing fans, so the number of triangles is roughly equal to
	// number of vertices
	m_iDrawnTriangles = myvtxcnt;

	// adaptively adjust resolution threshold up or down to attain
	// the desired polygon (vertex) count target
	int diff = m_iDrawnTriangles - m_iPolygonTarget;
	int iRange = m_iPolygonTarget / 20;		// ensure within 5%
	float adjust = 1.0f;
	if (diff < -iRange) adjust = 1.0f + (-diff * ADAPTION_SPEED);
	if (diff > iRange) adjust = 1.0f + (-diff * ADAPTION_SPEED);

	m_fResolution *= adjust;

	// keep the error within reasonable bounds
	if (m_fResolution < 1.0f)
		m_fResolution = 1.0f;
	if (m_fResolution > 4E7)
		m_fResolution = 4E7;
}

//
// These methods are called when the framework needs to know the surface
// position of the terrain at a given grid point.  Supply the height
// value from our own data structures.
//
float SRTerrain::GetElevation(int iX, int iZ) const
{
	return m_pMini->getheight(iX, iZ);
}

void SRTerrain::GetLocation(int i, int j, FPoint3 &p) const
{
	p.Set(m_fXLookup[i],
		  m_pMini->getheight(i, j),
		  m_fZLookup[j]);
}

<commit_msg>tweak<commit_after>//
// SRTerrain class : a subclass of vtDynTerrainGeom which exposes
//  Stefan Roettger's CLOD algorithm.
//
// utilizes: Roettger's MINI library implementation
// http://wwwvis.informatik.uni-stuttgart.de/~roettger
//
// Copyright (c) 2002-2004 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "SRTerrain.h"

using namespace mini;
#ifdef _MSC_VER
#pragma comment( lib, "libMini.lib" )
#endif

/////////////////////////////////////////////////////////////////////////////

//
// Constructor/destructor
//
SRTerrain::SRTerrain() : vtDynTerrainGeom()
{
	m_fResolution = 10000.0f;
	m_pMini = NULL;
}

SRTerrain::~SRTerrain()
{
	if (m_pMini)
	{
		delete m_pMini;
		m_pMini = NULL;
	}
}

/////////////////////////////////////////////////////////////////////////////

//
// Unfortunately the following statics are required because libMini only
// supports some functionality by callback, and the callback is only a
// simple C function which has no context to tell us which terrain.
//
static vtElevationGrid *s_pGrid;
static SRTerrain *s_pSRTerrain;
static int myfancnt, myvtxcnt;
static float s_fOceanDepth;

void beginfan_vtp()
{
	if (myfancnt++>0)
		glEnd();
	glBegin(GL_TRIANGLE_FAN);
	myvtxcnt-=2;	// 2 vertices are needed to start each fan
}

void fanvertex_vtp(float x, float y, float z)
{
   glVertex3f(x,y,z);
   myvtxcnt++;
}

void notify_vtp(int i, int j, int size)
{
	// check to see if we need to switch texture
	if (s_pSRTerrain->m_iTPatchDim > 1 && size == s_pSRTerrain->m_iBlockSize)
	{
		int a = i / size;
		int b = j / size;
		s_pSRTerrain->LoadBlockMaterial(a, b);
	}
}

short int getelevation_vtp1(int i, int j, int size)
{
	short elev = s_pGrid->GetValue(i, j);
	if (elev == 0)
		return (short) s_fOceanDepth;
	else
		return elev;
}

float getelevation_vtp2(int i, int j, int size)
{
	float elev = s_pGrid->GetFValue(i, j);
	if (elev == 0.0f)
		return s_fOceanDepth;
	else
		return elev;
}

//
// Initialize the terrain data
// fZScale converts from height values (meters) to world coordinates
//
bool SRTerrain::Init(vtElevationGrid *pGrid, float fZScale,
					 float fOceanDepth, int &iError)
{
	// Initializes necessary field of the parent class
	BasicInit(pGrid);

	m_fHeightScale = fZScale;

	// compute n (log2 of grid size)
	// ensure that the grid is size (1 << n) + 1
	int n = vt_log2(m_iColumns - 1);
	int required_size = (1<<n) + 1;
	if (m_iColumns != required_size || m_iRows != required_size)
	{
		iError = TERRAIN_ERROR_NOTPOWER2;
		return false;
	}

	int size = m_iColumns;
	float dim = m_fXStep;
	float cellaspect = m_fZStep / m_fXStep;

	s_pGrid = pGrid;
	s_fOceanDepth = fOceanDepth;

	if (pGrid->IsFloatMode())
	{
		float *image = NULL;
		m_pMini = new ministub(image,
				&size, &dim, fZScale, cellaspect,
				beginfan_vtp, fanvertex_vtp, notify_vtp,
				getelevation_vtp2);
	}
	else
	{
		short *image = NULL;
		m_pMini = new ministub(image,
				&size, &dim, fZScale, cellaspect,
				beginfan_vtp, fanvertex_vtp, notify_vtp,
				getelevation_vtp1);
	}

	m_iDrawnTriangles = -1;
	m_iBlockSize = m_iColumns / 4;
	return true;
}

//
// This will be called once per frame, during the culling pass.
//
// However, libMini does not allow you to call the culling pass
// independently of the rendering pass, so we cannot do culling here.
// Instead, just store the values for later use.
//
void SRTerrain::DoCulling(FPoint3 &eyepos_ogl, IPoint2 window_size, float fov)
{
	// store for later
	m_eyepos_ogl = eyepos_ogl;
	m_window_size = window_size;
	float aspect = (float)window_size.x / window_size.y;
	float fov_y2 = atan(tan (fov/2) / aspect);
	m_fFOVY = fov_y2 * 2.0f * 180 / PIf;
}

void SRTerrain::DoRender()
{
	// Prepare the render state for our OpenGL usage
	PreRender();

	// Render the triangles
	RenderSurface();

	// Clean up
	PostRender();
}

void SRTerrain::LoadSingleMaterial()
{
	// single texture for the whole terrain
	vtMaterial *pMat = GetMaterial(0);
	if (pMat)
	{
		pMat->Apply();
		SetupTexGen(1.0f);
	}
}

void SRTerrain::LoadBlockMaterial(int a, int b)
{
	// we can't change the texture between glBegin/glEnd
	if (myfancnt++>0)
		glEnd();

	// each block has it's own texture map
	int matidx = a*m_iTPatchDim + (m_iTPatchDim-1-b);
	vtMaterial *pMat = GetMaterial(matidx);
	if (pMat)
	{
		pMat->Apply();
		SetupBlockTexGen(a, b);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	}

	glBegin(GL_TRIANGLE_FAN);
}

void SRTerrain::RenderSurface()
{
	s_pSRTerrain = this;

	if (m_iTPatchDim == 1)
		LoadSingleMaterial();

	RenderPass();

	// how to do a second rendering pass
	if (m_bDetailTexture)
	{
		// once again, with the detail texture material
		m_pDetailMat->Apply();

		// the uv tiling is different (usually highly repetitive)
		SetupTexGen(m_fDetailTiling);

		// draw the second pass
		glPolygonOffset(-1.0f, -1.0f);
		glEnable(GL_POLYGON_OFFSET_FILL);
		RenderPass();
		glDisable(GL_POLYGON_OFFSET_FILL);
	}
	DisableTexGen();
}

#define ADAPTION_SPEED	.0001f	// speed at which detail converges

void SRTerrain::RenderPass()
{
	// grab necessary values from the VTP Scene framework
	vtScene *pScene = vtGetScene();
	vtCamera *pCamera = pScene->GetCamera();
	float nearp = pCamera->GetHither();
	float farp = pCamera->GetYon();

	float aspect = (float)m_window_size.x / m_window_size.y;

	float ex = m_eyepos_ogl.x;
	float ey = m_eyepos_ogl.y;
	float ez = m_eyepos_ogl.z;

	// Get up vector and direction vector from camera matrix
	FMatrix4 mat;
	pCamera->GetTransform1(mat);
	FPoint3 up(0.0f, 1.0f, 0.0f), eye_up;
	mat.TransformVector(up, eye_up);
	float ux = eye_up.x;
	float uy = eye_up.y;
	float uz = eye_up.z;

	FPoint3 forward(0.0f, 0.0f, -1.0f), eye_forward;
	mat.TransformVector(forward, eye_forward);
	float dx = eye_forward.x;
	float dy = eye_forward.y;
	float dz = eye_forward.z;

	myfancnt = myvtxcnt = 0;
	int size = m_iColumns;

	// Convert the eye location to the unusual coordinate scheme of libMini.
	ex-=(m_iColumns/2)*m_fXStep;
	ez+=(m_iRows/2)*m_fZStep;

	m_pMini->draw(m_fResolution,
				ex, ey, ez,
				dx, dy, dz,
				ux, uy, uz,
				m_fFOVY, aspect,
				nearp, farp);

	if (myfancnt>0) glEnd();

	// We are drawing fans, so the number of triangles is roughly equal to
	// number of vertices
	m_iDrawnTriangles = myvtxcnt;

	// adaptively adjust resolution threshold up or down to attain
	// the desired polygon (vertex) count target
	int diff = m_iDrawnTriangles - m_iPolygonTarget;
	int iRange = m_iPolygonTarget / 20;		// ensure within 5%
	float adjust = 1.0f;
	if (diff < -iRange) adjust = 1.0f + (-diff * ADAPTION_SPEED);
	if (diff > iRange) adjust = 1.0f + (-diff * ADAPTION_SPEED);

	m_fResolution *= adjust;

	// keep the error within reasonable bounds
	if (m_fResolution < 1.0f)
		m_fResolution = 1.0f;
	if (m_fResolution > 4E7)
		m_fResolution = 4E7;
}

//
// These methods are called when the framework needs to know the surface
// position of the terrain at a given grid point.  Supply the height
// value from our own data structures.
//
float SRTerrain::GetElevation(int iX, int iZ) const
{
	return m_pMini->getheight(iX, iZ);
}

void SRTerrain::GetLocation(int i, int j, FPoint3 &p) const
{
	p.Set(m_fXLookup[i],
		  m_pMini->getheight(i, j),
		  m_fZLookup[j]);
}

<|endoftext|>


<commit_before>#include "..\include\im\Urho3D\imgui.h"

#include "..\include\im\Urho3D\imguiEvents.h"
#include "../include/im/Urho3D/imguiGraphics.h"

#include <imgui.h>

#include <Urho3D/Core/CoreEvents.h>
#include <Urho3D/Core/Profiler.h>
#include <Urho3D/Graphics/Graphics.h>
#include <Urho3D/Graphics/GraphicsEvents.h>
#include <Urho3D/Graphics/Texture.h>
#include <Urho3D/Graphics/Texture2D.h>
#include <Urho3D/Input/Input.h>
#include <Urho3D/Input/InputEvents.h>
#include <Urho3D/ThirdParty/SDL/SDL_clipboard.h>

namespace Urho3D
{
	//
	// Constructor
	//
	imgui::imgui(Context * context) :
		Object(context)
	{

		ImGuiIO& io = ImGui::GetIO();

		io.KeyMap[ImGuiKey_Tab] = SCANCODE_TAB;                 // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
		io.KeyMap[ImGuiKey_LeftArrow] = SCANCODE_LEFT;
		io.KeyMap[ImGuiKey_RightArrow] = SCANCODE_RIGHT;
		io.KeyMap[ImGuiKey_UpArrow] = SCANCODE_UP;
		io.KeyMap[ImGuiKey_DownArrow] = SCANCODE_DOWN;
		io.KeyMap[ImGuiKey_Home] = SCANCODE_HOME;
		io.KeyMap[ImGuiKey_End] = SCANCODE_END;
		io.KeyMap[ImGuiKey_Delete] = SCANCODE_DELETE;
		io.KeyMap[ImGuiKey_Backspace] = SCANCODE_BACKSPACE;
		io.KeyMap[ImGuiKey_Enter] = SCANCODE_RETURN;
		io.KeyMap[ImGuiKey_Escape] = SCANCODE_ESCAPE;
		io.KeyMap[ImGuiKey_A] = SCANCODE_A;
		io.KeyMap[ImGuiKey_C] = SCANCODE_C;
		io.KeyMap[ImGuiKey_V] = SCANCODE_V;
		io.KeyMap[ImGuiKey_X] = SCANCODE_X;
		io.KeyMap[ImGuiKey_Y] = SCANCODE_Y;
		io.KeyMap[ImGuiKey_Z] = SCANCODE_Z;

		// setup callback functions
		io.RenderDrawListsFn = ImGui_Impl_RenderDrawLists;
		io.SetClipboardTextFn = SetClipboardText;
		io.GetClipboardTextFn = GetClipboardText;

		// Subscribe to events
		SubscribeToEvent(E_POSTUPDATE, URHO3D_HANDLER(imgui, HandlePostUpdate));
		SubscribeToEvent(E_ENDRENDERING, URHO3D_HANDLER(imgui, HandleEndRendering));

		SubscribeToEvent(E_KEYUP, URHO3D_HANDLER(imgui, HandleKeyUp));
		SubscribeToEvent(E_KEYDOWN, URHO3D_HANDLER(imgui, HandleKeyDown));
		SubscribeToEvent(E_TEXTINPUT, URHO3D_HANDLER(imgui, HandleTextInput));

		SubscribeToEvent(E_TOUCHBEGIN, URHO3D_HANDLER(imgui, HandleTouchBegin));
		SubscribeToEvent(E_TOUCHEND, URHO3D_HANDLER(imgui, HandleTouchEnd));
		SubscribeToEvent(E_TOUCHMOVE, URHO3D_HANDLER(imgui, HandleTouchMove));
	}

	//
	// Desctructor
	//
	imgui::~imgui()
	{
		ImGui_Impl_InvalidateDeviceObjects();
	}

	//
	// GetClipboardText
	//
	const char * imgui::GetClipboardText()
	{
		return SDL_GetClipboardText();
	}

	//
	// SetClipboardText
	//
	void imgui::SetClipboardText(const char * text)
	{
		SDL_SetClipboardText(text);
	}

	//
	// HandlePostUpdate
	//
	void imgui::HandlePostUpdate(StringHash eventType, VariantMap & eventData)
	{
		if (!ImGui_Impl_GetFontTexture())
			ImGui_Impl_CreateDeviceObjects(context_);

		using namespace PostUpdate;
		float timeStep = eventData[P_TIMESTEP].GetFloat();

		auto& io = ImGui::GetIO();

		// Get display size (every frame for resizing)
		auto graphics = GetSubsystem<Graphics>();
		io.DisplaySize = ImVec2((float)graphics->GetWidth(), (float)graphics->GetHeight());

		// Setup time step
		io.DeltaTime = timeStep > 0.0f ? timeStep : 1.0f / 60.0f;

		// mouse input handling
		auto input = GetSubsystem<Input>();
		if (input->IsMouseVisible() && !input->GetTouchEmulation())
		{
			IntVector2 pos = input->GetMousePosition();
			// Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
			io.MousePos.x = (float)pos.x_;
			io.MousePos.y = (float)pos.y_;
		}
		else
		{
			io.MousePos.x = -1.0f;
			io.MousePos.y = -1.0f;
		}

		io.MouseDown[0] = input->GetMouseButtonDown(MOUSEB_LEFT);
		io.MouseDown[1] = input->GetMouseButtonDown(MOUSEB_RIGHT);
		io.MouseDown[2] = input->GetMouseButtonDown(MOUSEB_MIDDLE);
		io.MouseWheel = (float)input->GetMouseMoveWheel();

		// Start new ImGui frame
		ImGui::NewFrame();

		// Send imgui NewFrame events, so users can use it as a guarenteed way to use imgui after NewFrame() was called.
		URHO3D_PROFILE(ImGuiNewFrame);
		SendEvent(E_IMGUI_NEWFRAME);
	}

	//
	// HandleEndRendering
	//
	void imgui::HandleEndRendering(StringHash eventType, VariantMap & eventData)
	{
		// Render after Urho's main renderer has rendered
		URHO3D_PROFILE(ImGuiRender);
		ImGui::Render();
	}

	//
	// HandleKeyUp
	//
	void imgui::HandleKeyUp(StringHash eventType, VariantMap & eventData)
	{
		using namespace KeyUp;

		ImGuiIO& io = ImGui::GetIO();
		int Scancode = eventData[P_SCANCODE].GetInt();

		if (Scancode < 512)
			io.KeysDown[Scancode] = false;
	}

	//
	// HandleKeyDown
	//
	void imgui::HandleKeyDown(StringHash eventType, VariantMap & eventData)
	{
		using namespace KeyDown;
		ImGuiIO& io = ImGui::GetIO();
		int Scancode = eventData[P_SCANCODE].GetInt();

		if (Scancode < 512)
			io.KeysDown[Scancode] = true;
	}

	//
	// HandleTextInput
	//
	void imgui::HandleTextInput(StringHash eventType, VariantMap & eventData)
	{
		using namespace TextInput;
		const String& text = eventData[P_TEXT].GetString();
		ImGuiIO& io = ImGui::GetIO();
		io.AddInputCharactersUTF8(text.CString());
	}

	//
	// HandleTouchBegin
	//
	void imgui::HandleTouchBegin(StringHash eventType, VariantMap & eventData)
	{
		using namespace TouchBegin;

		if (!touching)
		{
			touching = true;
			single_touchID = eventData[P_TOUCHID].GetInt();

			auto& io = ImGui::GetIO();
			io.MousePos.x = (float)eventData[P_X].GetInt();
			io.MousePos.y = (float)eventData[P_Y].GetInt();
			io.MouseDown[0] = true;
		}
	}

	//
	// HandleTouchEnd
	//
	void imgui::HandleTouchEnd(StringHash eventType, VariantMap & eventData)
	{
		using namespace TouchEnd;

		int touchID = eventData[P_TOUCHID].GetInt();

		if (touchID == single_touchID)
		{
			auto& io = ImGui::GetIO();
			io.MousePos.x = (float)eventData[P_X].GetInt();
			io.MousePos.y = (float)eventData[P_Y].GetInt();
			io.MouseDown[0] = false;
		}

		touching = false;
	}

	//
	// HandleTouchMove
	//
	void imgui::HandleTouchMove(StringHash eventType, VariantMap & eventData)
	{
		using namespace TouchMove;

		int touchID = eventData[P_TOUCHID].GetInt();

		if (touchID == single_touchID)
		{
			auto& io = ImGui::GetIO();
			io.MousePos.x = (float)eventData[P_X].GetInt();
			io.MousePos.y = (float)eventData[P_Y].GetInt();
		}
	}
}<commit_msg>Fixed missing modifier keys.<commit_after>#include "..\include\im\Urho3D\imgui.h"

#include "..\include\im\Urho3D\imguiEvents.h"
#include "../include/im/Urho3D/imguiGraphics.h"

#include <imgui.h>

#include <Urho3D/Core/CoreEvents.h>
#include <Urho3D/Core/Profiler.h>
#include <Urho3D/Graphics/Graphics.h>
#include <Urho3D/Graphics/GraphicsEvents.h>
#include <Urho3D/Graphics/Texture.h>
#include <Urho3D/Graphics/Texture2D.h>
#include <Urho3D/Input/Input.h>
#include <Urho3D/Input/InputEvents.h>
#include <Urho3D/ThirdParty/SDL/SDL_clipboard.h>

namespace Urho3D
{
	//
	// Constructor
	//
	imgui::imgui(Context * context) :
		Object(context)
	{

		ImGuiIO& io = ImGui::GetIO();

		io.KeyMap[ImGuiKey_Tab] = SCANCODE_TAB;                 // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
		io.KeyMap[ImGuiKey_LeftArrow] = SCANCODE_LEFT;
		io.KeyMap[ImGuiKey_RightArrow] = SCANCODE_RIGHT;
		io.KeyMap[ImGuiKey_UpArrow] = SCANCODE_UP;
		io.KeyMap[ImGuiKey_DownArrow] = SCANCODE_DOWN;
		io.KeyMap[ImGuiKey_Home] = SCANCODE_HOME;
		io.KeyMap[ImGuiKey_End] = SCANCODE_END;
		io.KeyMap[ImGuiKey_Delete] = SCANCODE_DELETE;
		io.KeyMap[ImGuiKey_Backspace] = SCANCODE_BACKSPACE;
		io.KeyMap[ImGuiKey_Enter] = SCANCODE_RETURN;
		io.KeyMap[ImGuiKey_Escape] = SCANCODE_ESCAPE;
		io.KeyMap[ImGuiKey_A] = SCANCODE_A;
		io.KeyMap[ImGuiKey_C] = SCANCODE_C;
		io.KeyMap[ImGuiKey_V] = SCANCODE_V;
		io.KeyMap[ImGuiKey_X] = SCANCODE_X;
		io.KeyMap[ImGuiKey_Y] = SCANCODE_Y;
		io.KeyMap[ImGuiKey_Z] = SCANCODE_Z;

		// setup callback functions
		io.RenderDrawListsFn = ImGui_Impl_RenderDrawLists;
		io.SetClipboardTextFn = SetClipboardText;
		io.GetClipboardTextFn = GetClipboardText;

		// Subscribe to events
		SubscribeToEvent(E_POSTUPDATE, URHO3D_HANDLER(imgui, HandlePostUpdate));
		SubscribeToEvent(E_ENDRENDERING, URHO3D_HANDLER(imgui, HandleEndRendering));

		SubscribeToEvent(E_KEYUP, URHO3D_HANDLER(imgui, HandleKeyUp));
		SubscribeToEvent(E_KEYDOWN, URHO3D_HANDLER(imgui, HandleKeyDown));
		SubscribeToEvent(E_TEXTINPUT, URHO3D_HANDLER(imgui, HandleTextInput));

		SubscribeToEvent(E_TOUCHBEGIN, URHO3D_HANDLER(imgui, HandleTouchBegin));
		SubscribeToEvent(E_TOUCHEND, URHO3D_HANDLER(imgui, HandleTouchEnd));
		SubscribeToEvent(E_TOUCHMOVE, URHO3D_HANDLER(imgui, HandleTouchMove));
	}

	//
	// Desctructor
	//
	imgui::~imgui()
	{
		ImGui_Impl_InvalidateDeviceObjects();
	}

	//
	// GetClipboardText
	//
	const char * imgui::GetClipboardText()
	{
		return SDL_GetClipboardText();
	}

	//
	// SetClipboardText
	//
	void imgui::SetClipboardText(const char * text)
	{
		SDL_SetClipboardText(text);
	}

	//
	// HandlePostUpdate
	//
	void imgui::HandlePostUpdate(StringHash eventType, VariantMap & eventData)
	{
		if (!ImGui_Impl_GetFontTexture())
			ImGui_Impl_CreateDeviceObjects(context_);

		using namespace PostUpdate;
		float timeStep = eventData[P_TIMESTEP].GetFloat();

		auto& io = ImGui::GetIO();

		// Get display size (every frame for resizing)
		auto graphics = GetSubsystem<Graphics>();
		io.DisplaySize = ImVec2((float)graphics->GetWidth(), (float)graphics->GetHeight());

		// Setup time step
		io.DeltaTime = timeStep > 0.0f ? timeStep : 1.0f / 60.0f;

		// mouse input
		auto input = GetSubsystem<Input>();
		if (input->IsMouseVisible() && !input->GetTouchEmulation())
		{
			IntVector2 pos = input->GetMousePosition();
			// Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
			io.MousePos.x = (float)pos.x_;
			io.MousePos.y = (float)pos.y_;
		}
		else
		{
			io.MousePos.x = -1.0f;
			io.MousePos.y = -1.0f;
		}

		io.MouseDown[0] = input->GetMouseButtonDown(MOUSEB_LEFT);
		io.MouseDown[1] = input->GetMouseButtonDown(MOUSEB_RIGHT);
		io.MouseDown[2] = input->GetMouseButtonDown(MOUSEB_MIDDLE);
		io.MouseWheel = (float)input->GetMouseMoveWheel();

		// Modifiers
		io.KeyCtrl = input->GetQualifierDown(QUAL_CTRL);
		io.KeyShift = input->GetQualifierDown(QUAL_SHIFT);
		io.KeyAlt = input->GetQualifierDown(QUAL_ALT);

		// Start new ImGui frame
		ImGui::NewFrame();

		// Send imgui NewFrame events, so users can use it as a guarenteed way to use imgui after NewFrame() was called.
		URHO3D_PROFILE(ImGuiNewFrame);
		SendEvent(E_IMGUI_NEWFRAME);
	}

	//
	// HandleEndRendering
	//
	void imgui::HandleEndRendering(StringHash eventType, VariantMap & eventData)
	{
		// Render after Urho's main renderer has rendered
		URHO3D_PROFILE(ImGuiRender);
		ImGui::Render();
	}

	//
	// HandleKeyUp
	//
	void imgui::HandleKeyUp(StringHash eventType, VariantMap & eventData)
	{
		using namespace KeyUp;

		ImGuiIO& io = ImGui::GetIO();
		int Scancode = eventData[P_SCANCODE].GetInt();

		if (Scancode < 512)
			io.KeysDown[Scancode] = false;
	}

	//
	// HandleKeyDown
	//
	void imgui::HandleKeyDown(StringHash eventType, VariantMap & eventData)
	{
		using namespace KeyDown;
		ImGuiIO& io = ImGui::GetIO();
		int Scancode = eventData[P_SCANCODE].GetInt();

		if (Scancode < 512)
			io.KeysDown[Scancode] = true;
	}

	//
	// HandleTextInput
	//
	void imgui::HandleTextInput(StringHash eventType, VariantMap & eventData)
	{
		using namespace TextInput;
		const String& text = eventData[P_TEXT].GetString();
		ImGuiIO& io = ImGui::GetIO();
		io.AddInputCharactersUTF8(text.CString());
	}

	//
	// HandleTouchBegin
	//
	void imgui::HandleTouchBegin(StringHash eventType, VariantMap & eventData)
	{
		using namespace TouchBegin;

		if (!touching)
		{
			touching = true;
			single_touchID = eventData[P_TOUCHID].GetInt();

			auto& io = ImGui::GetIO();
			io.MousePos.x = (float)eventData[P_X].GetInt();
			io.MousePos.y = (float)eventData[P_Y].GetInt();
			io.MouseDown[0] = true;
		}
	}

	//
	// HandleTouchEnd
	//
	void imgui::HandleTouchEnd(StringHash eventType, VariantMap & eventData)
	{
		using namespace TouchEnd;

		int touchID = eventData[P_TOUCHID].GetInt();

		if (touchID == single_touchID)
		{
			auto& io = ImGui::GetIO();
			io.MousePos.x = (float)eventData[P_X].GetInt();
			io.MousePos.y = (float)eventData[P_Y].GetInt();
			io.MouseDown[0] = false;
		}

		touching = false;
	}

	//
	// HandleTouchMove
	//
	void imgui::HandleTouchMove(StringHash eventType, VariantMap & eventData)
	{
		using namespace TouchMove;

		int touchID = eventData[P_TOUCHID].GetInt();

		if (touchID == single_touchID)
		{
			auto& io = ImGui::GetIO();
			io.MousePos.x = (float)eventData[P_X].GetInt();
			io.MousePos.y = (float)eventData[P_Y].GetInt();
		}
	}
}<|endoftext|>


<commit_before>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/* --------------------------------------------------------
   Needed for trapping floating point errors.
 ---------------------------------------------------------- */
#ifdef TRAPFPE_OSX
#include "fp_exception_glibc_extension.h"
#endif
/* Are these all that is needed for non-OSX systems? */
#include <fenv.h>
#include <signal.h>
#include <unistd.h>    //  To get process ids
/* -------------------------------------------------------- */

// This needs to go away.  The p4est namespace should not be used directly.
#include <p4est.h>

#include "amr_forestclaw.H"
#include "amr_utils.H"
#include "amr_waveprop.H"
#include "amr_options.h"

#include "swirl_user.H"

int
main (int argc, char **argv)
{
  int		        lp;
  MPI_Comm              mpicomm;
  sc_options_t          *options;
  fclaw2d_domain_t	*domain;
  amr_options_t         *gparms;
  amr_waveprop_parms_t  *waveprop_parms;

#ifdef TRAPFPE
  printf("Enabling floating point traps\n");
  feenableexcept(FE_INVALID);
#endif

  lp = SC_LP_PRODUCTION;
  mpicomm = MPI_COMM_WORLD;
  fclaw_mpi_init (&argc, &argv, mpicomm, lp);

#ifdef MPI_DEBUG
  /* Find out process rank */
  int my_rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

  /* Find out number of processes */
  int num;
  MPI_Comm_size(MPI_COMM_WORLD, &num);

  // Don't do anything until we are done with this part
  MPI_Barrier(MPI_COMM_WORLD);
  if (my_rank == 0)
  {
      printf("\n");
      printf("Getting setup for parallel debugging\n");
      printf("------------------------------------\n");
      MPI_Barrier(MPI_COMM_WORLD);
  }
  for(int i = 0; i < num; i++)
  {
      if (my_rank == i)
      {
          printf("Proc %d with process %d is waiting to be attached\n",my_rank,getpid());
          fflush(stdout);
      }
  }
  MPI_Barrier(MPI_COMM_WORLD);

  int ii = 0;
  while (ii == 0)
  {
      /* set break point here */
  }
#endif

  /* ---------------------------------------------------------------
     Read parameters from .ini file, parse command line, and
     do parameter checking.
     -------------------------------------------------------------- */
  options = sc_options_new(argv[0]);

  /* Register default parameters and any solver parameters */
  gparms = amr_options_new(options);
  waveprop_parms = amr_waveprop_parms_new(options);

  /* Parse any command line arguments.  Argument gparms is no longer needed
     as an input since the array conversion is now done in 'postprocess' */

  amr_options_parse(options,argc,argv,lp);

  /* Any arrays are converted here */
  amr_postprocess_parms(gparms);
  amr_waveprop_postprocess_parms(waveprop_parms);

  /* Check final state of parameters */
  amr_checkparms(gparms);
  amr_waveprop_checkparms(waveprop_parms,gparms);

  /* ---------------------------------------------------------------
     Domain geometry
     -------------------------------------------------------------- */
  domain = fclaw2d_domain_new_unitsquare (mpicomm, gparms->minlevel);

  if (gparms->verbosity > 0)
  {
      fclaw2d_domain_list_levels(domain, lp);
      fclaw2d_domain_list_neighbors(domain, lp);
  }

  /* ---------------------------------------------------------------
     Set domain data.
     --------------------------------------------------------------- */
  init_domain_data(domain);

  set_domain_parms(domain,gparms);
  set_waveprop_parms(domain,waveprop_parms);

  /* ---------------------------------------------------------------
     Define the solver and link in other problem/user specific
     routines
     --------------------------------------------------------------- */

  /* Using user defined functions just to demonstrate how one might setup
     something that depends on more than one solver (although only one is used
     here) */
  link_problem_setup(domain,swirl_problem_setup);

  swirl_link_solvers(domain);

  link_regrid_functions(domain,swirl_patch_tag4refinement,swirl_patch_tag4coarsening);

  /* ---------------------------------------------------------------
     Run
     --------------------------------------------------------------- */

  amrinit(&domain);
  amrrun(&domain);
  amrreset(&domain);

  sc_options_destroy(options);         /* this could be moved up */
  amr_options_destroy(gparms);
  amr_waveprop_parms_delete(waveprop_parms);

  fclaw_mpi_finalize ();

  return 0;
}
<commit_msg>Getting processes to print in order?<commit_after>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/* --------------------------------------------------------
   Needed for trapping floating point errors.
 ---------------------------------------------------------- */
#ifdef TRAPFPE_OSX
#include "fp_exception_glibc_extension.h"
#endif
/* Are these all that is needed for non-OSX systems? */
#include <fenv.h>
#include <signal.h>
#include <unistd.h>    //  To get process ids
/* -------------------------------------------------------- */

// This needs to go away.  The p4est namespace should not be used directly.
#include <p4est.h>

#include "amr_forestclaw.H"
#include "amr_utils.H"
#include "amr_waveprop.H"
#include "amr_options.h"

#include "swirl_user.H"

int
main (int argc, char **argv)
{
  int		        lp;
  MPI_Comm              mpicomm;
  sc_options_t          *options;
  fclaw2d_domain_t	*domain;
  amr_options_t         *gparms;
  amr_waveprop_parms_t  *waveprop_parms;

#ifdef TRAPFPE
  printf("Enabling floating point traps\n");
  feenableexcept(FE_INVALID);
#endif

  lp = SC_LP_PRODUCTION;
  mpicomm = MPI_COMM_WORLD;
  fclaw_mpi_init (&argc, &argv, mpicomm, lp);

#ifdef MPI_DEBUG
  /* Find out process rank */
  int my_rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

  /* Find out number of processes */
  int num;
  MPI_Comm_size(MPI_COMM_WORLD, &num);

  // Don't do anything until we are done with this part
  MPI_Barrier(MPI_COMM_WORLD);
  if (my_rank == 0)
  {
      printf("\n");
      printf("Getting setup for parallel debugging\n");
      printf("------------------------------------\n");
  }
  MPI_Barrier(MPI_COMM_WORLD);
  for(int i = 0; i < num; i++)
  {
      if (my_rank == i)
      {
          printf("Proc %d with process %d is waiting to be attached\n",my_rank,getpid());
          fflush(stdout);
      }
      MPI_Barrier(MPI_COMM_WORLD);
  }

  int ii = 0;
  while (ii == 0)
  {
      /* set break point here */
  }
#endif

  /* ---------------------------------------------------------------
     Read parameters from .ini file, parse command line, and
     do parameter checking.
     -------------------------------------------------------------- */
  options = sc_options_new(argv[0]);

  /* Register default parameters and any solver parameters */
  gparms = amr_options_new(options);
  waveprop_parms = amr_waveprop_parms_new(options);

  /* Parse any command line arguments.  Argument gparms is no longer needed
     as an input since the array conversion is now done in 'postprocess' */

  amr_options_parse(options,argc,argv,lp);

  /* Any arrays are converted here */
  amr_postprocess_parms(gparms);
  amr_waveprop_postprocess_parms(waveprop_parms);

  /* Check final state of parameters */
  amr_checkparms(gparms);
  amr_waveprop_checkparms(waveprop_parms,gparms);

  /* ---------------------------------------------------------------
     Domain geometry
     -------------------------------------------------------------- */
  domain = fclaw2d_domain_new_unitsquare (mpicomm, gparms->minlevel);

  if (gparms->verbosity > 0)
  {
      fclaw2d_domain_list_levels(domain, lp);
      fclaw2d_domain_list_neighbors(domain, lp);
  }

  /* ---------------------------------------------------------------
     Set domain data.
     --------------------------------------------------------------- */
  init_domain_data(domain);

  set_domain_parms(domain,gparms);
  set_waveprop_parms(domain,waveprop_parms);

  /* ---------------------------------------------------------------
     Define the solver and link in other problem/user specific
     routines
     --------------------------------------------------------------- */

  /* Using user defined functions just to demonstrate how one might setup
     something that depends on more than one solver (although only one is used
     here) */
  link_problem_setup(domain,swirl_problem_setup);

  swirl_link_solvers(domain);

  link_regrid_functions(domain,swirl_patch_tag4refinement,swirl_patch_tag4coarsening);

  /* ---------------------------------------------------------------
     Run
     --------------------------------------------------------------- */

  amrinit(&domain);
  amrrun(&domain);
  amrreset(&domain);

  sc_options_destroy(options);         /* this could be moved up */
  amr_options_destroy(gparms);
  amr_waveprop_parms_delete(waveprop_parms);

  fclaw_mpi_finalize ();

  return 0;
}
<|endoftext|>


<commit_before>#include "RenderModel.h"

RenderModel::RenderModel(const char* modelFile,
                         const char* vertexShaderFile,
                         const char* pixelShaderFile,
                         const char* geometryShaderFile)
{
	// TODO: Handle case with no normals
	// TODO: Handle case with no indices
	// TODO: Handle case with no texCoords

	Assimp::Importer importer;

	// TODO: Direct to appropriate directory, or use an interface to storage
	const aiScene* scene = importer.ReadFile(std::string(modelFile),
	                                         aiProcessPreset_TargetRealtime_Fast)

	// Reserve buffer IDs for each of the meshes
	glGenBuffers(scene.mNumMeshes, m_vertexBuffers);
	glGenBuffers(scene.mNumMeshes, m_indexBuffers);
	glGenBuffers(scene.mNumMeshes, m_normalBuffers);
	glGenBuffers(scene.mNumMeshes, m_textureCoordBuffers);

	// Prepare buffers
	aiMesh* currMesh;
	aiFace currFace;
	for(int meshNum=0; meshNum<scene->mNumMeshes; ++meshNum) {
		currMesh = scene->mMeshes[meshNum]

		// Prepare arrays of vertices, normals, and texture coordinates to send
		// to the GPU. There is a normal and texture coordinate for every vertex.
		std::vector<float> vertices;
		std::vector<float> normals;
		std::vector<float> texCoords;
		for(int vertNum=0; vertNum<currMesh->mNumVertices; ++vertNum) {
			vertices.push_back(currMesh->mVertices[vertNum].x);
			vertices.push_back(currMesh->mVertices[vertNum].y);
			vertices.push_back(currMesh->mVertices[vertNum].z);
			normals.push_back(currMesh->mNormals[vertNum].x);
			normals.push_back(currMesh->mNormals[vertNum].y);
			normals.push_back(currMesh->mNormals[vertNum].z);
			texCoords.push_back(currMesh->mTextureCoords.x);
			texCoords.push_back(currMesh->mTextureCoords.y);
			texCoords.push_back(currMesh->mTextureCoords.z);
			// Note: Assimp supports texture cubes. It is most likely the third
			//       component (mTextureCoords.z) will be null, though.
		}

		// Prepare array of indices to send to GPU
		// Indices are stored in faces. There should be 3 indices per
		// face, thanks to the aiProcess_Triangulate flag used in the
		// post-processing preset we gave the Assimp importer.
		std::vector<unsigned int> indices;
		for(int faceNum=0; faceNum<currMesh->mNumFaces; ++faceNum) {
			currFace = currMesh->mFaces[faceNum];
			for(int indexNum=0; indexNum<currFace.mNumIndices; ++indexNum) {
				indices.push_back(currFace.mIndices[indexNum]);
			}
		}

		// Fill buffers on the GPU using the prepared arrays
		// - Vertex buffer
		glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffers[i]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_STATIC_DRAW);
		// - Index buffer
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[i]);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices.data(), GL_STATIC_DRAW);
		// - Normal buffer
		glBindBuffer(GL_ARRAY_BUFFER, m_normalBuffers[i]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(normals), normals.data(), GL_STATIC_DRAW);
		// - Texture coordinate (UV) buffer
		glBindBuffer(GL_ARRAY_BUFFER, m_textureCoordBuffers[i]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords.data(), GL_STATIC_DRAW);
	}

	// TODO: Everything related to textures, animations, and lights

	// Compile shader program
	// TODO: Direct to appropriate directory, or use an interface to storage
	// -- Compile vertex shader
	std::ifstream vsFile(vertexShaderFile);
	std::stringstream vertexShaderSource;
	vertexShaderSource << vsFile.rdbuf();
	unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1, &vertexShaderSource.str().c_str(), NULL);
	// -- Compile pixel shader
	std::ifstream psFile(pixelShaderFile);
	std::stringstream pixelShaderSource;
	vertexShaderSource << psFile.rdbuf();
	unsigned int pixelShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(pixelShader, 1, &pixelShaderSource.str().c_str(), NULL);
	// -- Compile geometry shader
	if(geometryShaderFile != NULL) {
		std::ifstream gsFile(geometryShaderFile);
		std::stringstream geometryShaderSource;
		geometryShaderSource << gsFile.rdbuf();
		unsigned int geometryShader = glCreateShader(GL_GEOMETRY_SHADER);
		glShaderSource(geometryShader, 1, &geometryShaderSource.str().c_str(), NULL);
	}
	// -- Link shaders
	m_shaderProgram = glCreateProgram();
	glAttachShader(m_shaderProgram, vertexShader);
	glAttachShader(m_shaderProgram, pixelShader);
	if(geometryShaderFile != NULL) {
		glAttachShader(m_shaderProgram, geometryShader);
	}
	glLinkProgram(m_shaderProgram);

	// TODO: Review whether more than one shader per RenderModel may be needed
}

RenderModel::~RenderModel() {
	// These values should all be equal, but it saves us some work to calculate
	// them separately if we ever change the way RenderModels are initialized.
	unsigned int vertexCount = sizeof(m_vertexBuffers)/sizeof(m_vertexBuffers[0]);
	unsigned int indexCount = sizeof(m_indexBuffers)/sizeof(m_indexBuffers[0]);
	unsigned int normalCount = sizeof(m_normalBuffers)/sizeof(m_normalBuffers[0]);
	unsigned int texCoordCount = sizeof(m_textureCoordBuffers)/sizeof(m_textureCoordBuffers[0]);

	// Release GPU resources
	glDeleteBuffers(vertexCount, &m_vertexBuffers);
	glDeleteBuffers(indexCount, &m_indexBuffers);
	glDeleteBuffers(normalCount, &m_normalBuffers);
	glDeleteBuffers(texCoordCount, &m_textureCoordBuffers);

	glDeleteProgram(m_shaderPrograms);
}

RenderModel::draw() {
	// Draw all meshes
	// NOTE: Consider the use of a vertex array object
	// TODO: Add transformations (as OpenGL uniforms)
	glUseProgram(m_shaderProgram);

	for(int i=0; i<sizeof(m_vertexBuffers)/sizeof(m_vertexBuffers[0]); ++i) {
		unsigned int positionAttribute = glGetAttribLocation(m_shaderProgram, "position");
		glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffers[i]);
		glVertexAttribPointer(positionAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(positionAttribute);

		unsigned int normalAttribute = glGetAttribLocation(m_shaderProgram, "normal");
		glBindBuffer(GL_ARRAY_BUFFER, m_normalBuffers[i]);
		glVertexAttribPointer(normalAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(normalAttribute);

		unsigned int texCoordAttribute = glGetAttribLocation(m_shaderProgram, "texCoord");
		glBindBuffer(GL_ARRAY_BUFFER, m_textureCoordBuffers[i]);
		glVertexAttribPointer(texCoordAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0); // 3D Coordinates
		glEnableVertexAttribArray(texCoordAttribute);

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[i]);

		glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
	}

	glDisableVertexAttribArray(0);
}
<commit_msg>Minor outstanding change to comments<commit_after>#include "RenderModel.h"

RenderModel::RenderModel(const char* modelFile,
                         const char* vertexShaderFile,
                         const char* pixelShaderFile,
                         const char* geometryShaderFile)
{
	// TODO: Handle case with no texCoords

	Assimp::Importer importer;

	// TODO: Direct to appropriate directory, or use an interface to storage
	const aiScene* scene = importer.ReadFile(std::string(modelFile),
	                                         aiProcessPreset_TargetRealtime_Fast)

	// Reserve buffer IDs for each of the meshes
	glGenBuffers(scene.mNumMeshes, m_vertexBuffers);
	glGenBuffers(scene.mNumMeshes, m_indexBuffers);
	glGenBuffers(scene.mNumMeshes, m_normalBuffers);
	glGenBuffers(scene.mNumMeshes, m_textureCoordBuffers);

	// Prepare buffers
	aiMesh* currMesh;
	aiFace currFace;
	for(int meshNum=0; meshNum<scene->mNumMeshes; ++meshNum) {
		currMesh = scene->mMeshes[meshNum]

		// Prepare arrays of vertices, normals, and texture coordinates to send
		// to the GPU. There is a normal and texture coordinate for every vertex.
		std::vector<float> vertices;
		std::vector<float> normals;
		std::vector<float> texCoords;
		for(int vertNum=0; vertNum<currMesh->mNumVertices; ++vertNum) {
			vertices.push_back(currMesh->mVertices[vertNum].x);
			vertices.push_back(currMesh->mVertices[vertNum].y);
			vertices.push_back(currMesh->mVertices[vertNum].z);
			normals.push_back(currMesh->mNormals[vertNum].x);
			normals.push_back(currMesh->mNormals[vertNum].y);
			normals.push_back(currMesh->mNormals[vertNum].z);
			texCoords.push_back(currMesh->mTextureCoords.x);
			texCoords.push_back(currMesh->mTextureCoords.y);
			texCoords.push_back(currMesh->mTextureCoords.z);
			// Note: Assimp supports texture cubes. It is most likely the third
			//       component (mTextureCoords.z) will be null, though.
		}

		// Prepare array of indices to send to GPU
		// Indices are stored in faces. There should be 3 indices per
		// face, thanks to the aiProcess_Triangulate flag used in the
		// post-processing preset we gave the Assimp importer.
		std::vector<unsigned int> indices;
		for(int faceNum=0; faceNum<currMesh->mNumFaces; ++faceNum) {
			currFace = currMesh->mFaces[faceNum];
			for(int indexNum=0; indexNum<currFace.mNumIndices; ++indexNum) {
				indices.push_back(currFace.mIndices[indexNum]);
			}
		}

		// Fill buffers on the GPU using the prepared arrays
		// - Vertex buffer
		glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffers[i]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices.data(), GL_STATIC_DRAW);
		// - Index buffer
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[i]);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices.data(), GL_STATIC_DRAW);
		// - Normal buffer
		glBindBuffer(GL_ARRAY_BUFFER, m_normalBuffers[i]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(normals), normals.data(), GL_STATIC_DRAW);
		// - Texture coordinate (UV) buffer
		glBindBuffer(GL_ARRAY_BUFFER, m_textureCoordBuffers[i]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords.data(), GL_STATIC_DRAW);
	}

	// TODO: Everything related to textures, animations, and lights

	// Compile shader program
	// TODO: Direct to appropriate directory, or use an interface to storage
	// -- Compile vertex shader
	std::ifstream vsFile(vertexShaderFile);
	std::stringstream vertexShaderSource;
	vertexShaderSource << vsFile.rdbuf();
	unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1, &vertexShaderSource.str().c_str(), NULL);
	// -- Compile pixel shader
	std::ifstream psFile(pixelShaderFile);
	std::stringstream pixelShaderSource;
	vertexShaderSource << psFile.rdbuf();
	unsigned int pixelShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(pixelShader, 1, &pixelShaderSource.str().c_str(), NULL);
	// -- Compile geometry shader
	if(geometryShaderFile != NULL) {
		std::ifstream gsFile(geometryShaderFile);
		std::stringstream geometryShaderSource;
		geometryShaderSource << gsFile.rdbuf();
		unsigned int geometryShader = glCreateShader(GL_GEOMETRY_SHADER);
		glShaderSource(geometryShader, 1, &geometryShaderSource.str().c_str(), NULL);
	}
	// -- Link shaders
	m_shaderProgram = glCreateProgram();
	glAttachShader(m_shaderProgram, vertexShader);
	glAttachShader(m_shaderProgram, pixelShader);
	if(geometryShaderFile != NULL) {
		glAttachShader(m_shaderProgram, geometryShader);
	}
	glLinkProgram(m_shaderProgram);

	// TODO: Review whether more than one shader per RenderModel may be needed
}

RenderModel::~RenderModel() {
	// These values should all be equal, but it saves us some work to calculate
	// them separately if we ever change the way RenderModels are initialized.
	unsigned int vertexCount = sizeof(m_vertexBuffers)/sizeof(m_vertexBuffers[0]);
	unsigned int indexCount = sizeof(m_indexBuffers)/sizeof(m_indexBuffers[0]);
	unsigned int normalCount = sizeof(m_normalBuffers)/sizeof(m_normalBuffers[0]);
	unsigned int texCoordCount = sizeof(m_textureCoordBuffers)/sizeof(m_textureCoordBuffers[0]);

	// Release GPU resources
	glDeleteBuffers(vertexCount, &m_vertexBuffers);
	glDeleteBuffers(indexCount, &m_indexBuffers);
	glDeleteBuffers(normalCount, &m_normalBuffers);
	glDeleteBuffers(texCoordCount, &m_textureCoordBuffers);

	glDeleteProgram(m_shaderPrograms);
}

RenderModel::draw() {
	// Draw all meshes
	// NOTE: Consider the use of a vertex array object
	// TODO: Add transformations (as OpenGL uniforms)
	glUseProgram(m_shaderProgram);

	for(int i=0; i<sizeof(m_vertexBuffers)/sizeof(m_vertexBuffers[0]); ++i) {
		unsigned int positionAttribute = glGetAttribLocation(m_shaderProgram, "position");
		glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffers[i]);
		glVertexAttribPointer(positionAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(positionAttribute);

		unsigned int normalAttribute = glGetAttribLocation(m_shaderProgram, "normal");
		glBindBuffer(GL_ARRAY_BUFFER, m_normalBuffers[i]);
		glVertexAttribPointer(normalAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0);
		glEnableVertexAttribArray(normalAttribute);

		unsigned int texCoordAttribute = glGetAttribLocation(m_shaderProgram, "texCoord");
		glBindBuffer(GL_ARRAY_BUFFER, m_textureCoordBuffers[i]);
		glVertexAttribPointer(texCoordAttribute, 3, GL_FLOAT, GL_FALSE, 0, 0); // 3D Coordinates
		glEnableVertexAttribArray(texCoordAttribute);

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[i]);

		glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
	}

	glDisableVertexAttribArray(0);
}
<|endoftext|>


<commit_before><commit_msg>Use std versions of C functions.<commit_after><|endoftext|>


<commit_before>/*
 * SMD2Structs.cpp
 *
 *  Created on: 09.02.2016
 *      Author: Megacrafter127
 */

#include "SMD2Structs.h"
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <zlib.h>
#include <stdexcept>

namespace smd2{
	block::block(const struct block *copy) {
		memcpy(this,copy,sizeof(struct block));
	};
	block::block(const unsigned int id, const unsigned int hp, const bool active, const unsigned int orientation) {
		this->id=id;
		this->hp=hp;
		this->active=active;
		this->orientation=orientation;
	};
	block::block(const rawBlock *raw, const blocktypeList *list) {
		if(!list) std::__throw_invalid_argument("the provided list may not be NULL");
		uint32_t buff=0;
		memcpy(&buff+sizeof(uint32_t)-sizeof(rawBlock),raw,sizeof(rawBlock));
		if(buff) {
			buff=ntohl(buff);
			this->id=buff;
			buff>>=11;
			blockType type=((blockType*)list)[this->id];
			if(type==undefined) {
				std::__throw_invalid_argument("blocktype not defined");
			}
			this->hp=buff;
			if(type==fullyRotating) {
				this->hp&=0x00FF;
				buff>>=8;
			} else buff>>=9;
			if(type==logic) {
				this->active=buff & 1;
				buff>>=1;
			}
			this->orientation=buff;
		} else {
			this->id=0;
			this->hp=0;
			this->active=false;
			this->orientation=0;
		}
	};
	block::block() {
		this->id=0;
		this->hp=0;
		this->active=false;
		this->orientation=0;
	};
	rawBlock *block::toRaw(rawBlock *target, const blocktypeList *list) {
		if(!list) std::__throw_invalid_argument("the provided list may not be NULL");
		blockType type=((blockType*)list)[this->id];
		if(type==undefined) {
			std::__throw_invalid_argument("blocktype not defined");
		}
		uint32_t buff=this->orientation;
		if(type==logic) {
			buff<<=1;
			if(this->active) buff++;
		}
		if(type==fullyRotating) {
			buff<<=8;
			buff+=(0xFF & this->hp);
		} else {
			buff<<=9;
			buff+=this->hp;
		}
		buff<<=11;
		buff+=id;
		buff=htonl(buff);
		memcpy(target,&buff+sizeof(uint32_t)-sizeof(rawBlock),sizeof(rawBlock));
		return target;
	};

	rawChunkData *inflate(rawChunkData *trg,const compressedChunkData *src) {}; //TODO #31
	compressedChunkData *deflate(compressedChunkData *trg,const rawChunkData *src) {}; //TODO #32
	bool isEmpty(const rawCompressedSegment *segment) {
		size_t *chars=(size_t*)segment;
		for(size_t i=0;i<(sizeof(rawCompressedSegment)/sizeof(size_t));i++) {
			if(chars[i]) return false;
		}
		return true;
	};

	segmentHead::segmentHead(const struct segmentHead *copy) {
		memcpy(this,copy,sizeof(struct segmentHead));
	};
	segmentHead::segmentHead(const unsigned char unknownChar, const unsigned long long timestamp, const signed long x, const signed long y, const signed long z, const unsigned char type, const unsigned long inlen) {
		this->unknownChar=unknownChar;
		this->timestamp=timestamp;
		this->x=x;
		this->y=y;
		this->z=z;
		this->type=type;
		this->inlen=inlen;
	};
	segmentHead::segmentHead(const rawCompressedSegment *raw,const bool offset) {
		size_t i=0;
		char *chars=(char*)raw;
		if(offset) {
			this->unknownChar=chars[i];
			i++;
		}
		uint64_t dbuff64;
		uint32_t *buff32=(uint32_t*)&dbuff64,dbuff32=ntohl(buff32[0]);
		memcpy(buff32,&(chars[i]),sizeof(uint64_t));
		if(ntohl(1)!=1) {
			buff32[0]=ntohl(buff32[1]);
			buff32[1]=dbuff32;
		}
		this->timestamp=dbuff64;
		i+=sizeof(uint64_t);

		memcpy(&dbuff32,&(chars[i]),sizeof(int32_t));
		this->x=ntohl(dbuff32);
		i+=sizeof(int32_t);

		memcpy(&dbuff32,&(chars[i]),sizeof(int32_t));
		this->y=ntohl(dbuff32);
		i+=sizeof(int32_t);

		memcpy(&dbuff32,&(chars[i]),sizeof(int32_t));
		this->z=ntohl(dbuff32);
		i+=sizeof(int32_t);

		this->type=chars[i];
		i++;

		memcpy(&dbuff32,&(chars[i]),sizeof(uint32_t));
		this->inlen=ntohl(dbuff32);
	};
	segmentHead::segmentHead() {
		this->unknownChar=0;
		this->timestamp=0;
		this->x=0;
		this->y=0;
		this->z=0;
		this->type=0;
		this->inlen=0;
	};
	rawCompressedSegment *segmentHead::toRaw(rawCompressedSegment *target,const bool offset) {
		size_t i=0;
		char *chars=(char*)target;
		if(offset) {
			chars[i]=this->unknownChar;
			i++;
		}
		uint64_t dbuff64=this->timestamp;
		uint32_t *buff32=(uint32_t*)&dbuff64,dbuff32=htonl(buff32[0]);
		if(htonl(1)!=1) {
			buff32[0]=htonl(buff32[1]);
			buff32[1]=dbuff32;
		}
		memcpy(&(chars[i]),buff32,sizeof(uint64_t));
		i+=sizeof(uint64_t);

		dbuff32=htonl(this->x);
		memcpy(&(chars[i]),&dbuff32,sizeof(int32_t));
		i+=sizeof(int32_t);

		dbuff32=htonl(this->y);
		memcpy(&(chars[i]),&dbuff32,sizeof(int32_t));
		i+=sizeof(int32_t);

		dbuff32=htonl(this->z);
		memcpy(&(chars[i]),&dbuff32,sizeof(int32_t));
		i+=sizeof(int32_t);

		this->type=chars[i];
		i++;

		dbuff32=htonl(this->inlen);
		memcpy(&(chars[i]),&dbuff32,sizeof(uint32_t));
		return target;
	};

	segment::segment(const struct segment *copy) {
		memcpy(this,copy,sizeof(struct segment));
	};
	segment::segment(const struct segmentHead *head,const chunkData *blocks) {
		this->head=*head;
		memcpy(&(this->blocks),blocks,sizeof(chunkData));
	};
	segment::segment(const struct segmentHead *head,const rawChunkData *blocks) {}; //TODO #9
	segment::segment(const struct segmentHead *head,const compressedChunkData *blocks) {}; //TODO #10
	segment::segment(const struct rawSegment *src) {}; //TODO #9
	segment::segment(const struct compressedSegment *src) {}; //TODO #10
	segment::segment(const rawCompressedSegment *src) {}; //TODO #11
	rawCompressedSegment *segment::toRawCompressed(rawCompressedSegment *trg,const bool offset) {}; //TODO #12

	rawSegment::rawSegment(const struct rawSegment *copy) {
		memcpy(this,copy,sizeof(struct rawSegment));
	};
	rawSegment::rawSegment(const struct segmentHead *head,const rawChunkData *blocks) {
		this->head=*head;
		memcpy(&(this->blocks),blocks,sizeof(rawChunkData));
	};
	rawSegment::rawSegment(const struct segmentHead *head,const chunkData*) {}; //TODO #15
	rawSegment::rawSegment(const struct segmentHead *head,const compressedChunkData*) {}; //TODO #16
	rawSegment::rawSegment(const struct segment *src) {}; //TODO #15
	rawSegment::rawSegment(const struct compressedSegment *src) {}; //TODO #16
	rawSegment::rawSegment(const rawCompressedSegment *src) {}; //TODO #17
	rawCompressedSegment *rawSegment::toRawCompressed(rawCompressedSegment *trg,const bool offset) {}; //TODO #18

	compressedSegment::compressedSegment(const struct compressedSegment *copy) {
		memcpy(this,copy,sizeof(struct compressedSegment));
	};
	compressedSegment::compressedSegment(const struct segmentHead *head,const compressedChunkData *blocks) {
		this->head=*head;
		memcpy(&(this->blocks),blocks,sizeof(compressedChunkData));
	};
	compressedSegment::compressedSegment(const struct segmentHead *head,const chunkData *blocks) {}; //TODO #21
	compressedSegment::compressedSegment(const struct segmentHead *head,const rawChunkData *blocks) {}; //TODO #22
	compressedSegment::compressedSegment(const struct segment *src) {}; //TODO #21
	compressedSegment::compressedSegment(const struct rawSegment *src) {}; //TODO #22
	compressedSegment::compressedSegment(const rawCompressedSegment *src) {}; //TODO #23
	rawCompressedSegment *compressedSegment::toRawCompressed(rawCompressedSegment *trg,const bool offset) {}; //TODO #24

	smd2Index::smd2Index(const struct smd2Index *copy) {
		this->id=copy->id;
		this->inlen=copy->inlen;
	};
	smd2Index::smd2Index(const signed long id, const unsigned long len) {
		this->id=id;
		this->inlen=len;
	};
	smd2Index::smd2Index() {
		this->id=-1;
		this->inlen=0;
	};
	smd2Index::smd2Index(const rawSmd2Index *raw) {
		uint32_t split[2];
		memcpy(split,raw,sizeof(rawSmd2Index));
		this->id=ntohl(split[0]);
		this->inlen=ntohl(split[1]);
	};
	rawSmd2Index *smd2Index::toRaw(rawSmd2Index *trg) {
		uint32_t split[2];
		split[0]=htonl(this->id);
		split[1]=htonl(this->inlen);
		memcpy(trg,split,sizeof(rawSmd2Index));
		return trg;
	};
	bool smd2Index::isValid() {
		return this->id!=-1;
	};

	smd2Head::smd2Head(const struct smd2Head *copy) {
		memcpy(this,copy,sizeof(struct smd2Head));
	};
	smd2Head::smd2Head(const unsigned long version, const fullSmd2Index *index,const fullSmd2TimestampHead *timestamps) {
		this->version=version;
		memcpy(&(this->index),index,sizeof(fullSmd2Index));
		memcpy(&(this->timestamps),timestamps,sizeof(fullSmd2TimestampHead));
	};
	smd2Head::smd2Head(const rawSmd2Head*) {}; //TODO #26
	rawSmd2Head *smd2Head::toRaw(rawSmd2Head*) {}; //TODO #27

	unsigned int getSegmentSlotCountFromSMD2Size(const size_t size) {
		return (size-sizeof(rawSmd2Head))/sizeof(rawCompressedSegment);
	};
	size_t getSMD2SizeFromSegmentSlotCount(const unsigned int slots) {
		return sizeof(rawSmd2Head)+(slots*sizeof(rawCompressedSegment));
	};
}

<commit_msg>replaced __throw_invalid_argument calls (couldn't compile on my machine)<commit_after>/*
 * SMD2Structs.cpp
 *
 *  Created on: 09.02.2016
 *      Author: Megacrafter127
 */

#include "SMD2Structs.h"
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <zlib.h>
#include <stdexcept>

namespace smd2{
	block::block(const struct block *copy) {
		memcpy(this,copy,sizeof(struct block));
	};
	block::block(const unsigned int id, const unsigned int hp, const bool active, const unsigned int orientation) {
		this->id=id;
		this->hp=hp;
		this->active=active;
		this->orientation=orientation;
	};
	block::block(const rawBlock *raw, const blocktypeList *list) {
		if(!list) throw std::invalid_argument("the provided list may not be NULL");
		uint32_t buff=0;
		memcpy(&buff+sizeof(uint32_t)-sizeof(rawBlock),raw,sizeof(rawBlock));
		if(buff) {
			buff=ntohl(buff);
			this->id=buff;
			buff>>=11;
			blockType type=((blockType*)list)[this->id];
			if(type==undefined) {
				throw std::invalid_argument("blocktype not defined");
			}
			this->hp=buff;
			if(type==fullyRotating) {
				this->hp&=0x00FF;
				buff>>=8;
			} else buff>>=9;
			if(type==logic) {
				this->active=buff & 1;
				buff>>=1;
			}
			this->orientation=buff;
		} else {
			this->id=0;
			this->hp=0;
			this->active=false;
			this->orientation=0;
		}
	};
	block::block() {
		this->id=0;
		this->hp=0;
		this->active=false;
		this->orientation=0;
	};
	rawBlock *block::toRaw(rawBlock *target, const blocktypeList *list) {
		if(!list) throw std::invalid_argument("the provided list may not be NULL");
		blockType type=((blockType*)list)[this->id];
		if(type==undefined) {
			throw std::invalid_argument("blocktype not defined");
		}
		uint32_t buff=this->orientation;
		if(type==logic) {
			buff<<=1;
			if(this->active) buff++;
		}
		if(type==fullyRotating) {
			buff<<=8;
			buff+=(0xFF & this->hp);
		} else {
			buff<<=9;
			buff+=this->hp;
		}
		buff<<=11;
		buff+=id;
		buff=htonl(buff);
		memcpy(target,&buff+sizeof(uint32_t)-sizeof(rawBlock),sizeof(rawBlock));
		return target;
	};

	rawChunkData *inflate(rawChunkData *trg,const compressedChunkData *src) {}; //TODO #31
	compressedChunkData *deflate(compressedChunkData *trg,const rawChunkData *src) {}; //TODO #32
	bool isEmpty(const rawCompressedSegment *segment) {
		size_t *chars=(size_t*)segment;
		for(size_t i=0;i<(sizeof(rawCompressedSegment)/sizeof(size_t));i++) {
			if(chars[i]) return false;
		}
		return true;
	};

	segmentHead::segmentHead(const struct segmentHead *copy) {
		memcpy(this,copy,sizeof(struct segmentHead));
	};
	segmentHead::segmentHead(const unsigned char unknownChar, const unsigned long long timestamp, const signed long x, const signed long y, const signed long z, const unsigned char type, const unsigned long inlen) {
		this->unknownChar=unknownChar;
		this->timestamp=timestamp;
		this->x=x;
		this->y=y;
		this->z=z;
		this->type=type;
		this->inlen=inlen;
	};
	segmentHead::segmentHead(const rawCompressedSegment *raw,const bool offset) {
		size_t i=0;
		char *chars=(char*)raw;
		if(offset) {
			this->unknownChar=chars[i];
			i++;
		}
		uint64_t dbuff64;
		uint32_t *buff32=(uint32_t*)&dbuff64,dbuff32=ntohl(buff32[0]);
		memcpy(buff32,&(chars[i]),sizeof(uint64_t));
		if(ntohl(1)!=1) {
			buff32[0]=ntohl(buff32[1]);
			buff32[1]=dbuff32;
		}
		this->timestamp=dbuff64;
		i+=sizeof(uint64_t);

		memcpy(&dbuff32,&(chars[i]),sizeof(int32_t));
		this->x=ntohl(dbuff32);
		i+=sizeof(int32_t);

		memcpy(&dbuff32,&(chars[i]),sizeof(int32_t));
		this->y=ntohl(dbuff32);
		i+=sizeof(int32_t);

		memcpy(&dbuff32,&(chars[i]),sizeof(int32_t));
		this->z=ntohl(dbuff32);
		i+=sizeof(int32_t);

		this->type=chars[i];
		i++;

		memcpy(&dbuff32,&(chars[i]),sizeof(uint32_t));
		this->inlen=ntohl(dbuff32);
	};
	segmentHead::segmentHead() {
		this->unknownChar=0;
		this->timestamp=0;
		this->x=0;
		this->y=0;
		this->z=0;
		this->type=0;
		this->inlen=0;
	};
	rawCompressedSegment *segmentHead::toRaw(rawCompressedSegment *target,const bool offset) {
		size_t i=0;
		char *chars=(char*)target;
		if(offset) {
			chars[i]=this->unknownChar;
			i++;
		}
		uint64_t dbuff64=this->timestamp;
		uint32_t *buff32=(uint32_t*)&dbuff64,dbuff32=htonl(buff32[0]);
		if(htonl(1)!=1) {
			buff32[0]=htonl(buff32[1]);
			buff32[1]=dbuff32;
		}
		memcpy(&(chars[i]),buff32,sizeof(uint64_t));
		i+=sizeof(uint64_t);

		dbuff32=htonl(this->x);
		memcpy(&(chars[i]),&dbuff32,sizeof(int32_t));
		i+=sizeof(int32_t);

		dbuff32=htonl(this->y);
		memcpy(&(chars[i]),&dbuff32,sizeof(int32_t));
		i+=sizeof(int32_t);

		dbuff32=htonl(this->z);
		memcpy(&(chars[i]),&dbuff32,sizeof(int32_t));
		i+=sizeof(int32_t);

		this->type=chars[i];
		i++;

		dbuff32=htonl(this->inlen);
		memcpy(&(chars[i]),&dbuff32,sizeof(uint32_t));
		return target;
	};

	segment::segment(const struct segment *copy) {
		memcpy(this,copy,sizeof(struct segment));
	};
	segment::segment(const struct segmentHead *head,const chunkData *blocks) {
		this->head=*head;
		memcpy(&(this->blocks),blocks,sizeof(chunkData));
	};
	segment::segment(const struct segmentHead *head,const rawChunkData *blocks) {}; //TODO #9
	segment::segment(const struct segmentHead *head,const compressedChunkData *blocks) {}; //TODO #10
	segment::segment(const struct rawSegment *src) {}; //TODO #9
	segment::segment(const struct compressedSegment *src) {}; //TODO #10
	segment::segment(const rawCompressedSegment *src) {}; //TODO #11
	rawCompressedSegment *segment::toRawCompressed(rawCompressedSegment *trg,const bool offset) {}; //TODO #12

	rawSegment::rawSegment(const struct rawSegment *copy) {
		memcpy(this,copy,sizeof(struct rawSegment));
	};
	rawSegment::rawSegment(const struct segmentHead *head,const rawChunkData *blocks) {
		this->head=*head;
		memcpy(&(this->blocks),blocks,sizeof(rawChunkData));
	};
	rawSegment::rawSegment(const struct segmentHead *head,const chunkData*) {}; //TODO #15
	rawSegment::rawSegment(const struct segmentHead *head,const compressedChunkData*) {}; //TODO #16
	rawSegment::rawSegment(const struct segment *src) {}; //TODO #15
	rawSegment::rawSegment(const struct compressedSegment *src) {}; //TODO #16
	rawSegment::rawSegment(const rawCompressedSegment *src) {}; //TODO #17
	rawCompressedSegment *rawSegment::toRawCompressed(rawCompressedSegment *trg,const bool offset) {}; //TODO #18

	compressedSegment::compressedSegment(const struct compressedSegment *copy) {
		memcpy(this,copy,sizeof(struct compressedSegment));
	};
	compressedSegment::compressedSegment(const struct segmentHead *head,const compressedChunkData *blocks) {
		this->head=*head;
		memcpy(&(this->blocks),blocks,sizeof(compressedChunkData));
	};
	compressedSegment::compressedSegment(const struct segmentHead *head,const chunkData *blocks) {}; //TODO #21
	compressedSegment::compressedSegment(const struct segmentHead *head,const rawChunkData *blocks) {}; //TODO #22
	compressedSegment::compressedSegment(const struct segment *src) {}; //TODO #21
	compressedSegment::compressedSegment(const struct rawSegment *src) {}; //TODO #22
	compressedSegment::compressedSegment(const rawCompressedSegment *src) {}; //TODO #23
	rawCompressedSegment *compressedSegment::toRawCompressed(rawCompressedSegment *trg,const bool offset) {}; //TODO #24

	smd2Index::smd2Index(const struct smd2Index *copy) {
		this->id=copy->id;
		this->inlen=copy->inlen;
	};
	smd2Index::smd2Index(const signed long id, const unsigned long len) {
		this->id=id;
		this->inlen=len;
	};
	smd2Index::smd2Index() {
		this->id=-1;
		this->inlen=0;
	};
	smd2Index::smd2Index(const rawSmd2Index *raw) {
		uint32_t split[2];
		memcpy(split,raw,sizeof(rawSmd2Index));
		this->id=ntohl(split[0]);
		this->inlen=ntohl(split[1]);
	};
	rawSmd2Index *smd2Index::toRaw(rawSmd2Index *trg) {
		uint32_t split[2];
		split[0]=htonl(this->id);
		split[1]=htonl(this->inlen);
		memcpy(trg,split,sizeof(rawSmd2Index));
		return trg;
	};
	bool smd2Index::isValid() {
		return this->id!=-1;
	};

	smd2Head::smd2Head(const struct smd2Head *copy) {
		memcpy(this,copy,sizeof(struct smd2Head));
	};
	smd2Head::smd2Head(const unsigned long version, const fullSmd2Index *index,const fullSmd2TimestampHead *timestamps) {
		this->version=version;
		memcpy(&(this->index),index,sizeof(fullSmd2Index));
		memcpy(&(this->timestamps),timestamps,sizeof(fullSmd2TimestampHead));
	};
	smd2Head::smd2Head(const rawSmd2Head*) {}; //TODO #26
	rawSmd2Head *smd2Head::toRaw(rawSmd2Head*) {}; //TODO #27

	unsigned int getSegmentSlotCountFromSMD2Size(const size_t size) {
		return (size-sizeof(rawSmd2Head))/sizeof(rawCompressedSegment);
	};
	size_t getSMD2SizeFromSegmentSlotCount(const unsigned int slots) {
		return sizeof(rawSmd2Head)+(slots*sizeof(rawCompressedSegment));
	};
}

<|endoftext|>


<commit_before><commit_msg>Fix the %assign/v0/x1 operators for width equal negative offset case.<commit_after><|endoftext|>


<commit_before>/*
Copyright (c) 2014-2015 Ableton AG, Berlin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "StylePlugin.hpp"

#include "StyleEngine.hpp"
#include "StylesDirWatcher.hpp"
#include "StyleSet.hpp"
#include "Warnings.hpp"

SUPPRESS_WARNINGS
#include <QtQml/QQmlComponent>
#include <QtQml/QQmlEngine>
RESTORE_WARNINGS

void aqt::stylesheets::StylePlugin::registerTypes(const char* pUri)
{
  qmlRegisterUncreatableType<aqt::stylesheets::StyleSet>(
    pUri, 1, 0, "StyleSet", "StyleSet is exposed as an attached property");
  qmlRegisterType<aqt::stylesheets::StyleEngine>(pUri, 1, 0, "StyleEngine");
  qmlRegisterType<aqt::stylesheets::StyleEngine, 1>(pUri, 1, 1, "StyleEngine");
  qmlRegisterType<aqt::stylesheets::StylesDirWatcher>(pUri, 1, 1, "StylesDirWatcher");
}

#if !defined(NOT_INCLUDE_MOC)
SUPPRESS_WARNINGS
#include "moc_StylePlugin.cpp"
RESTORE_WARNINGS
#endif
<commit_msg>Define Aqt.StyleSheets 1.2<commit_after>/*
Copyright (c) 2014-2015 Ableton AG, Berlin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "StylePlugin.hpp"

#include "StyleEngine.hpp"
#include "StylesDirWatcher.hpp"
#include "StyleSet.hpp"
#include "Warnings.hpp"

SUPPRESS_WARNINGS
#include <QtQml/QQmlComponent>
#include <QtQml/QQmlEngine>
RESTORE_WARNINGS

void aqt::stylesheets::StylePlugin::registerTypes(const char* pUri)
{
  qmlRegisterUncreatableType<aqt::stylesheets::StyleSet>(
    pUri, 1, 0, "StyleSet", "StyleSet is exposed as an attached property");
  qmlRegisterUncreatableType<aqt::stylesheets::StyleSet, 2>(
    pUri, 1, 2, "StyleSet", "StyleSet is exposed as an attached property");
  qmlRegisterType<aqt::stylesheets::StyleEngine>(pUri, 1, 0, "StyleEngine");
  qmlRegisterType<aqt::stylesheets::StyleEngine, 1>(pUri, 1, 1, "StyleEngine");
  qmlRegisterType<aqt::stylesheets::StylesDirWatcher>(pUri, 1, 1, "StylesDirWatcher");
}

#if !defined(NOT_INCLUDE_MOC)
SUPPRESS_WARNINGS
#include "moc_StylePlugin.cpp"
RESTORE_WARNINGS
#endif
<|endoftext|>


<commit_before>/*
	Copyright (C) 2015-2016 Claude SIMON (http://q37.info/contact/).

	This file is part of 'orgnzq' software.

    'orgnzq' is free software: you can redistribute it and/or modify it
    under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    'orgnzq' is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with 'orgnzq'.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "sclxdhtml.h"
#include "sclmisc.h"

#include "frdrgstry.h"

#include "core.h"

const char *sclmisc::SCLMISCTargetName = BASE_NAME;

void sclxdhtml::SCLXDHTMLInitialization( xdhcmn::mode__ Mode )
{
qRH
	sclfrntnd::features___ Features;
qRB
	core::Core.Init( Mode );

	if ( Mode == xdhcmn::mMultiUser ) {
		Features.Init();
		sclfrntnd::GuessBackendFeatures( Features );
		core::Kernel().Init( Features );
	}
qRR
qRT
qRE
}

xdhcmn::session_callback__ *sclxdhtml::SCLXDHTMLRetrieveCallback(
	const char *Language,
	xdhcmn::proxy_callback__ *ProxyCallback )
{
	core::rSession *Session = new core::rSession;

	if ( Session == NULL )
		qRGnr();

	Session->Init( core::Kernel(), Language, ProxyCallback );

	switch ( core::Core.Mode() ) {
	case xdhcmn::mMonoUser:
		::prolog::SetLayout( *Session );
		break;
	case xdhcmn::mMultiUser:
//		login::SetLayout( *Session );
		break;
	default:
		qRGnr();
		break;
	}

	return Session;
}

void sclxdhtml::SCLXDHTMLReleaseCallback( xdhcmn::session_callback__ *Callback )
{
	if ( Callback == NULL )
		qRGnr();

	delete Callback;
}

<commit_msg>29/03/2016 10:13:16<commit_after>/*
	Copyright (C) 2015-2016 Claude SIMON (http://q37.info/contact/).

	This file is part of 'orgnzq' software.

    'orgnzq' is free software: you can redistribute it and/or modify it
    under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    'orgnzq' is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with 'orgnzq'.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "sclxdhtml.h"
#include "sclmisc.h"

#include "frdrgstry.h"

#include "core.h"

const char *sclmisc::SCLMISCTargetName = BASE_NAME;

void sclxdhtml::SCLXDHTMLInitialization( xdhcmn::mode__ Mode )
{
qRH
	sclfrntnd::features___ Features;
qRB
	core::Core.Init( Mode );

	if ( Mode == xdhcmn::mMultiUser ) {
		Features.Init();
		sclfrntnd::GuessBackendFeatures( Features );
		core::Kernel().Init( Features, plgn::EmptyAbstracts );
	}
qRR
qRT
qRE
}

xdhcmn::session_callback__ *sclxdhtml::SCLXDHTMLRetrieveCallback(
	const char *Language,
	xdhcmn::proxy_callback__ *ProxyCallback )
{
	core::rSession *Session = new core::rSession;

	if ( Session == NULL )
		qRGnr();

	Session->Init( core::Kernel(), Language, ProxyCallback );

	switch ( core::Core.Mode() ) {
	case xdhcmn::mMonoUser:
		::prolog::SetLayout( *Session );
		break;
	case xdhcmn::mMultiUser:
//		login::SetLayout( *Session );
		break;
	default:
		qRGnr();
		break;
	}

	return Session;
}

void sclxdhtml::SCLXDHTMLReleaseCallback( xdhcmn::session_callback__ *Callback )
{
	if ( Callback == NULL )
		qRGnr();

	delete Callback;
}

<|endoftext|>