Hello all, in order to teach myself how to use AGK2 Tier 2, I wrote a simple 3D demo in C++ using MSVS Express 2013 and tested it on Windows 8.1. I thought it might prove useful for others to learn from. Enjoy!
I changed the header names to match my project, i.e. "planets", but otherwise I used the standard template "Core.cpp" & "resource.h"
planets.cpp
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Planets - AGKv2 Tier-2 Sample Application
// Author: MARDONIX Marty Quire (aka Uncle Martin) - Tampa, Florida, USA - www.mardonix.com
// Created: July 2015
// Description: Several small spheres revolving around a larger rotating central sphere
// Purpose: Sample to demostrate simple 3D graphics using AGK2 & C++
// Environment: Built & tested with MSVS Express 2013 on Windows 8.1 with nVidia graphics
// DISCLAIMER: Permission given to use at your discretion, no claims or implications of suitability
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Includes
#include "planets.h"
// Namespace
using namespace AGK;
app App;
// Define a color type structure
typedef struct ColorTypTag
{
int Red;
int Grn;
int Blu;
int Alp;
} ColorTyp;
// Define a platform type structure
typedef struct PlatformTypTag
{
float Size;
ColorTyp Color;
float OrbitRadius;
float OrbitAngSpd;
float OrbAngRad;
float xPos;
float yPos;
float zPos;
} PlatformTyp;
// Define variables
PlatformTyp Planet[15]; // Planet definitions
float CamHi; // Camera height (Y)
float CamDis; // Camera distance (Z)
// Define constants
const float PI2_RAD = 2.0f * 3.1415926f; // 2 Pi (Radians per circle)
const float DEG_RAD = 360.0f / PI2_RAD; // Degrees per Radian
const float CAMHI_RAT = 0.3f; // Camera height (Y) rate
const float CAMDS_RAT = 0.3f; // Camera distance (Z) rate
const int FIRST_PLNT = 3; // First planet index
const int LAST_PLNT = 10; // Last planet index
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void app::Begin(void) // Initialization code
{
// Set up screen
agk::SetVirtualResolution(1024, 768);
agk::SetClearColor(0, 0, 0); // black
agk::SetSyncRate(60, 0);
agk::SetScissor(0, 0, 0, 0);
// Set up lighting with a white lightpoint at the origin
agk::CreateLightDirectional(1, 0, 0, 0, 0, 0, 0); // only needed to create point light
agk::CreateLightPoint(1, 0, 0, 0, 100, 255, 255, 255); // only index 1 available for now
// Set up central star object at origin
agk::CreateObjectSphere(1, 3.0f, 16, 32); // Sphere
agk::SetObjectColor(1, 255, 255, 0, 255); // Yellow
agk::SetObjectPosition(1, 0, 0, 0); // at Origin
agk::SetObjectLightMode(1, 0); // Disable lighting on this object
agk::LoadImage(1, "Media\\Sun1.png"); // Load Texture
agk::SetObjectImage(1, 1, 0); // Apply texture
// Set up initial camera Y height & Z distance from origin
CamHi = 5.0f; // Y
CamDis = 22.5f; // Z
// Define macro to help populate planetary data table
#define _PLANET_(Id, Ra, Sp, Sz, Rd, Gr, Bl) \
Planet[(Id)].OrbitRadius=(Ra); Planet[(Id)].OrbitAngSpd=(Sp); Planet[(Id)].Size=(Sz);\
Planet[(Id)].Color.Red=(Rd); Planet[(Id)].Color.Grn=(Gr); Planet[(Id)].Color.Blu=(Bl); Planet[(Id)].Color.Alp=255;
// Populate planetary data table
// Index Radius Speed Size Red Grn Blu
_PLANET_( 3, 3.0f, .08f, 0.3f, 255, 0, 0) // Red
_PLANET_( 4, 4.1f, .07f, 0.4f, 255, 127, 0) // Orange
_PLANET_( 5, 5.2f, .06f, 0.5f, 255, 255, 0) // Yellow
_PLANET_( 6, 6.3f, .05f, 0.6f, 0, 255, 0) // Green
_PLANET_( 7, 7.4f, .04f, 0.7f, 0, 0, 255) // Blue
_PLANET_( 8, 8.5f, .03f, 0.8f, 255, 0, 255) // Magenta
_PLANET_( 9, 9.6f, .02f, 0.9f, 255, 255, 255) // White
_PLANET_(10, 10.7f, .01f, 1.0f, 0, 255, 255) // Cyan
// For each planet (first to last)
for (int Plnt = FIRST_PLNT; Plnt < LAST_PLNT+1; Plnt++)
{
// Set up the planet
agk::CreateObjectSphere(Plnt, Planet[Plnt].Size, 8, 16); // Sphere of specified size
agk::SetObjectColor(Plnt, Planet[Plnt].Color.Red, Planet[Plnt].Color.Grn, Planet[Plnt].Color.Blu, Planet[Plnt].Color.Alp);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void app::Loop(void) // Cyclic code
{
// Display help text for camera keyboard controls
agk::PrintC("C/Sp=Dn/Up CamY: "); agk::PrintC(CamHi); agk::Print(" Z=Reset CamY/Z");
agk::PrintC("W/S=In/Out CamZ: "); agk::Print(CamDis);
// Get key inputs
int KeyW = agk::GetRawKeyState(87); // Camera In
int KeyS = agk::GetRawKeyState(83); // Camera Out
int KeyC = agk::GetRawKeyState(67); // Camera Down
int KeySp = agk::GetRawKeyState(32); // Camera Up
int KeyZ = agk::GetRawKeyState(90); // Camera "Zero" (reset)
int KeyEsc = agk::GetRawKeyState(27); // Exit application
// Update camera Y Height & Z Distance based on key inputs (note: not currently limited)
if (KeyC) CamHi -= CAMHI_RAT; else if (KeySp) CamHi += CAMHI_RAT; // Y Height Dn/Up
if (KeyW) CamDis -= CAMDS_RAT; else if (KeyS) CamDis += CAMDS_RAT; // Z Distance In/Out
if (KeyZ) { CamHi = 5.0f; CamDis = 22.5f; } // Reset
// For each planet (first to last)
for (int Plnt = FIRST_PLNT; Plnt < LAST_PLNT+1; Plnt++)
{
// Integrate & wrap orbital angle based on its angular speed (sign controls direction)
Planet[Plnt].OrbAngRad -= Planet[Plnt].OrbitAngSpd;
if (Planet[Plnt].OrbAngRad < PI2_RAD) Planet[Plnt].OrbAngRad += PI2_RAD;
// Determine & set planet's circular path position based on it's angular position & radius
// Polar to rectangular: Z = R * cos(angle); X = R * sin(angle); angles in radians
Planet[Plnt].zPos = Planet[Plnt].OrbitRadius * cos(Planet[Plnt].OrbAngRad);
Planet[Plnt].xPos = Planet[Plnt].OrbitRadius * sin(Planet[Plnt].OrbAngRad);
agk::SetObjectPosition(Plnt, Planet[Plnt].xPos, Planet[Plnt].yPos, Planet[Plnt].zPos);
}
// Rotate sun using innermost planet angle (deg)
agk::SetObjectRotation(1, 0, Planet[3].OrbAngRad * DEG_RAD, 0);
// Update camera Y Height & Z Distance, while still looking at origin
agk::SetCameraPosition(1, 0, CamHi, CamDis);
agk::SetCameraLookAt(1, 0, 0, 0, 0);
// Update display
agk::Sync();
// Exit on <Esc> key
if (KeyEsc) PostQuitMessage(0);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void app::End (void) // Cleanup code
{
// Cleanup as required
}
Code every line like it might be your last...
Someday it will be.