Jump to content

  • Log In with Google      Sign In   
  • Create Account

[RESOLVED]World of Warcraft Image Effect (Spell Cooldown) With Source Code!


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
13 replies to this topic

#1 Psychopathetica   Members   -  Reputation: 199

Like
0Likes
Like

Posted 28 October 2011 - 10:38 AM

I'm recreating World of Warcraft only in 2D using DirectX and I'm trying to simulate this which can be used as a cooldown on a spell that you can't use for a certain number of seconds / minutes. The lit image overlaying rotates smoothly around like a clock over the darkened image.I figured the solution to this would be to split the square into a pie using 8 separate polygons. But my problem is probably in my rotation trigonometry with both the texture coordinates and rotation, cause I can only get one polygon of the 8 to work properly. The others just warp or don't do it right. Is there a solution or a better approach on how I can produce this effect shown below? Thanks in advance. I'm using VB but I can decipher C++ and C# as well if someone has a code sample.

Spell.png



Sponsor:

#2 Codarki   Members   -  Reputation: 462

Like
1Likes
Like

Posted 28 October 2011 - 10:47 AM

Think of it as black and white mask for the image. Then create a triangle-fan geometry (minimum of 4 triangles or so) where each outer vertex is weighted linearly, then just rotate with time. The actual triangles can be a lot bigger than the rendertarget.

Or you could calculate angle for each pixel, and shade accordingly.

#3 FLeBlanc   Crossbones+   -  Reputation: 3117

Like
5Likes
Like

Posted 28 October 2011 - 11:43 AM

You can also do that effect by drawing a translucent black area over the buttons with an alpha-blend texture that looks something like this:
Posted Image

Don't use continuous blending, but more of a stenciled blend, and vary the cut-off of the blend based on time remaining in the cooldown. This way, you can do a continuous sweep and the only assets you need to create are the button and the above texture.

#4 Codarki   Members   -  Reputation: 462

Like
0Likes
Like

Posted 28 October 2011 - 11:51 AM

FleBlanc's solution is better than mine Posted Image

Just make sure the change in gradient is a straight line. I've become paranoid about results of photo editing tools.

#5 Psychopathetica   Members   -  Reputation: 199

Like
0Likes
Like

Posted 28 October 2011 - 12:49 PM

I'm a little confused cause on wow it's lit the whole time as it goes around over the darkened image. It doesn't get darker or lighter as it goes around, but rather starts from nothing and reappears as it goes around with it's original color. Could you explain in more detail about the stencil blend? Maybe I'm misunderstanding =P

#6 Codarki   Members   -  Reputation: 462

Like
0Likes
Like

Posted 28 October 2011 - 01:14 PM

You linearly with time apply a cut-off value for that black and white image with a gradient. When the cut-off value is below the pixel value it is 0, and above it is 1. This makes the gradient bitmap only two color, 0 or 1, black and white. You use this as a multiplier for the original image. Then you add some constant value so the image is dimmed when mask is zero, and original color when mask is 1.

So with cut-off value of 0.5, half of the rectangle is 0 and other half is 1.

#7 FLeBlanc   Crossbones+   -  Reputation: 3117

Like
1Likes
Like

Posted 28 October 2011 - 04:06 PM

Here is how it works:

Imagine you have a grey rectangle that is (0.5,0.5,0.5) color, and a button. If you draw the grey rectangle over the button using a subtractive blending mode (ie, subtract the grey square from the button) you get a darkened button.

The way this method works is that you draw the grey square over the button, with the swirl texture above set as the grey square's alpha channel. Only you don't do alpha-based blending; that would just result in the grey square appearing darker/lighter as it goes around as you thought it might. No, you continue to use subtractive blending. The difference is that you use the alpha channel as a stencil test. If the alpha value is under a certain threshold, draw the pixel, otherwise discard it. So the alpha channel only provides a pass/fail test for whether a pixel is to be drawn, but when the pixel is drawn it is merely subtracted from the pixel that is already there from drawing the button, making that pixel a bit dimmer.

The magic comes in setting the threshold value to compare the source alpha against. When this value is 1, the entire square will be darkened, because every pixel in the swirl texture corresponds to an alpha value that is less than or equal to 1. However, as you lower the value of the alpha test toward 0, fewer and fewer of the swirl pixels pass the test, and the pattern of pixels that fails the test sweeps around the circle following the circular gradient, until finally you hit 0 and the entire grey texture is discarded.

Here is a minimal example using SFML and OpenGL. There are some caveats here, though, in that the piece of shit computers I have at work are old integrated Intel boxes with XP and no updated drivers that don't support the ARB_imaging OpenGL extension, and so I couldn't set a subtractive blend. So in this example, the button starts out dark and is lightened by the overlay gray sweep texture, rather than starting out bright and being darkened. The interesting bits, however, are in the way I use glAlphaTest() to pass/fail pixels in the sweep texture. (Also, given that I couldn't do subtractive, the comparison function is greater-equal rather than less-than-equal):

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>


////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{
	// Create the main window
	sf::Window App(sf::VideoMode(800, 600, 32), "SFML OpenGL");

	std::cout << glGetString(GL_VERSION) << std::endl;
	std::cout << glGetString(GL_EXTENSIONS) << std::endl;

	// Create a clock for measuring time elapsed
	sf::Clock Clock;

	// Set color and depth clear value
	glClearDepth(1.f);
	glClearColor(0.f, 0.f, 0.f, 0.f);

	// Enable Z-buffer read and write
	glDisable(GL_DEPTH_TEST);
	//glDepthMask(GL_TRUE);
	glEnable(GL_TEXTURE_2D);

	// Setup a perspective projection
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	//gluPerspective(90.f, 1.f, 1.f, 500.f);
	glOrtho(-400,400,300,-300, -100, 100);

	sf::Image swirl;
	swirl.LoadFromFile("swirl.png");

	sf::Image button;
	button.LoadFromFile("button.png");

	float alpha=1;

	// Start game loop
	while (App.IsOpened())
	{
    	// Process events
    	sf::Event Event;
    	while (App.GetEvent(Event))
    	{
        	// Close window : exit
        	if (Event.Type == sf::Event::Closed)
            	App.Close();

        	// Escape key : exit
        	if ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape))
            	App.Close();

        	// Resize event : adjust viewport
        	if (Event.Type == sf::Event::Resized)
            	glViewport(0, 0, Event.Size.Width, Event.Size.Height);
    	}

    	// Set the active window before using OpenGL commands
    	// It's useless here because active window is always the same,
    	// but don't forget it if you use multiple windows or controls
    	App.SetActive();

    	// Clear color and depth buffer
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    	button.Bind();
    	glBegin(GL_QUADS);

    	glTexCoord2f(0,0);
    	glVertex2f(-64,-64);
    	glTexCoord2f(0,1);
    	glVertex2f(-64,64);
    	glTexCoord2f(1,1);
    	glVertex2f(64,64);
    	glTexCoord2f(1,0);
    	glVertex2f(64,-64);


    	glEnd();

    	// Draw a cube
    	//glBlendColor(1,1,1,0.5);
    	glEnable(GL_BLEND);
    	glBlendFunc(GL_ONE, GL_ONE);
    	//glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
    	glEnable(GL_ALPHA_TEST);
    	glAlphaFunc(GL_GEQUAL, alpha);

    	swirl.Bind();
    	glBegin(GL_QUADS);

    	glTexCoord2f(0,0);
    	glVertex2f(-64,-64);
    	glTexCoord2f(0,1);
    	glVertex2f(-64,64);
    	glTexCoord2f(1,1);
    	glVertex2f(64,64);
    	glTexCoord2f(1,0);
    	glVertex2f(64,-64);


    	glEnd();

    	glDisable(GL_BLEND);
    	glDisable(GL_ALPHA_TEST);




    	// Finally, display rendered frame on screen
    	App.Display();

    	alpha-=(Clock.GetElapsedTime() * 0.5);
    	if(alpha<0) alpha=1;
    	Clock.Reset();
	}

	return EXIT_SUCCESS;
}


Now, it is OpenGL because I don't use Direct3D ever, but the same principles should apply in Direct3D. You get the alpha value from the texture, compare against the threshold, and pass/fail it, then blend the passed pixels against the button pixels already drawn. Here is a screen shot of the above in action:

Posted Image

The darker areas are the button un-brightened, where none of the sweep texture pixels pass. The brighter areas are where the sweep pixels pass the stencil test and are drawn, brightening the view.

#8 Kryzon   Prime Members   -  Reputation: 3314

Like
1Likes
Like

Posted 28 October 2011 - 04:45 PM

Although that elegantly works, the problem with using a texture is that you get a jittery line where a few pixels fail the alpha test (you can see that in the image you posted) - it's minimal, but I'm sure under motion it must be distracting. Warcraft III (where this button "cooldown" effect originated) doesn't have jittery lines when displaying this effect, which leads me to believe it's solely based on geometry blending as explained in the following:

Posted Image

The above would require every button to be square (such as they are in WoW or Warcraft III). By using Stencil tests instead of Scissoring you can have buttons of any shape, as long as they don't use transparency.
The angle of the polygon indicates the "cooldown" value. You can easily place its vertices using Cos() and Sin() based on that angle. To safely have a fully shaded button graphic without artifacts, you need five total vertices with four rotating around the button and the fifth on the center. This is enough to surround any shape of button.

EDIT: I just realized user Codarki of post #2 shares the same opinion.

#9 Psychopathetica   Members   -  Reputation: 199

Like
0Likes
Like

Posted 29 October 2011 - 11:30 AM

Thanks for the posts. I'm gonna try to take a whack at it with DirectX and see if I can get the blasted thing to work and I'll get back to yall.

#10 Psychopathetica   Members   -  Reputation: 199

Like
0Likes
Like

Posted 01 November 2011 - 11:07 AM

I managed to successfully pull it off using Kryzons method but I ran into another problem. Lets say I'm putting the button on the UI. How would I keep it within the square so I dont end up darkening the game or UI itself?

#11 Kryzon   Prime Members   -  Reputation: 3314

Like
0Likes
Like

Posted 01 November 2011 - 12:58 PM

There're two ways to clip the shading polygon to the button's area: using a glScissor() rectangle (might be easier, since you probably have rectangular buttons as well), or setting up a Stencil test (can be used for rectangular buttons just as for any other kind of shape). In case you're not familiar with these functionalities, please refer to the OpenGL documentation or the Direct3D equivalent.

If you decide to use glScissor() you will be able to batch all the buttons and then go in separate passes setting up the scissoring and drawing each one's shading polygon. From all the easy methods available, this is probably the one with the best performance.

#12 Psychopathetica   Members   -  Reputation: 199

Like
0Likes
Like

Posted 01 November 2011 - 11:45 PM

I tried looking it up and it seems a little difficult to implement in DirectX. I can't exactly use OpenGL cause I already got a massive sized game going and can't change all that code. Is there a simple 2D DX example to cut off around that square? With the code I attempted nothing happened o.o . And the example I got it the Stencil code from it was 3D yet my games 2D and non DirectDraw based. Heres what I have so far in my spell cooldown code. It works nicely and the darkened poly I made an even diamond around the square icon split into 4 polys from 5 vertices. But where i have it saying Nothings cutting off, just a poly over a poly is where my problem lies.

Option Explicit

'The 2D (Transformed and Lit) vertex format type.

Private Type TLVERTEX

	X As Single
	Y As Single
	Z As Single
	RHW As Single
	Color As Long
	Specular As Long
	TU As Single
	TV As Single
	
End Type

Private Type Vector

	X As Single
	Y As Single

End Type


Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpPerformanceCount As Currency) As Long

'Some color depth constants to help make the DX constants more readable.
Private Const COLOR_DEPTH_16_BIT As Long = D3DFMT_R5G6B5
Private Const COLOR_DEPTH_24_BIT As Long = D3DFMT_A8R8G8B8
Private Const COLOR_DEPTH_32_BIT As Long = D3DFMT_X8R8G8B8

Private Const IMAGE_SIZE As Long = 100

Private Const PI As Single = 3.141592654

'The 2D (Transformed and Lit) vertex format.
Private Const FVF_TLVERTEX As Long = D3DFVF_XYZRHW Or D3DFVF_TEX1 Or D3DFVF_DIFFUSE Or D3DFVF_SPECULAR

Private DirectX8 As DirectX8 'The master DirectX object.
Private Direct3D As Direct3D8 'Controls all things 3D.
Private Direct3D_Device As Direct3DDevice8 'Represents the hardware rendering.
Private Direct3DX As D3DX8

Private Fullscreen_Enabled As Boolean 'Helps determine whether it's fullscreen mode.
Private Running As Boolean 'Helps determine whether the main game loop is running.

Private Vertex_List(3) As TLVERTEX '4 vertices will make a square.
Private Vertex_List2(5) As TLVERTEX
Private Vertex_List3(3) As TLVERTEX

Private Texture As Direct3DTexture8

Private Alpha As Long

Private X As Single, Y As Single
Private Angle As Single

Private Ticks_Per_Second As Currency
Private Start_Time As Currency
Private Cooldown_Amount As Single
Private Cooldown_Time As Single
Private Milliseconds As Single

Private Cooldown_Flag As Boolean

Private Function Hi_Res_Timer_Initialize() As Boolean

	If QueryPerformanceFrequency(Ticks_Per_Second) = 0 Then
    	Hi_Res_Timer_Initialize = False
	Else
    	QueryPerformanceCounter Start_Time
    	Hi_Res_Timer_Initialize = True
	End If

End Function

Private Function Get_Elapsed_Time() As Single
	
	Dim Last_Time As Currency
	Dim Current_Time As Currency
	
	QueryPerformanceCounter Current_Time
	Get_Elapsed_Time = (Current_Time - Last_Time) / Ticks_Per_Second
	QueryPerformanceCounter Last_Time
	
End Function

'This function will make it much easier to setup the vertices with the info it needs.
Private Function Create_TLVertex(X As Single, Y As Single, Z As Single, RHW As Single, Color As Long, Specular As Long, TU As Single, TV As Single) As TLVERTEX

	Create_TLVertex.X = X
	Create_TLVertex.Y = Y
	Create_TLVertex.Z = Z
	Create_TLVertex.RHW = RHW
	Create_TLVertex.Color = Color
	Create_TLVertex.Specular = Specular
	Create_TLVertex.TU = TU
	Create_TLVertex.TV = TV
	
End Function

Private Function DirectX_Initialize() As Boolean

	On Error GoTo Error_Handler
	
	Dim Display_Mode As D3DDISPLAYMODE 'Display mode desciption.
	Dim Direct3D_Window As D3DPRESENT_PARAMETERS 'Backbuffer and viewport description.
	
	Set DirectX8 = New DirectX8 'Creates the DirectX object.
	Set Direct3D = DirectX8.Direct3DCreate() 'Creates the Direct3D object using the DirectX object.
	Set Direct3DX = New D3DX8
	
	If Fullscreen_Enabled = True Then
	
    	'Now that we are working with fullscreen mode, we must set up the
    	'screen resolution to switch to, rather than use the default screen
    	'resolution.
    	
    	Display_Mode.Width = 800
    	Display_Mode.Height = 600
    	Display_Mode.Format = COLOR_DEPTH_16_BIT
	
    	Direct3D_Window.Windowed = False 'The app will be in fullscreen mode.
    	Direct3D_Window.BackBufferCount = 1 '1 backbuffer only
    	Direct3D_Window.BackBufferWidth = Display_Mode.Width 'Match the backbuffer width with the display width
    	Direct3D_Window.BackBufferHeight = Display_Mode.Height 'Match the backbuffer height with the display height
    	Direct3D_Window.hDeviceWindow = frmMain.hWnd 'Use frmMain as the device window.
    	
	Else
	
    	Direct3D.GetAdapterDisplayMode D3DADAPTER_DEFAULT, Display_Mode 'Use the current display mode that you
                                                                    	'are already on. Incase you are confused, I'm
                                                                    	'talking about your current screen resolution. ;)
    	
    	Direct3D_Window.Windowed = True 'The app will be in windowed mode.
	
	End If
	
	Direct3D_Window.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC 'Refresh when the monitor does.
	Direct3D_Window.BackBufferFormat = Display_Mode.Format 'Sets the format that was retrieved into the backbuffer.
	Direct3D_Window.AutoDepthStencilFormat = D3DFMT_D24S8
	Direct3D_Window.EnableAutoDepthStencil = 1
	
	'Creates the rendering device with some useful info, along with the info
	'we've already setup for Direct3D_Window.
	Set Direct3D_Device = Direct3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, frmMain.hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, Direct3D_Window)
	
	Direct3D_Device.SetVertexShader FVF_TLVERTEX 'Set the type of vertex shading. (Required)
	
	'Right here will alphablend the polygon
	
	Direct3D_Device.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_MODULATE
	Direct3D_Device.SetTextureStageState 0, D3DTSS_COLORARG1, D3DTA_TEXTURE
	Direct3D_Device.SetTextureStageState 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE
       			
	Direct3D_Device.SetTextureStageState 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE
	Direct3D_Device.SetTextureStageState 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE
	Direct3D_Device.SetTextureStageState 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE
	
	Direct3D_Device.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCALPHA
	Direct3D_Device.SetRenderState D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA
	Direct3D_Device.SetRenderState D3DRS_BLENDOP, D3DBLENDOP_ADD
	
	'These lines are not needed, but it's nice to be able to filter the
	'textures to make them look nicer.
	
	Direct3D_Device.SetTextureStageState 0, D3DTSS_MINFILTER, D3DTEXF_POINT
	Direct3D_Device.SetTextureStageState 0, D3DTSS_MAGFILTER, D3DTEXF_POINT


	Exit Function
	
Error_Handler:
	
	MsgBox "An error occured while initializing DirectX", vbCritical
	Close_Program
	DirectX_Initialize = False

End Function

Private Sub Create_Polygon()
	Vertex_List(0) = Create_TLVertex(X - (IMAGE_SIZE / 2) + 0, Y - (IMAGE_SIZE / 2) + 0, 0, 1, D3DColorRGBA(255, 255, 255, Alpha), 0, 0, 0)
	Vertex_List(1) = Create_TLVertex(X - (IMAGE_SIZE / 2) + IMAGE_SIZE, Y - (IMAGE_SIZE / 2) + 0, 0, 1, D3DColorRGBA(255, 255, 255, Alpha), 0, 1, 0)
	Vertex_List(2) = Create_TLVertex(X - (IMAGE_SIZE / 2) + 0, Y - (IMAGE_SIZE / 2) + IMAGE_SIZE, 0, 1, D3DColorRGBA(255, 255, 255, Alpha), 0, 0, 1)
	Vertex_List(3) = Create_TLVertex(X - (IMAGE_SIZE / 2) + IMAGE_SIZE, Y - (IMAGE_SIZE / 2) + IMAGE_SIZE, 0, 1, D3DColorRGBA(255, 255, 255, Alpha), 0, 1, 1)

End Sub

Private Sub Create_Polygon2()
	
	Dim Offset As Long
	Dim Color As Long
	Dim RotX As Single, RotY As Single
	Offset = IMAGE_SIZE
	Color = D3DColorRGBA(0, 0, 0, 155)
	'Angle = 0
	If Angle < 90 Then
    	RotX = X + (0 * Cos((Angle) * (PI / 180)) - (-Offset) * Sin((Angle) * (PI / 180)))
    	RotY = Y + (0 * Sin((Angle) * (PI / 180)) + (-Offset) * Cos((Angle) * (PI / 180)))
    	Vertex_List2(0) = Create_TLVertex(RotX, RotY, 0, 1, Color, 0, 0, 0) 'Top
    	Vertex_List2(1) = Create_TLVertex(X + Offset, Y, 0, 1, Color, 0, 0, 0)	'Right
    	Vertex_List2(2) = Create_TLVertex(X, Y, 0, 1, Color, 0, 0, 0)  'Center
    	Vertex_List2(3) = Create_TLVertex(X, Y + Offset, 0, 1, Color, 0, 0, 0)   'Bottom
    	Vertex_List2(4) = Create_TLVertex(X, Y + -Offset, 0, 1, Color, 0, 0, 0)  ' Top
    	Vertex_List2(5) = Create_TLVertex(X + -Offset, Y, 0, 1, Color, 0, 0, 0)  'Left
	ElseIf Angle >= 90 And Angle < 180 Then
    	RotX = X + ((Offset * Cos((Angle - 90) * (PI / 180))) - (0 * Sin((Angle - 90) * (PI / 180))))
    	RotY = Y + ((Offset * Sin((Angle - 90) * (PI / 180))) + (0 * Cos((Angle - 90) * (PI / 180))))
    	Vertex_List2(0) = Create_TLVertex(RotX, RotY, 0, 1, Color, 0, 0, 0) 'Right
    	Vertex_List2(1) = Create_TLVertex(X, Y + Offset, 0, 1, Color, 0, 0, 0)  'Bottom
    	Vertex_List2(2) = Create_TLVertex(X, Y, 0, 1, Color, 0, 0, 0)  'Center
    	Vertex_List2(3) = Create_TLVertex(X + -Offset, Y, 0, 1, Color, 0, 0, 0)  'Left
    	Vertex_List2(4) = Create_TLVertex(X, Y + -Offset, 0, 1, Color, 0, 0, 0)  ' Top
	ElseIf Angle >= 180 And Angle <= 270 Then
    	RotX = X + ((0 * Cos((Angle - 180) * (PI / 180))) - (Offset * Sin((Angle - 180) * (PI / 180))))
    	RotY = Y + ((0 * Sin((Angle - 180) * (PI / 180))) + (Offset * Cos((Angle - 180) * (PI / 180))))
    	Vertex_List2(0) = Create_TLVertex(RotX, RotY, 0, 1, Color, 0, 0, 0) 'Bottom
    	Vertex_List2(1) = Create_TLVertex(X + -Offset, Y, 0, 1, Color, 0, 0, 0) 'Left
    	Vertex_List2(2) = Create_TLVertex(X, Y, 0, 1, Color, 0, 0, 0)   'Center
    	Vertex_List2(3) = Create_TLVertex(X, Y + -Offset, 0, 1, Color, 0, 0, 0)  ' Top
	Else
    	RotX = X + ((-Offset * Cos((Angle - 270) * (PI / 180))) - (0 * Sin((Angle - 270) * (PI / 180))))
    	RotY = Y + ((-Offset * Sin((Angle - 270) * (PI / 180))) + (0 * Cos((Angle - 270) * (PI / 180))))
    	Vertex_List2(0) = Create_TLVertex(RotX, RotY, 0, 1, Color, 0, 0, 0)   'Left
    	Vertex_List2(1) = Create_TLVertex(X, Y + -Offset, 0, 1, Color, 0, 0, 0)  ' Top
    	Vertex_List2(2) = Create_TLVertex(X, Y, 0, 1, Color, 0, 0, 0)   'Center
	End If
	
End Sub

Private Sub Load_Texture()

	Dim File_Path As String
	Dim Width As Long
	Dim Height As Long
	Dim Transparency_Color As Long
	
	File_Path = App.Path & "\Death Coil.bmp"

	Width = 256
	Height = 256
	
	Transparency_Color = D3DColorRGBA(0, 0, 0, 255)

	Set Texture = Direct3DX.CreateTextureFromFileEx(Direct3D_Device, _
                                                	File_Path, _
                                                	Width, Height, _
                                                	0, _
                                                	0, _
                                                	D3DFMT_A8R8G8B8, _
                                                	D3DPOOL_MANAGED, _
                                                	D3DX_FILTER_POINT, _
                                                	D3DX_FILTER_POINT, _
                                                	Transparency_Color, _
                                                	ByVal 0, _
                                                	ByVal 0)
                                                	

End Sub

Private Sub Game_Loop()

	Do While Running = True
    	
    	DoEvents 'Allow events to happen so the program doesn't lock up.
    	
    	If Fullscreen_Enabled = False Then frmMain.Caption = "CD Time: " & CStr(Cooldown_Time) & " / " & Milliseconds & "   S/X - Angle: " & Angle & " CD = " & Cooldown_Flag
    	
    	'----------------------------------------------------
    	'DirectX automatically handles the framerate for you
    	'which makes it run (at most) as fast as the monitors
    	'refresh rate, so you don't need to add extra code to
    	'slow down the loop and run at a certain number of frames
    	'per second.
    	'----------------------------------------------------
    	
    	'Clears the backbuffer.
    	Direct3D_Device.Clear 0, ByVal 0, D3DCLEAR_TARGET Or D3DCLEAR_STENCIL, D3DColorRGBA(0, 0, 0, 0), 1#, 0
        	
        	Direct3D_Device.BeginScene
        	
            	'Right here will alphablend the polygon
            	Direct3D_Device.SetRenderState D3DRS_ALPHABLENDENABLE, True
            	
            	X = (Me.ScaleWidth / 2)
            	Y = (Me.ScaleHeight / 2)

            	Cooldown_Amount = 5  'seconds
            	
            	If Cooldown_Flag = True Then
                	Cooldown_Time = Get_Elapsed_Time - Milliseconds
                	If Cooldown_Time >= Cooldown_Amount Then Cooldown_Time = Cooldown_Amount
                	Angle = ((Cooldown_Time / Cooldown_Amount) * 360)
            	End If
            	
            	If Angle <= 0 Then Angle = 0
            	If Angle >= 360 Then
                	Angle = 360
                	Cooldown_Flag = False
            	End If
            	
            	Create_Polygon
            	Direct3D_Device.SetTexture 0, Texture
            	Direct3D_Device.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, Vertex_List(0), Len(Vertex_List(0))
        	
            	Create_Polygon2
            	Direct3D_Device.SetTexture 0, Nothing
            	Direct3D_Device.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 4, Vertex_List2(0), Len(Vertex_List2(0))
            	
            	Direct3D_Device.SetRenderState D3DRS_ALPHABLENDENABLE, False
            	
            	With Direct3D_Device
            	
                	.SetRenderState D3DRS_STENCILENABLE, True
                	.SetRenderState D3DRS_STENCILFUNC, D3DCMP_ALWAYS
                	.SetRenderState D3DRS_STENCILREF, 0
                	.SetRenderState D3DRS_STENCILMASK, &HFFFFFFFF
                	.SetRenderState D3DRS_STENCILWRITEMASK, &HFFFFFFFF
                	.SetRenderState D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP
                	.SetRenderState D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP
                	.SetRenderState D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE
            	
                	'.SetRenderState D3DRS_ZWRITEENABLE, False
                	.SetRenderState D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP
                	.SetRenderState D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP
                	.SetRenderState D3DRS_STENCILPASS, D3DSTENCILOP_KEEP
                	.SetRenderState D3DRS_STENCILFUNC, D3DCMP_EQUAL
                	.SetRenderState D3DRS_STENCILREF, 0
                	
                	.SetRenderState D3DRS_STENCILMASK, &H1
'//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Nothings cutting off. It just ends up another poly over my spell icon
'//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                	Vertex_List3(0) = Create_TLVertex(X - (20 / 2) + 0, Y - (20 / 2) + 0, 0, 1, D3DColorXRGB(0, 0, 0), 0, 0, 0)
                	Vertex_List3(1) = Create_TLVertex(X - (20 / 2) + 20, Y - (20 / 2) + 0, 0, 1, D3DColorXRGB(0, 0, 0), 0, 1, 0)
                	Vertex_List3(2) = Create_TLVertex(X - (20 / 2) + 0, Y - (20 / 2) + 20, 0, 1, D3DColorXRGB(0, 0, 0), 0, 0, 1)
                	Vertex_List3(3) = Create_TLVertex(X - (20 / 2) + 20, Y - (20 / 2) + 20, 0, 1, D3DColorXRGB(0, 0, 0), 0, 1, 1)
                	.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, Vertex_List3(0), Len(Vertex_List3(0))
                	
                	.SetRenderState D3DRS_STENCILENABLE, 0
                	'.SetRenderState D3DRS_ZWRITEENABLE, True
                	.SetRenderState D3DRS_ALPHABLENDENABLE, True
            	End With
        	
        	Direct3D_Device.EndScene
    	
    	'Flips the backbuffer into the form window.
    	Direct3D_Device.Present ByVal 0, ByVal 0, 0, ByVal 0
    	
    	QueryPerformanceCounter Start_Time
    	
	Loop

End Sub


Private Sub Close_Program()

	Running = False 'This helps the program bail out of the game loop.
	
	'Unload all of the DirectX objects.
	
	Set Texture = Nothing
	Set Direct3DX = Nothing
	Set Direct3D_Device = Nothing
	Set Direct3D = Nothing
	Set DirectX8 = Nothing
	
	Unload Me 'Unload the form.
	
	End 'Ends the program.
	
	'Although the Unload statement located above exits the program, you
	'will end up with an Automation error after doing so. The End statement
	'will help prevent that, and end the app completely.

End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

	If KeyCode = vbKeyEscape Then 'If the user presses the Esc key...
    	Close_Program
	End If

End Sub

Private Sub Form_Load()

	'This event will fire before the form has completely loaded.
	
	If MsgBox("Click Yes to go to full screen (Recommended)", vbQuestion Or vbYesNo, "Options") = vbYes Then Fullscreen_Enabled = True
	Hi_Res_Timer_Initialize
	frmMain.ScaleMode = vbPixels
	Alpha = 255
	Angle = 360
	frmMain.Show
	DirectX_Initialize 'Initializes DirectX and Direct3D.
	Create_Polygon 'Creates the polygon.
	Load_Texture 'Loads a texture from file.
	Running = True 'Initializations all set. It's now ok to activate the game loop.
	Game_Loop

End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

	If Button = 1 Then
    	If Cooldown_Flag = False And (Angle >= 360) Then
        	Angle = 0
        	Cooldown_Time = 0
        	Milliseconds = Get_Elapsed_Time
        	Cooldown_Flag = True
    	End If
	End If

End Sub

Private Sub Form_Unload(Cancel As Integer)

	Close_Program

End Sub



#13 Kryzon   Prime Members   -  Reputation: 3314

Like
0Likes
Like

Posted 02 November 2011 - 12:09 AM

Direct3D 9 - Scissor Test

Direct3D 10 - Set the Scissor Rectangle

#14 Psychopathetica   Members   -  Reputation: 199

Like
1Likes
Like

Posted 26 June 2013 - 09:53 AM

I know this is an old topic but I figured it out a long time ago. The solution was to overlap the squared spell icon with a perfectly squared diamond the same size only rotated 45 degrees that darken the spell icon. That darkened diamond is then split into 8 triangle slices like a pizza, and gets clipped around the entire square as it rotates, so you only see it within the spell icon. It starts at 8 and as it rotates to shrink the first polys of the group, it cuts it down to 7. Then 6, then 5, 4, 3, 2, and ultimately 1. This can be done at any cooldown time you desire, and it does it very smooth, and accurately. Here is the code:

Option Explicit

Private Type CUSTOM_VERTEX_TYPE
    X As Single
    Y As Single
    Z As Single
    RHW As Single
    Color As Long
    Specular As Long
    TU As Single
    TV As Single
End Type

Private Type Vector
    X As Single
    Y As Single
End Type

Private Type Spell_Type
    Position As Vector
    Angle As Single
    Texture As Direct3DTexture8
    Width As Long
    Height As Long
    Half_Width As Long
    Half_Height As Long
    Image_Size As Long
    Vertex_List(3) As CUSTOM_VERTEX_TYPE
    Vertex_List2(23) As CUSTOM_VERTEX_TYPE
    Clip_Region(3, 3) As CUSTOM_VERTEX_TYPE
    Cooldown_Amount As Single
    Cooldown_Time As Single
    Milliseconds As Single
    Cooldown_Flag As Boolean
    Polycount As Long
End Type

Private Declare Function timeGetTime Lib "winmm.dll" () As Long

'Some color depth constants to help make the DX constants more readable.
Private Const COLOR_DEPTH_16_BIT As Long = D3DFMT_R5G6B5
Private Const COLOR_DEPTH_24_BIT As Long = D3DFMT_A8R8G8B8
Private Const COLOR_DEPTH_32_BIT As Long = D3DFMT_X8R8G8B8

Private Const PI As Double = 3.141592576

'The 2D (Transformed and Lit) vertex format.
Private Const CUSTOM_VERTEX As Long = D3DFVF_XYZRHW Or D3DFVF_TEX1 Or D3DFVF_DIFFUSE Or D3DFVF_SPECULAR

Private DX As DirectX8 'The master DirectX object.
Private D3D As Direct3D8 'Controls all things 3D.
Private Device As Direct3DDevice8 'Represents the hardware rendering.
Private D3DX As D3DX8

Private Fullscreen_Enabled As Boolean 'Helps determine whether it's fullscreen mode.
Private Fullscreen_Width As Long
Private Fullscreen_Height As Long
Private Running As Boolean 'Helps determine whether the main game loop is running.

Private Main_Font As D3DXFont
Private Main_Font_Description As IFont
Private Text_Rect As RECT

Private Spell As Spell_Type

Public Sub Setup_Spell()
    With Spell
        .Position.X = frmMain.ScaleWidth / 2
        .Position.Y = frmMain.ScaleHeight / 2
        .Width = 200
        .Height = 200
        .Half_Width = .Width / 2
        .Half_Height = .Height / 2
        .Cooldown_Amount = 60 'seconds
        Load_Texture App.Path & "\Death Coil.bmp", D3DColorRGBA(255, 255, 255, 255)
        Create_Spell_Polygon Spell
    End With
End Sub

Private Function Get_Elapsed_Time() As Single
    Get_Elapsed_Time = Abs(timeGetTime / 1000)
End Function

'This function will make it much easier to setup the vertices with the info it needs.
Private Function Create_Custom_Vertex(X As Single, Y As Single, Z As Single, RHW As Single, Color As Long, Specular As Long, TU As Single, TV As Single) As CUSTOM_VERTEX_TYPE
    Create_Custom_Vertex.X = X
    Create_Custom_Vertex.Y = Y
    Create_Custom_Vertex.Z = Z
    Create_Custom_Vertex.RHW = RHW
    Create_Custom_Vertex.Color = Color
    Create_Custom_Vertex.Specular = Specular
    Create_Custom_Vertex.TU = TU
    Create_Custom_Vertex.TV = TV
End Function

Private Function Line_Intersect(ByVal L1_X1 As Single, ByVal L1_Y1 As Single, ByVal L1_X2 As Single, ByVal L1_Y2 As Single, _
                                  ByVal L2_X1 As Single, ByVal L2_Y1 As Single, ByVal L2_X2 As Single, ByVal L2_Y2 As Single, _
                                  ByRef Intersection As Vector) As Boolean
    'Denominator for ua and ub are the same, so store this calculation
    Dim Denominator As Double
    Dim n_a As Double
    Dim n_b As Double
    Denominator = (L2_Y2 - L2_Y1) * (L1_X2 - L1_X1) - (L2_X2 - L2_X1) * (L1_Y2 - L1_Y1)

      'n_a and n_b are calculated as seperate values for readability
     ' Dim n_a As Double =

      'Dim n_b As Double =


      'If ua >= 0D AndAlso ua <= 1D AndAlso ub >= 0D AndAlso ub <= 1D Then
      '   Intersection.X = L1.X1 + (ua * (L1.X2 - L1.X1))
      '   Intersection.Y = L1.Y1 + (ua * (L1.Y2 - L1.Y1))
       '  Return True
      'End If

    'n_a and n_b are calculated as seperate values for readability
    n_a = (L2_X2 - L2_X1) * (L1_Y1 - L2_Y1) - (L2_Y2 - L2_Y1) * (L1_X1 - L2_X1)
    n_b = (L1_X2 - L1_X1) * (L1_Y1 - L2_Y1) - (L1_Y2 - L1_Y1) * (L1_X1 - L2_X1)
    
    ' Make sure there is not a division by zero - this also indicates that
    ' the lines are parallel.
    ' If n_a and n_b were both equal to zero the lines would be on top of each
    ' other (coincidental).  This check is not done because it is not
    ' necessary for this implementation (the parallel check accounts for this).
    If Denominator = 0 Then
        Line_Intersect = False
        Exit Function
    End If
    
    ' Calculate the intermediate fractional point that the lines potentially intersect.
    Dim ua As Double: ua = n_a / Denominator
    Dim ub As Double: ub = n_b / Denominator
    
    ' The fractional point will be between 0 and 1 inclusive if the lines
    ' intersect.  If the fractional calculation is larger than 1 or smaller
    ' than 0 the lines would need to be longer to intersect.
    
    If ua >= 0 And ua <= 1 And ub >= 0 And ub <= 1 Then
        Intersection.X = L1_X1 + (ua * (L1_X2 - L1_X1))
        Intersection.Y = L1_Y1 + (ua * (L1_Y2 - L1_Y1))
        Line_Intersect = True
        Exit Function
    End If

   Line_Intersect = False
End Function

Private Function DirectX_Initialize() As Boolean
    On Error GoTo Error_Handler
    
    Dim Display_Mode As D3DDISPLAYMODE 'Display mode desciption.
    Dim Screen As D3DPRESENT_PARAMETERS 'Backbuffer and viewport description.
    
    Set DX = New DirectX8 'Creates the DirectX object.
    Set D3D = DX.Direct3DCreate() 'Creates the Direct3D object using the DirectX object.
    Set D3DX = New D3DX8
    
    If Fullscreen_Enabled = True Then
    
        'Now that we are working with fullscreen mode, we must set up the
        'screen resolution to switch to, rather than use the default screen
        'resolution.
        
        Display_Mode.Width = Fullscreen_Width
        Display_Mode.Height = Fullscreen_Height
        Display_Mode.Format = COLOR_DEPTH_32_BIT
    
        Screen.Windowed = False 'The app will be in fullscreen mode.
        Screen.BackBufferCount = 1 '1 backbuffer only
        Screen.BackBufferWidth = Display_Mode.Width 'Match the backbuffer width with the display width
        Screen.BackBufferHeight = Display_Mode.Height 'Match the backbuffer height with the display height
        Screen.hDeviceWindow = frmMain.hWnd 'Use frmMain as the device window.
        
    Else
    
        D3D.GetAdapterDisplayMode D3DADAPTER_DEFAULT, Display_Mode 'Use the current display mode that you
                                                                        'are already on. Incase you are confused, I'm
                                                                        'talking about your current screen resolution. ;)
        
        Screen.Windowed = True 'The app will be in windowed mode.
    
    End If
    
    Screen.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC 'Refresh when the monitor does.
    Screen.BackBufferFormat = Display_Mode.Format 'Sets the format that was retrieved into the backbuffer.
    
    'Creates the rendering device with some useful info, along with the info
    'we've already setup for Screen.
    Set Device = D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, frmMain.hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, Screen)
    
    Device.SetVertexShader CUSTOM_VERTEX 'Set the type of vertex shading. (Required)
    
    'Right here will alphablend the polygon
    Device.SetRenderState D3DRS_ALPHABLENDENABLE, True
    
    Device.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_MODULATE
    Device.SetTextureStageState 0, D3DTSS_COLORARG1, D3DTA_TEXTURE
    Device.SetTextureStageState 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE
                   
    Device.SetTextureStageState 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE
    Device.SetTextureStageState 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE
    Device.SetTextureStageState 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE
    
    Device.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCALPHA
    Device.SetRenderState D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA
    Device.SetRenderState D3DRS_BLENDOP, D3DBLENDOP_ADD
    
    'These lines are not needed, but it's nice to be able to filter the
    'textures to make them look nicer.
    
    Device.SetTextureStageState 0, D3DTSS_MINFILTER, D3DTEXF_POINT
    Device.SetTextureStageState 0, D3DTSS_MAGFILTER, D3DTEXF_POINT


    Exit Function
    
Error_Handler:
    
    MsgBox "An error occured while initializing DirectX", vbCritical
    Shutdown
    DirectX_Initialize = False
End Function

Private Sub Create_Spell_Polygon(ByRef Spell As Spell_Type)
    With Spell
        .Vertex_List(0) = Create_Custom_Vertex(.Position.X - .Half_Width, .Position.Y - .Half_Height, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 0, 0)
        .Vertex_List(1) = Create_Custom_Vertex(.Position.X + .Half_Width, .Position.Y - .Half_Height, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 1, 0)
        .Vertex_List(2) = Create_Custom_Vertex(.Position.X - .Half_Width, .Position.Y + .Half_Height, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 0, 1)
        .Vertex_List(3) = Create_Custom_Vertex(.Position.X + .Half_Width, .Position.Y + .Half_Height, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 1, 1)
    End With
End Sub

Private Sub Create_Spell_Cooldown_Polygon(ByRef Spell As Spell_Type, ByVal X As Single, ByVal Y As Single, ByVal Size As Long)
    Dim Offset As Long
    Dim Half_Offset As Long
    Dim Color As Long
    Dim Rotate As Vector
    Dim Clipped As Boolean, Clip_Intersection As Vector
    
    With Spell
        .Clip_Region(0, 0) = Create_Custom_Vertex(X - Size, Y - Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 0, 0)
        .Clip_Region(0, 1) = Create_Custom_Vertex(X + Size, Y - Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 1, 0)
        .Clip_Region(0, 2) = Create_Custom_Vertex(X - Size, Y - (Size / 2), 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 0, 1)
        .Clip_Region(0, 3) = Create_Custom_Vertex(X + Size, Y - (Size / 2), 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 1, 1)
        
        .Clip_Region(1, 0) = Create_Custom_Vertex(X + (Size / 2), Y - Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 0, 0)
        .Clip_Region(1, 1) = Create_Custom_Vertex(X + Size, Y - Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 1, 0)
        .Clip_Region(1, 2) = Create_Custom_Vertex(X + (Size / 2), Y + Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 0, 1)
        .Clip_Region(1, 3) = Create_Custom_Vertex(X + Size, Y + Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 1, 1)
        
        .Clip_Region(2, 0) = Create_Custom_Vertex(X - Size, Y + (Size / 2), 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 0, 0)
        .Clip_Region(2, 1) = Create_Custom_Vertex(X + Size, Y + (Size / 2), 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 1, 0)
        .Clip_Region(2, 2) = Create_Custom_Vertex(X - Size, Y + Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 0, 1)
        .Clip_Region(2, 3) = Create_Custom_Vertex(X + Size, Y + Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 1, 1)
        
        .Clip_Region(3, 0) = Create_Custom_Vertex(X - Size, Y - Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 0, 0)
        .Clip_Region(3, 1) = Create_Custom_Vertex(X - (Size / 2), Y - Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 1, 0)
        .Clip_Region(3, 2) = Create_Custom_Vertex(X - Size, Y + Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 0, 1)
        .Clip_Region(3, 3) = Create_Custom_Vertex(X - (Size / 2), Y + Size, 0, 1, D3DColorRGBA(255, 255, 255, 255), 0, 1, 1)
    
        Offset = Size
        Half_Offset = Offset / 2
        Color = D3DColorRGBA(0, 0, 0, 155)
    
        If .Angle < 90 Then
            Rotate.X = X + (0 * Cos((.Angle) * (PI / 180)) - (-Offset) * Sin((.Angle) * (PI / 180)))
            Rotate.Y = Y + (0 * Sin((.Angle) * (PI / 180)) + (-Offset) * Cos((.Angle) * (PI / 180)))
            If .Angle >= 0 And .Angle < 45 Then
                .Polycount = 8
                Clipped = Line_Intersect(Rotate.X, Rotate.Y, X, Y, .Clip_Region(0, 2).X, .Clip_Region(0, 2).Y, .Clip_Region(0, 3).X, .Clip_Region(0, 3).Y, Clip_Intersection)
                If Clipped = True Then
                    .Vertex_List2(0) = Create_Custom_Vertex(Clip_Intersection.X, Clip_Intersection.Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(1) = Create_Custom_Vertex(X + Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(2) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(3) = Create_Custom_Vertex(X + Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(4) = Create_Custom_Vertex(X + Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(5) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(6) = Create_Custom_Vertex(X + Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(7) = Create_Custom_Vertex(X + Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(8) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(9) = Create_Custom_Vertex(X + Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(10) = Create_Custom_Vertex(X, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(11) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(12) = Create_Custom_Vertex(X, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(13) = Create_Custom_Vertex(X - Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(14) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(15) = Create_Custom_Vertex(X - Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(16) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(17) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(18) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(19) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(20) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(21) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(22) = Create_Custom_Vertex(X, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(23) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                End If
            ElseIf .Angle >= 45 And .Angle < 90 Then
                .Polycount = 7
                Clipped = Line_Intersect(Rotate.X, Rotate.Y, X, Y, .Clip_Region(1, 0).X, .Clip_Region(1, 0).Y, .Clip_Region(1, 2).X, .Clip_Region(1, 2).Y, Clip_Intersection)
                If Clipped = True Then
                    .Vertex_List2(0) = Create_Custom_Vertex(Clip_Intersection.X, Clip_Intersection.Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(1) = Create_Custom_Vertex(X + Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(2) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(3) = Create_Custom_Vertex(X + Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(4) = Create_Custom_Vertex(X + Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(5) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(6) = Create_Custom_Vertex(X + Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(7) = Create_Custom_Vertex(X, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(8) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(9) = Create_Custom_Vertex(X, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(10) = Create_Custom_Vertex(X - Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(11) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(12) = Create_Custom_Vertex(X - Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(13) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(14) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
    
                    .Vertex_List2(15) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(16) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(17) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(18) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(19) = Create_Custom_Vertex(X, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(20) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                End If
            End If
        ElseIf .Angle >= 90 And .Angle < 180 Then
            Rotate.X = X + ((Offset * Cos((.Angle - 90) * (PI / 180))) - (0 * Sin((.Angle - 90) * (PI / 180))))
            Rotate.Y = Y + ((Offset * Sin((.Angle - 90) * (PI / 180))) + (0 * Cos((.Angle - 90) * (PI / 180))))
            If .Angle >= 90 And .Angle < 135 Then
                .Polycount = 6
                Clipped = Line_Intersect(Rotate.X, Rotate.Y, X, Y, .Clip_Region(1, 0).X, .Clip_Region(1, 0).Y, .Clip_Region(1, 2).X, .Clip_Region(1, 2).Y, Clip_Intersection)
                If Clipped = True Then
                    .Vertex_List2(0) = Create_Custom_Vertex(Clip_Intersection.X, Clip_Intersection.Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(1) = Create_Custom_Vertex(X + Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(2) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                
                    .Vertex_List2(3) = Create_Custom_Vertex(X + Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(4) = Create_Custom_Vertex(X, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(5) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(6) = Create_Custom_Vertex(X, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(7) = Create_Custom_Vertex(X - Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(8) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(9) = Create_Custom_Vertex(X - Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(10) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(11) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(12) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(13) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(14) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(15) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(16) = Create_Custom_Vertex(X, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(17) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                End If
            ElseIf .Angle >= 135 And .Angle < 180 Then
                .Polycount = 5
                Clipped = Line_Intersect(Rotate.X, Rotate.Y, X, Y, .Clip_Region(2, 0).X, .Clip_Region(2, 0).Y, .Clip_Region(2, 1).X, .Clip_Region(2, 1).Y, Clip_Intersection)
                If Clipped = True Then
                    .Vertex_List2(0) = Create_Custom_Vertex(Clip_Intersection.X, Clip_Intersection.Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(1) = Create_Custom_Vertex(X, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(2) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(3) = Create_Custom_Vertex(X, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(4) = Create_Custom_Vertex(X - Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(5) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(6) = Create_Custom_Vertex(X - Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(7) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(8) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(9) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(10) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(11) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(12) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(13) = Create_Custom_Vertex(X, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(14) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                End If
            End If
        ElseIf .Angle >= 180 And .Angle <= 270 Then
            Rotate.X = X + ((0 * Cos((.Angle - 180) * (PI / 180))) - (Offset * Sin((.Angle - 180) * (PI / 180))))
            Rotate.Y = Y + ((0 * Sin((.Angle - 180) * (PI / 180))) + (Offset * Cos((.Angle - 180) * (PI / 180))))
            If .Angle >= 180 And .Angle < 225 Then
                .Polycount = 4
                Clipped = Line_Intersect(Rotate.X, Rotate.Y, X, Y, .Clip_Region(2, 0).X, .Clip_Region(2, 0).Y, .Clip_Region(2, 1).X, .Clip_Region(2, 1).Y, Clip_Intersection)
                If Clipped = True Then
                
                    .Vertex_List2(0) = Create_Custom_Vertex(Clip_Intersection.X, Clip_Intersection.Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(1) = Create_Custom_Vertex(X - Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(2) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(3) = Create_Custom_Vertex(X - Half_Offset, Y + Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(4) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(5) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(6) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(7) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(8) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(9) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(10) = Create_Custom_Vertex(X, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(11) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                End If
            ElseIf .Angle >= 225 And .Angle < 270 Then
                .Polycount = 3
                Clipped = Line_Intersect(Rotate.X, Rotate.Y, X, Y, .Clip_Region(3, 1).X, .Clip_Region(3, 1).Y, .Clip_Region(3, 3).X, .Clip_Region(3, 3).Y, Clip_Intersection)
                If Clipped = True Then
                    .Vertex_List2(0) = Create_Custom_Vertex(Clip_Intersection.X, Clip_Intersection.Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(1) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(2) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(3) = Create_Custom_Vertex(X - Half_Offset, Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(4) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(5) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(6) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(7) = Create_Custom_Vertex(X, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(8) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                End If
            End If
        Else
            Rotate.X = X + ((-Offset * Cos((.Angle - 270) * (PI / 180))) - (0 * Sin((.Angle - 270) * (PI / 180))))
            Rotate.Y = Y + ((-Offset * Sin((.Angle - 270) * (PI / 180))) + (0 * Cos((.Angle - 270) * (PI / 180))))
            If .Angle >= 270 And .Angle < 315 Then
                .Polycount = 2
                Clipped = Line_Intersect(Rotate.X, Rotate.Y, X, Y, .Clip_Region(3, 1).X, .Clip_Region(3, 1).Y, .Clip_Region(3, 3).X, .Clip_Region(3, 3).Y, Clip_Intersection)
                If Clipped = True Then
                    .Vertex_List2(0) = Create_Custom_Vertex(Clip_Intersection.X, Clip_Intersection.Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(1) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(2) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                    
                    .Vertex_List2(3) = Create_Custom_Vertex(X - Half_Offset, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(4) = Create_Custom_Vertex(X, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(5) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                End If
            ElseIf .Angle >= 315 And .Angle < 360 Then
                .Polycount = 1
                Clipped = Line_Intersect(Rotate.X, Rotate.Y, X, Y, .Clip_Region(0, 2).X, .Clip_Region(0, 2).Y, .Clip_Region(0, 3).X, .Clip_Region(0, 3).Y, Clip_Intersection)
                If Clipped = True Then
                    .Vertex_List2(0) = Create_Custom_Vertex(Clip_Intersection.X, Clip_Intersection.Y, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(1) = Create_Custom_Vertex(X, Y - Half_Offset, 0, 1, Color, 0, 0, 0)
                    .Vertex_List2(2) = Create_Custom_Vertex(X, Y, 0, 1, Color, 0, 0, 0)
                End If
            End If
        End If
    End With
End Sub

Private Sub Load_Texture(ByRef File_Path As String, ByVal Transparency_Color As Long)
    Set Spell.Texture = D3DX.CreateTextureFromFileEx(Device, _
                                                    File_Path, _
                                                    512, 512, _
                                                    0, _
                                                    0, _
                                                    D3DFMT_A8R8G8B8, _
                                                    D3DPOOL_MANAGED, _
                                                    D3DX_FILTER_POINT, _
                                                    D3DX_FILTER_POINT, _
                                                    Transparency_Color, _
                                                    ByVal 0, _
                                                    ByVal 0)
End Sub

Private Sub Draw_Spell_Polygon(ByRef Spell As Spell_Type)
    With Spell
        Device.SetTexture 0, .Texture
        Device.DrawPrimitiveUP D3DPT_TRIANGLESTRIP, 2, .Vertex_List(0), Len(.Vertex_List(0))
        If .Cooldown_Flag = True Then
            .Cooldown_Time = Get_Elapsed_Time - .Milliseconds
            Create_Spell_Cooldown_Polygon Spell, .Position.X, .Position.Y, .Width
            Device.SetTexture 0, Nothing
            Device.DrawPrimitiveUP D3DPT_TRIANGLELIST, .Polycount, .Vertex_List2(0), Len(.Vertex_List2(0))
            If .Cooldown_Time >= .Cooldown_Amount Then .Cooldown_Time = .Cooldown_Amount
            .Angle = ((.Cooldown_Time / .Cooldown_Amount) * 360)
            If .Angle <= 0 Then .Angle = 0
            If .Angle >= 360 Then
                .Angle = 360
                .Cooldown_Flag = False
            End If
        End If
    End With
End Sub

Public Sub Draw_Text(Text As String, X As Single, Y As Single, Width As Long, Height As Long, Font_Name As String, Font_Size As Long, Color As Long, Optional Font_Bold As Boolean = False, Optional Font_Italic As Boolean = False)
    
    'World of Warcraft uses Bookman Old Style
    
    'NOTE TO SELF - This crashes when you alt tab out and come back in for some reason
    Dim Font As New StdFont
    
    If Device.TestCooperativeLevel = D3D_OK Then
        Font.Name = Font_Name
        Font.Size = Font_Size
        If Font_Bold = True Then Font.Bold = True
        If Font_Italic = True Then Font.Italic = True
        Set Main_Font_Description = Font
        Set Main_Font = D3DX.CreateFont(Device, Main_Font_Description.hFont)
        
        Text_Rect.Left = X + 0
        Text_Rect.Top = Y + 0
        Text_Rect.Right = X + Width
        Text_Rect.bottom = Y + Height
        
        D3DX.DrawText Main_Font, Color, Text, Text_Rect, DT_TOP Or DT_LEFT
    End If
    
End Sub

Private Sub Render()
    Device.Clear 0, ByVal 0, D3DCLEAR_TARGET, D3DColorRGBA(0, 0, 255, 0), 1#, 0
    Device.BeginScene
    Draw_Spell_Polygon Spell
    Draw_Text "Seconds: " & CStr(Spell.Cooldown_Time), 50, 25, 500, 25, "ariel", 8, D3DColorRGBA(255, 255, 255, 255)
    Device.EndScene
    Device.Present ByVal 0, ByVal 0, 0, ByVal 0
End Sub

Private Sub Game_Loop()
    Do While Running = True
        Render
        DoEvents
    Loop
End Sub

Private Sub Shutdown()
    Running = False
    
    'Unload all of the DirectX objects.
    
    Set Spell.Texture = Nothing
    Set D3DX = Nothing
    Set Device = Nothing
    Set D3D = Nothing
    Set DX = Nothing
    
    Unload Me
End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = vbKeyEscape Then
        Shutdown
    End If
End Sub

Private Sub Form_Load()
    If MsgBox("Click Yes to go to full screen (Recommended)", vbQuestion Or vbYesNo, "Options") = vbYes Then Fullscreen_Enabled = True
    
    frmMain.Show
    frmMain.ScaleMode = vbPixels
    
    Fullscreen_Width = 1024
    Fullscreen_Height = 768
    
    DirectX_Initialize
    Setup_Spell
    Running = True
    Game_Loop
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button = 1 Then
        If Spell.Cooldown_Flag = False Then
            Spell.Angle = 0
            Spell.Cooldown_Time = 0
            Spell.Milliseconds = Get_Elapsed_Time
            Spell.Cooldown_Flag = True
        End If
    End If
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Shutdown
End Sub



Edited by Psychopathetica, 26 June 2013 - 09:55 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS