So first off all we must come up with structure of our program. it will consist of the following classes: House, camera, controller, exterior.
Than we need to draw the house, I did this job in 3DMax and it was really easy. You can find many different lessons or documentation, on how to do this in the internet, or even by some books but I prefer the first :)
You can DOWNLOAD it from HERE. And here is the project code:
The MainForm:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ShadowEngine;
using ShadowEngine.OpenGL;
using Tao.OpenGl;
using ShadowEngine.Sound;
namespace Casa
{
public partial class MainForm : Form
{
//handle the viewport
uint hdc;
controller controller = new controller();
int moving;
static Vector2 formPos;
bool lines;
bool pressedH;
public static Vector2 FormPos
{
get { return MainForm.formPos; }
set { MainForm.formPos = value; }
}
public MainForm()
{
InitializeComponent();
//identifier of where I will draw
hdc = (uint)pnlViewPort.Handle;
//making the mistake that happened
string error = "";
//Command initialization of the viewport
OpenGLControl.OpenGLInit(ref hdc, pnlViewPort.Width, pnlViewPort.Height, ref error);
if (error != "")
{
MessageBox.Show(error);
}
// start position of the camera angle so as defined in perspective, etc etc
controller.Camera.InitCamera();
//Enables the lights
Lighting.SetupLighting();
ContentManager.SetTextureList("textures\\"); //specify the location of the textures
ContentManager.LoadTextures(); //the charge
ContentManager.SetModelList("models\\"); // the specific location of the office
ContentManager.LoadModels(); //the charge
Camera.CenterMouse();
controller.creatingObjects();
}
private void tmrPaint_Tick(object sender, EventArgs e)
{
// opengl clean paint
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
//draws the entire scene
controller.Camera.Update(moving);
controller.DrawScene();
//change the buffer
Winapi.SwapBuffers(hdc);
//finish paint
Gl.glFlush();
}
private void MainForm_Load(object sender, EventArgs e)
{
formPos = new Vector2(this.Left, this.Top); // first coordinates of camera
}
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
if (!pressedH)
{
panel1.Visible = true;
panel2.Visible = true;
panel3.Visible = true;
panel4.Visible = true;
pressedH = true;
}
else
{
panel1.Visible = false;
panel2.Visible = false;
panel3.Visible = false;
panel4.Visible = false;
pressedH = false;
}
if (e.KeyCode == Keys.Escape)
{
Close();
}
if (e.KeyCode == Keys.W)
{
moving = 1;
}
if (e.KeyCode == Keys.L)
{
if (lines)
{
Gl.glPolygonMode(Gl.GL_FRONT_AND_BACK, Gl.GL_FILL);
lines = false;
}
else
{
Gl.glPolygonMode(Gl.GL_FRONT_AND_BACK, Gl.GL_LINE);
lines = true;
}
}
}
private void pnlViewPort_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
moving = 1;
}
if (e.Button == MouseButtons.Right)
{
moving = -1;
}
}
private void pnlViewPort_MouseUp(object sender, MouseEventArgs e)
{
moving = 0;
}
private void MainForm_KeyUp(object sender, KeyEventArgs e)
{
moving = 0;
}
private void label2_Click(object sender, EventArgs e)
{
}
private void pnlViewPort_Paint(object sender, PaintEventArgs e)
{
}
}
}
The class House:
using System;
using System.Collections.Generic;
using System.Text;
using ShadowEngine;
using ShadowEngine.ContentLoading;
using Tao.OpenGl;
namespace Casa
{
public class House
{
ModelContainer m;
Mesh aspa;
float bladeAngle;
public void Create()
{
m = ContentManager.GetModelByName("house3.3DS");
m.CreateDisplayList();
aspa = m.GetMeshWithName("ventilado0");
aspa.CalcCenterPoint(); // calculating the midpoint of the object
m.RemoveMeshByName("ventilado0"); //remove the mesh
}
public void CreateCollisions()
{
Collision.AddCollisionSegment(new Point3D(-24.4f, -14.1f, 0), new Point3D(18.9f, -14.1f, 0), 0.5f);
Collision.AddCollisionSegment(new Point3D(-24.4f, -14.1f, 0), new Point3D(-24.4f, 13.2f, 0), 0.5f);
Collision.AddCollisionSegment(new Point3D(-20.2f, -0.1f, 0), new Point3D(-4.8f, -0.1f, 0), 0.5f);
Collision.AddCollisionSegment(new Point3D(-0.5f, 0.7f, 0), new Point3D(-0.5f, -8.7f, 0), 0.5f);
Collision.AddCollisionSegment(new Point3D(19.4f, 14.4f, 0), new Point3D(-24.4f, 14.4f, 0), 0.5f);
Collision.AddCollisionSegment(new Point3D(19.4f, 14.4f, 0), new Point3D(19.4f, -14.4f, 0), 0.5f);
Collision.AddCollisionSegment(new Point3D(-17.5f, 0.5f, 0), new Point3D(-17.5f, 11, 0), 0.5f);
Collision.AddCollisionSegment(new Point3D(13.4f, -0.15f, 0), new Point3D(18.74f, -0.15f, 0), 0.5f);
Collision.AddCollisionSegment(new Point3D(-0.43f, -9.1f, 0), new Point3D(12.4f, -9.1f, 0), 0.5f);
//Collision.GhostMode = true;
}
public void Draw()
{
Gl.glPushMatrix();
Gl.glTranslatef(0, 2.3f, 0);
Gl.glScalef(0.1f, 0.1f, 0.1f);
m.DrawWithTextures();
#region Ventilator (rotation, drawing...)
Gl.glPushMatrix();
bladeAngle += 25;
if (bladeAngle > 3600)
{
bladeAngle = 0;
}
//rotaition of ventilator
Gl.glTranslatef(aspa.CenterPoint.X, aspa.CenterPoint.Y, aspa.CenterPoint.Z);
Gl.glRotatef(-bladeAngle, 0, 0, 1);
Gl.glTranslatef(-aspa.CenterPoint.X, -aspa.CenterPoint.Y, -aspa.CenterPoint.Z);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, ContentManager.GetTextureByName(aspa.Name + ".jpg"));
aspa.Draw();
Gl.glPopMatrix();
#endregion
Gl.glPopMatrix();
}
}
}
Class Camera:
using System;
using System.Collections.Generic;
using System.Text;
using Tao.OpenGl;
using System.Drawing;
using ShadowEngine;
namespace Casa
{
public class Camera
{
#region Camera constants
const double div1 = Math.PI / 180;
const double div2 = 180 / Math.PI;
#endregion
#region Private atributes
static float eyex, eyey, eyez;
static float centerx, centery, centerz;
static float forwardSpeed = 0.3f;
static float yaw, pitch;
static float rotationSpeed = 1/5f;
static double i, j, k;
#endregion
public static float Pitch
{
get { return Camera.pitch; }
set { Camera.pitch = value; }
}
public static float Yaw
{
get { return Camera.yaw; }
set { Camera.yaw = value; }
}
public void InitCamera() //initilizing pos of x,y,z
{
eyex = -17.1f;
eyey = 7.3f;
eyez = -9.4f;
centerx = -3;
centery = 2;
centerz = -2;
Look();
}
public void Look()
{
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0, 1, 0);
}
static public float AngleToRad(double pAngle)
{
return (float)(pAngle * div1);
}
static public float RadToAngle(double pAngle)
{
return (float)(pAngle * div2);
}
public void UpdateDirVector()
{
k = Math.Cos(AngleToRad((double)yaw));
i = -Math.Sin(AngleToRad((double)yaw));
j = Math.Sin(AngleToRad((double)pitch));
centerz = eyez - (float)k;
centerx = eyex - (float)i;
centery = eyey - (float)j;
}
public static void CenterMouse()
{
Winapi.SetCursorPos(MainForm.FormPos.X + 512, MainForm.FormPos.Y + 384);
}
public void Update(int pressedButton)
{
#region Target chamber
Pointer position = new Pointer();
Winapi.GetCursorPos(ref position);
int difX = MainForm.FormPos.X + 512 - position.x;
int difY = MainForm.FormPos.Y + 384 - position.y;
if (position.y < MainForm.FormPos.Y + 384)
{
pitch -= rotationSpeed * difY;
}
else
if (position.y > MainForm.FormPos.Y + 384)
{
pitch += rotationSpeed * -difY;
}
if (position.x < MainForm.FormPos.X + 512)
{
yaw += rotationSpeed * -difX;
}
else
if (position.x > MainForm.FormPos.X + 512)
{
yaw -= rotationSpeed * difX;
}
UpdateDirVector();
CenterMouse();
if (pressedButton == 1) // pressed the left button of mouse
{
if (!Collision.CheckCollision(new Point3D(eyex - (float)i * forwardSpeed, eyez - (float)k * forwardSpeed, 0)))
{
eyex -= (float)i * forwardSpeed;
eyez -= (float)k * forwardSpeed;
}
}
if (pressedButton == -1) // pressed the left button of mouse
{
if (!Collision.CheckCollision(new Point3D(eyex + (float)i * forwardSpeed, eyez + (float)k * forwardSpeed, 0)))
{
eyex += (float)i * forwardSpeed;
eyez += (float)k * forwardSpeed;
}
}
#endregion
Look();
}
}
}
Class Controller:
using System;
using System.Collections.Generic;
using System.Text;
using ShadowEngine;
namespace Casa
{
public class controller
{
Camera camera = new Camera();
House house = new House();
Exterior sky = new Exterior();
public void creatingObjects()
{
house.Create();
house.CreateCollisions(); // making walls
Sprite.Create(); // draw text on screen (coordinates)
}
public Camera Camera
{
get { return camera; }
}
public void DrawScene()
{
house.Draw(); // drawing the house
sky.Draw(); // outside the house
DebugMode.WriteCamaraPos(200, 200);
Collision.DrawColissions();
}
}
}
Class Exterior:
using System;
using System.Collections.Generic;
using System.Text;
using ShadowEngine;
using Tao.OpenGl;
namespace Casa
{
class Exterior
{
public void Draw()
{
// size height and length
int width = 240;
int height = 200;
int length = 240;
// begins at these coordinates
int x = 10;
int y = -3;
int z = 7;
//encentrar the square
x = x - width / 2;
y = y - height / 2;
z = z - length / 2;
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, ContentManager.GetTextureByName("back.jpg"));
//begins to draw squares
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3d(-1, 1, 1);
Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3d(x + width, y, z);
Gl.glNormal3d(-1, -1, 1);
Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3d(x + width, y + height, z);
Gl.glNormal3d(1, -1, 1);
Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3d(x, y + height, z);
Gl.glNormal3d(1, 1, 1);
Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3d(x, y, z);
Gl.glEnd();
Gl.glBindTexture(Gl.GL_TEXTURE_2D, ContentManager.GetTextureByName("front.jpg"));
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3d(1, 1, -1);
Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3d(x, y, z + length);
Gl.glNormal3d(1, -1, -1);
Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3d(x, y + height, z + length);
Gl.glNormal3d(-1, -1, -1);
Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3d(x + width, y + height, z + length);
Gl.glNormal3d(-1, 1, -1);
Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3d(x + width, y, z + length);
Gl.glEnd();
Gl.glBindTexture(Gl.GL_TEXTURE_2D, ContentManager.GetTextureByName("top.jpg"));
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3d(-1, -1, 1);
Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3d(x + width, y + height, z);
Gl.glNormal3d(-1, -1, -1);
Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3d(x + width, y + height, z + length);
Gl.glNormal3d(1, -1, -1);
Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3d(x, y + height, z + length);
Gl.glNormal3d(1, -1, 1);
Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3d(x, y + height, z);
Gl.glEnd();
Gl.glBindTexture(Gl.GL_TEXTURE_2D, ContentManager.GetTextureByName("left.jpg"));
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3d(1, -1, 1);
Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3d(x, y + height, z);
Gl.glNormal3d(1, -1, -1);
Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3d(x, y + height, z + length);
Gl.glNormal3d(1, 1, -1);
Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3d(x, y, z + length);
Gl.glNormal3d(1, 1, 1);
Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3d(x, y, z);
Gl.glEnd();
Gl.glBindTexture(Gl.GL_TEXTURE_2D, ContentManager.GetTextureByName("right.jpg"));
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3d(-1, 1, 1);
Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3d(x + width, y, z);
Gl.glNormal3d(-1, 1, -1);
Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3d(x + width, y, z + length);
Gl.glNormal3d(-1, -1, -1);
Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3d(x + width, y + height, z + length);
Gl.glNormal3d(-1, -1, 1);
Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3d(x + width, y + height, z);
Gl.glEnd();
Gl.glBindTexture(Gl.GL_TEXTURE_2D, ContentManager.GetTextureByName("GRASS2.JPG"));
Gl.glBegin(Gl.GL_QUADS);
Gl.glNormal3d(1, 1, 1);
Gl.glTexCoord2f(8.0f, 0.0f); Gl.glVertex3d(x, 1, z);
Gl.glNormal3d(1, 1, -1);
Gl.glTexCoord2f(8.0f, 8.0f); Gl.glVertex3d(x, 1, z + length);
Gl.glNormal3d(-1, 1, -1);
Gl.glTexCoord2f(0.0f, 8.0f); Gl.glVertex3d(x + width, 1, z + length);
Gl.glNormal3d(-1, 1, 1);
Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3d(x + width, 1, z);
Gl.glEnd();
}
}
}
Class winApi
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace Casa
{
public struct Pointer
{
public int x;
public int y;
}
public static class Winapi
{
[DllImport("GDI32.dll")]
public static extern void SwapBuffers(uint hdc);
[DllImport("user32.dll")]
public static extern void SetCursorPos(int x, int y);
[DllImport("user32.dll")]
public static extern void GetCursorPos(ref Pointer point);
}
}