Texture Mapping in Direct3D

From IronPython Cookbook

An image to use as a texture map

Adapted from this blog entry.

This example shows using texture mapping with Direct3D. It needs an image ('texture.bmp') in the same directory to use as a texture. The one I used was the one shown to the right here.

When run, it will look something like the following:

The texture example in action...

This example can be resized.

import clr
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")

clr.AddReferenceByPartialName("Microsoft.DirectX, Version=1.0.2902.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
clr.AddReferenceByPartialName("Microsoft.DirectX.Direct3D")

# Needed for the TextureLoader
clr.AddReferenceByPartialName("Microsoft.DirectX.Direct3DX")

from System import Environment, Math
from System.Drawing import *
from System.Windows.Forms import *

from Microsoft.DirectX import *
from Microsoft.DirectX.Direct3D import *


class Textures(Form):
    def __init__(self):
        self.ClientSize = Size(400, 300)
        self.Text = "D3D Tutorial 05: Textures"
        
        self.pause = False
        self.device = None
        self.vertexBuffer = None
        self.texture = None
        
        self.Paint += lambda *_: self.render()
        self.Resize += self.onResize
        
        self.initializeGraphics()


    def initializeGraphics(self):
        presentParams = PresentParameters()
        presentParams.Windowed = True
        presentParams.SwapEffect = SwapEffect.Discard
        presentParams.EnableAutoDepthStencil = True
        presentParams.AutoDepthStencilFormat = DepthFormat.D16

        self.device = Device(0, DeviceType.Hardware, self, CreateFlags.SoftwareVertexProcessing, presentParams)
        self.device.DeviceReset += self.onResetDevice

        self.onCreateDevice(self.device, None)
        self.onResetDevice(self.device, None)


    def onCreateDevice(self, dev, event):
        self.vertexBuffer = VertexBuffer(
            CustomVertex.PositionNormalTextured, 100,
            dev,
            Usage.WriteOnly,
            CustomVertex.PositionNormalTextured.Format,
            Pool.Default)

        self.vertexBuffer.Created += self.onCreateVertexBuffer

        self.onCreateVertexBuffer(self.vertexBuffer, None)


    def onResetDevice(self, dev, event):
        dev.RenderState.CullMode = Cull.None
        dev.RenderState.Lighting = False
        dev.RenderState.ZBufferEnable = True

        self.texture = TextureLoader.FromFile(dev, "texture.bmp")


    def onCreateVertexBuffer(self, vb, event):
        verts = vb.Lock(0, LockFlags.None)

        for i in xrange(50):
            theta = (2 * Math.PI * i) / 49
            sin_theta = Math.Sin(theta)
            cos_theta = Math.Cos(theta)
            verts[2 * i] = CustomVertex.PositionNormalTextured(
                Vector3(sin_theta, -1, cos_theta),  # Position
                Vector3(sin_theta,  0, cos_theta),  # Normal
                i/float(50-1), 1.0                  # TextureUV
            )
            verts[2 * i + 1] = CustomVertex.PositionNormalTextured(
                Vector3(sin_theta, 1, cos_theta),   # Position
                Vector3(sin_theta, 0, cos_theta),   # Normal
                i/float(50-1), 0.0                  # TextureUV
            )

        vb.Unlock()


    def render(self):
        if not self.device:
            print "error"
            return

        if self.pause:
            return

        self.device.Clear(ClearFlags.Target|ClearFlags.ZBuffer, Color.Blue, 1.0, 0)

        self.device.BeginScene()

        self.setupMatrices()

        self.device.SetTexture(0, self.texture)
        self.device.TextureState[0].ColorOperation = TextureOperation.Modulate
        self.device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor
        self.device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse
        self.device.TextureState[0].AlphaOperation = TextureOperation.Disable

        self.device.SetStreamSource(0, self.vertexBuffer, 0)

        self.device.VertexFormat = CustomVertex.PositionNormalTextured.Format

        self.device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, (4*25)-2)

        self.device.EndScene()
        self.device.Present()


    def setupMatrices(self):
        tick_step   = Environment.TickCount / 250.0
        roll_step   = Environment.TickCount / 1000.0
        axis        = Vector3(Math.Cos(tick_step), 1, Math.Sin(tick_step))
        self.device.Transform.World = Matrix.RotationAxis(axis, roll_step)

        self.device.Transform.View = Matrix.LookAtLH(
            Vector3(0.0, 3.0, -5.0),
            Vector3(0.0, 0.0, 0.0),
            Vector3(0.0, 1.0, 0.0)
        )

        self.device.Transform.Projection = Matrix.PerspectiveFovLH(
            Math.PI / 4, 1.0, 1.0, 100.0)


    def onResize(self, sender, event):
        self.pause = (self.WindowState == FormWindowState.Minimized) or not self.Visible


frm = Textures()
frm.Show()

while (frm.Created):
    frm.render()
    Application.DoEvents()


Back to Contents.

TOOLBOX
LANGUAGES