Проект texture1
Main Menu - File → New Project... → Visual Studio installed templates: Windows Forms Application
Name: texture1 → Location: C:\temp → Create directory for solution: отключить → OK
Сотрите Program.cs и Form1.Designer.cs и код внутри Form1.cs.
В References добавить Microsoft.DirectX Version 1.0.2902.0 и Microsoft.DirectX.Direct3D Version 1.0.2902.0.
Добавьте следующий код в Form1.cs
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
public class Form1 : Form
{
[STAThread]
static void Main() { Application.Run(new Form1()); }
static Device device = null;
static float xAngle, yAngle, zAngle;
static Vector3 xAxis = new Vector3(1, 0, 0);
static Vector3 yAxis = new Vector3(0, 1, 0);
static Vector3 zAxis = new Vector3(0, 0, 1);
VertexBuffer vertexBuffer;
Bitmap bmp = null;
Texture texture = null;
const Int32 N = 100; //N must be an even no. 6, 8, 10, etc
CustomVertex.PositionNormalTextured[] vv = new CustomVertex.PositionNormalTextured[N];
Timer myTimer = new Timer();
public Form1()
{
MenuItem miRead = new MenuItem("Read", new EventHandler(MenuFileRead));
MenuItem miExit = new MenuItem("Exit", new EventHandler(MenuFileExit));
MenuItem miFile = new MenuItem("File", new MenuItem[] { miRead, miExit });
Menu = new System.Windows.Forms.MainMenu(new MenuItem[] { miFile });
try
{ //Delete this inner try-catch clause if you have no Internet connection running.
String s = "http://gems.novikov.de/resources/texture4.jpg";
System.Net.WebRequest webreq = System.Net.WebRequest.Create(s);
System.Net.WebResponse webres = webreq.GetResponse();
System.IO.Stream stream = webres.GetResponseStream();
bmp = (Bitmap)Image.FromStream(stream);
}
catch { };
Text = "D3DTexture: Use the File menu to read new textures !";
//TriangleStrip forming a cylinder
//radius = 1; axis = Z-axis; top = 1; bottom = -1; => height = 2;
//in order to see the vertices, replace the TriangleStrip by a LineStrip in OnTimer(...)
float arcus_increment = (float)(2.0 * Math.PI / (N - 2)); //cylinder angular increment
float tu_increment = (float)(1.0 / (N - 2)); //texture horiz. increment
Vector3 v = new Vector3();
for (int i = 0; i < N; i++)
{
float arcus = i * arcus_increment;
v.X = (float)Math.Cos(arcus);
v.Y = (float)Math.Sin(arcus);
if (i % 2 == 0) v.Z = 1f;
else v.Z = -1f; //zigzag between top and bottom
vv[i].Position = v; //vertex = (cos,sin,+1) or (cos,sin,-1)
v.Z = 0; //cylinder normals have no Z-component
vv[i].Normal = v; //normal = (cos,sin,0)
vv[i].Tu = i * tu_increment; //horizontal texture position
if (i % 2 == 0) vv[i].Tv = 0f;
else vv[i].Tv = 1f; //vertical zigzag on texture image
}
myTimer.Tick += new EventHandler(OnTimer);
myTimer.Interval = 1;
ClientSize = new Size(400, 300); //Calls OnResize( ... )
}
protected override void OnResize(System.EventArgs e)
//Whenever the window changes we have to initialize Direct3D from scratch
{
myTimer.Stop();// stop the timer during initialization
try
{ //get information from the operating system about its current graphics properties
PresentParameters presentParams = new PresentParameters();
//we have to set two flags
presentParams.Windowed = true; //no full screen display
presentParams.SwapEffect = SwapEffect.Discard; //no swap buffer
presentParams.EnableAutoDepthStencil = true; //with depth buffer
presentParams.AutoDepthStencilFormat = DepthFormat.D16; //16 bit depth
//Create a new D3D-device that serves as canvas.
if (device != null) device.Dispose(); //free the old canvas if any
device = new Device(0, DeviceType.Hardware, this,
CreateFlags.SoftwareVertexProcessing, presentParams);
//Create a white material.
Material mtrl = new Material();
mtrl.Diffuse = mtrl.Ambient = Color.White;
device.Material = mtrl;
//Create a single, white, directional, diffuse light source and a gray ambient light.
//Many lights may be active at a time. (Notice: Each one slows down the render process.)
device.Lights[0].Type = LightType.Directional;
device.Lights[0].Diffuse = System.Drawing.Color.White;
device.Lights[0].Direction = new Vector3(0, 1, 1);
device.Lights[0].Enabled = true; //turn it on
//Finally, turn on some ambient light that scatters and lights the object evenly
device.RenderState.Ambient = System.Drawing.Color.FromArgb(0x202020);
//setup texture
if (texture != null) texture.Dispose();
if (bmp != null) texture = Texture.FromBitmap(device, bmp, 0, Pool.Managed);
device.SetTexture(0, texture);
//set up the transformation of world coordinates into camera or view space
device.Transform.View = Matrix.LookAtLH(
new Vector3(0f, 0f, -4f), //eye point 4.0 in front of the canvas
new Vector3(0f, 0f, 0f), //camera looks at point 0,0,0
new Vector3(0f, 1f, 0f)); //worlds up direction is the y-axis
//set up the projection transformation using 4 parameters:
//1.: field of view = 45 degrees; 2.: aspect ratio = width / height = 1 = square window;
//3.: near clipping distance = 0; 4.: far clipping distance = 10;
device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, 1f, 1f, 10f);
device.RenderState.CullMode = Cull.None;
device.RenderState.Lighting = true;
//set up the property that fills the triangle with colors
device.VertexFormat = CustomVertex.PositionNormalTextured.Format;
//create a new vertex buffer and connect it to the device
if (vertexBuffer != null) vertexBuffer.Dispose(); //free the old vertexBuffer if any
vertexBuffer = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured), N,
device, 0, CustomVertex.PositionNormalTextured.Format,
Pool.Default);
//copy the coordinates and colors of "vv" into the vertex buffer
vertexBuffer.SetData(vv, 0, LockFlags.None);
device.SetStreamSource(0, vertexBuffer, 0);
myTimer.Start();//start the timer again
}
catch (DirectXException) { MessageBox.Show("Could not initialize Direct3D."); return; }
}
protected static void OnTimer(Object myObject, EventArgs myEventArgs)
{
if (device == null) return;
//throw the old image away
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Gray, 1f, 0);
//rotate with 3 angular velocities
xAngle += 0.1f;
yAngle += 0.02f;
zAngle += 0.02f;
device.Transform.World = Matrix.RotationAxis(xAxis, xAngle);
device.Transform.World *= Matrix.RotationAxis(yAxis, yAngle);
device.Transform.World *= Matrix.RotationAxis(zAxis, zAngle);
//draw on the canvas
device.BeginScene();
device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, N - 2);
//Experiment: Replace the TriangleStrip by a LineStrip as follows:
//device.DrawPrimitives( PrimitiveType.LineStrip, 0, N-2 );
device.EndScene();
device.Present(); //show the canvas
}
void MenuFileRead(object obj, EventArgs ea)
{
try
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Filter = "images |*.bmp;*.gif;*.jpeg;*.jpg;*.png;*.tif;*.tiff;*.bmp|" +
"Windows Bitmap (*.bmp)|*.bmp|" +
"Graphics Interchange Format (*.gif)|*.gif|" +
"Joint Photographic Experts Group (*.jpg)|*.jpg;*.jpeg|" +
"Portable Network Graphics (*.png)|*.png|" +
"Tag Image File Format (*.tif)|*.tif;*.tiff|" +
"All files (*.*)|*.*";
if (dlg.ShowDialog() != DialogResult.OK) return;
bmp = (Bitmap)Image.FromFile(dlg.FileName);
OnResize(null);
}
catch
{ MessageBox.Show("Cannot read", "D3DTexture", MessageBoxButtons.OKCancel); }
}
void MenuFileExit(object obj, EventArgs ea)
{ Application.Exit(); }
}
Embedded Resource = Встроенные данные
Наша программа требует наличия текстуры "texture4.jpg" и в конструкторе производится попытка поиска текстуры по адресу "http://gems.novikov.de/resources/texture4.jpg".
Проблема: Если это не сработает - программа стартует без текстуры.
Решение: Встройте "texture4.jpg" про грамму:
1. В Solution Explorer кликните правой кнопкой на проект texture1. В контекстном меню выберите Add - Add Existing Item....В диалоговом окне выберите Image Files (*.bmp, ... ). и найдите и загрузите файл текстуры на вашем компьютере. Элемент "texture4.jpg" появится в проекте. В свойствах этого элемента "Properties"поменяйте свойство Build Action с Content на Embedded Resource.
2. Сотрите в конструкторе public Form1() следующий блок:
try { //Delete this inner try-catch clause if you have no Internet connection running.
String s = "http://www.miszalok.de/Images/tiger.bmp";
System.Net.WebRequest webreq = System.Net.WebRequest.Create( s );
System.Net.WebResponse webres = webreq.GetResponse();
System.IO.Stream stream = webres.GetResponseStream();
bmp = (Bitmap)Image.FromStream( stream );
} catch {};
и замените этот код на строку:
bmp = new Bitmap( typeof( Form1 ), "texture1.texture4.jpg" ); //read the embedded resource
Теперь после построения нового texture1.exe - программа содержит собственную начальную текстуру.
Плюс: "texture4.jpg" при старте всегда на месте независимо от ресурса в интернете..
Минус: Размер texture1.exe увеличился на размер файла текстуры texture4.jpg.