April 26, 2024, 01:48:29 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


C3DMesh::CreateBox Question

Started by J B Wood (Zumwalt), December 30, 2006, 12:37:52 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

J B Wood (Zumwalt)

Been playing around with this to come up with a decent sky object.
Can the box have more than 1 texture applied to the box?
I have 6 textures that I want to apply to the box, or do I have to create 6 flat planes and have them orientated so that they are visible to anything on a certain side of them?

Ionic Wind Support Team

The CreateBox creates a simple 1 textured box.  There is an example of multi texturing included with the installation.  Or you can do cube mapping to create a 6 sided texture that is wrapped around the box.

Paul.
Ionic Wind Support Team

Bruce Peaslee

Although I am listed as a Moderator for this forum, I know nothing about 3D graphics. Can anyone suggest a primer on the subject?
Bruce Peaslee
"Born too loose."
iTired (There's a nap for that.)
Well, I headed for Las Vegas
Only made it out to Needles

J B Wood (Zumwalt)

Whats the name of the example Paul?
I am not finding one in the d3d folder.

Ionic Wind Support Team

Ionic Wind Support Team

Ionic Wind Support Team

Which , oddly enough, wasn't included with the installation.   ::)


//structure used in our restore callback
struct RestObj
{
C3DMesh *pSphere;
C3DMesh *pRoom;
C3DScreen *pScreen;
}
#define DegToRad 0.01745329251995
#define smoothing_frames 10
//Arrow keys to move camera.
//PgUp/PgDn to pan up and down.
//Z and X to rotate on Z axis.

import int QueryPerformanceFrequency(int64 *lpFrequency);
import int QueryPerformanceCounter(int64 *lpPerformanceCount);

global sub main()
{
C3DScreen s;
C3DCamera c;
C3DMesh *room;
C3DMesh sphere;
C3DObject scene;
CDirectInput di;
double fTarget=75.0,fAdjust = 1.0;
int64 freq;
QueryPerformanceFrequency(freq);
double dfreq = freq;

//s.CreateFullScreen(800,600,32,true);
s.CreateWindowed(0,0,800,600,AWS_CAPTION|AWS_VISIBLE|AWS_SIZE|AWS_CENTERED,0,"3D Test - ESC exits",NULL,false);

di.Init(s);
c.Create(s);
c.Position(0,0,-8);
c.Orient(0,0,1,0,1,0);
c.SetBackPlane(500);

s.Clear(RGBA(0,0,0,255));
s.BeginScene(c);
s.RenderText(0,10,"Loading objects...",RGBA(255,255,0,255));
s.RenderScene();

room = CreateRoom(s,20,20,50,null);

sphere.CreateSphere(s,30f,2f,false);
sphere.EnableLighting(false);
sphere.CreateCubeTexture(0,256,"cubemap");
//render a static cubemap
for( x = 0; x < 6; x++)
{
sphere.BeginRenderCubeTexture(0,x,0,0,0);
s.Clear(RGBA(0,0,255,255));
room->Draw();
sphere.EndRenderCubeTexture();
}

//setup the restore callback
RestObj res;
res.pScreen = s;
res.pRoom = room;
res.pSphere = sphere;
s.SetRestoreCallback(&rebuild_room,res);

scene.CreateScene(s);
scene.AddChild(room);
scene.AddChild(sphere);

int fps = 0;
int smoothing = smoothing_frames;
double accumtime = 0.0;
double startTime = 0.0;
int64 iStartTime;
do
{
QueryPerformanceCounter(iStartTime);
startTime = iStartTime;
//check for keys and move camera accordingly
IF di.KeyDown(DIK_UP)
c.Move(0.0f,.25 * fAdjust);
IF di.KeyDown(DIK_DOWN)
c.Move(0.0f,-.25* fAdjust);
IF di.KeyDown(DIK_RIGHT)
c.Rotate(1.0*DegToRad*fAdjust,0,0);
IF di.KeyDown(DIK_LEFT)
c.Rotate(-1.0*DegToRad*fAdjust,0,0);
IF di.KeyDown(DIK_Z)
c.Rotate(0,0,-1.0*DegToRad*fAdjust);
IF di.KeyDown(DIK_X)
c.Rotate(0,0,1.0*DegToRad*fAdjust);
IF di.KeyDown(DIK_PRIOR)
c.Rotate(0,-1.0*DegToRad*fAdjust,0);
IF di.KeyDown(DIK_NEXT)
c.Rotate(0,1.0*DegToRad*fAdjust,0);
IF di.KeyDown(DIK_R)
c.LookAt(0,0,0);

s.Clear(RGBA(0,0,0,255));
s.BeginScene(c);
scene.Draw();
s.RenderText(0,10,"FPS:"+NumToStr(fps) + " " + NumToStr(fAdjust,10),RGBA(255,255,0,255));
s.RenderText(0,30,"Use arrow keys to move around",RGBA(255,255,0,255));
fps = s.RenderScene();

QueryPerformanceCounter(iStartTime);
accumtime += ((iStartTime - startTime) / dfreq) * fTarget;
smoothing--;
if(!smoothing)
{
fAdjust = accumtime / smoothing_frames;
accumtime = 0.0;
smoothing = smoothing_frames;
}


}until di.KeyDown(DIK_ESCAPE);
Scene.Free();
}

sub CreateRoom(C3DScreen *pScreen,float width, float height,float depth,C3DMesh *restore = NULL),C3DMesh *
{
C3DMesh *pRet,*pass2;
if(!restore)
pRet = new(C3DMesh,1)
else
pRet = restore;
pass2 = new(C3DMesh,1);
int i,j,k,index;
//create a box to copy.  Make it an 'inside' cube
C3DMesh temp;
temp.CreateBox(pScreen,width,height,depth,true);
numVertices = temp.GetVertexCount();
numIndices = temp.GetIndexCount();
if(restore)
pRet->Free();
//create the mesh with a vertex format that allows position, a diffuse color and a normal vector + two textures.
pRet->CreateMesh(pScreen,numVertices,numIndices,D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2 );
//create the pass2 mesh. It only needs one texture and will be temporary
pass2->CreateMesh(pScreen,numVertices,numIndices,D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1 );
pRet->AddChild(pass2);
//lock the buffers and copy the data
VERTEX2TEXTURE *pVB;
VERTEX1TEXTURE *pVBPass2,*pVBOld;
word *pIB,*pIBOld,*pIBPass2;
pVB = pRet->LockVertexBuffer();
pVBOld = temp.LockVertexBuffer();
pVBPass2 = pass2->LockVertexBuffer();
pIB = pRet->LockIndexBuffer();
pIBOld = temp.LockIndexBuffer();
pIBPass2 = pass2->LockIndexBuffer();

//copy the vertices and 1st texture coordinates.  Duplicate the 2nd
for( j=0; j < numVertices; j++)
{
*pVB[j].position = *pVBOld[j].position;
*pVB[j].normal = *pVBOld[j].normal;
*pVB[j].diffuseColor = *pVBOld[j].diffuseColor;
*pVB[j].texCoords[0] = *pVBOld[j].texCoords[0];
*pVB[j].texCoords[1] = *pVBOld[j].texCoords[0];

*pVBPass2[j].position = *pVBOld[j].position;
*pVBPass2[j].normal = *pVBOld[j].normal;
*pVBPass2[j].diffuseColor = *pVBOld[j].diffuseColor;
*pVBPass2[j].texCoords[0] = *pVBOld[j].texCoords[0];
}

//copy the indices
FOR( k=0; k < numIndices; k++)
{
*pIB[k] = *pIBOld[k];
*pIBPass2[k] = *pIBOld[k];
}

//now rewrite the diffuse colors based on the side
for( i=0; i < 6; i++)//the sides
{
for( j = 0; j < 3; j++)//num of triangles per row
{
for( k =0; k < 3;k++)// num of triangles per column
{
index = i * 3 * 3 + j * 3 + k;
SELECT i
{
CASE 0:
//ceiling
*pVB[index].diffuseColor = RGBA(255,255,255,0);
*pVBPass2[index].diffuseColor = RGBA(0,0,0,0);
CASE 1:
//floor using pass2
*pVBPass2[index].diffuseColor = RGBA(255,255,255,255);
*pVB[index].diffuseColor = 0;
default:
//walls
*pVB[index].diffuseColor = RGBA(0,0,0,255);
*pVBPass2[index].diffuseColor = RGBA(0,0,0,0);
}
}
}
}

//unlock the buffers
pRet->UnlockIndexBuffer();
pRet->UnlockVertexBuffer();
temp.UnlockIndexBuffer();
temp.UnlockVertexBuffer();
pass2->UnlockIndexBuffer();
pass2->UnlockVertexBuffer();

temp.Free();

pRet->SetCulling(CULL_CW);
pass2->SetCulling(CULL_CW);

pRet->LoadTexture(0,GetStartPath() + "media\\tile3.tga",0);
pRet->LoadTexture(1,GetStartPath() + "media\\wall11.jpg",0);
pass2->LoadTexture(0,GetStartPath() + "media\\floor11.jpg",0);
//make it visible
pRet->SetVisible(TRUE);
pass2->SetVisible(TRUE);
pRet->RecalcBoundingBox();
pass2->RecalcBoundingBox();

//since we are using diffuse and alpha for texture blending turn of lighting for the objects
pRet->EnableLighting(FALSE);
pass2->EnableLighting(FALSE);

//setup the pipeline
//PASS 1
//Stage 0 - Color - Modulate the texture with diffuse
//This results in : stage0_color_result = rgb(diffuse)*t1
pRet->SetColorArg1(0,D3DTA_DIFFUSE);
pRet->SetColorArg2(0,D3DTA_TEXTURE);
pRet->SetColorOperation(0,D3DTOP_MODULATE);
//Stage 0 - Alpha - Use diffuse alpha
//This results in : stage0_alpha_result = a
pRet->SetAlphaArg1(0, D3DTA_DIFFUSE);
pRet->SetAlphaOperation(0, D3DTOP_SELECTARG1);
//Stage 1- Color - Modulate alpha add color
//This results in : pass1_color_result = stage0_color_result + stage0_alpha_result*t2
//which is : pass1_color_result = rgb(diffuse)*t1 + a(diffuse)*t2
pRet->SetColorArg1(1,D3DTA_CURRENT);
pRet->SetColorArg2(1,D3DTA_TEXTURE);
pRet->SetColorOperation(1,D3DTOP_MODULATEALPHA_ADDCOLOR);
//This results in : pass1_alpha_result = tile2_alpha
pRet->SetAlphaArg1(1, D3DTA_TEXTURE);
pRet->SetAlphaOperation(1, D3DTOP_SELECTARG1);

//PASS 2
pass2->SetColorArg1(0,D3DTA_DIFFUSE);
pass2->SetColorArg2(0,D3DTA_TEXTURE);
pass2->SetColorOperation(0,D3DTOP_MODULATE);

pass2->SetAlphaArg1(0, D3DTA_DIFFUSE);
pass2->SetAlphaOperation(0, D3DTOP_SELECTARG1);

pass2->EnableAlpha(TRUE);
pass2->SetAlphaOp(D3DBLENDOP_MAX);
pass2->SetAlphaSource(D3DBLEND_SRCALPHA);
pass2->SetAlphaDest(D3DBLEND_SRCALPHA);

//delete our local pass2 object.  The internal mesh used by the engine will
//still be there as a child of our room mesh. It will be freed when the parent mesh is freed.
delete pass2;
return pRet;
}

/*
this function is called by the engine when the d3d device has been reset and restored
Usually during an ALT_TAB switch from fullscreen to the desktop. At this point our vertex
and index buffer were released and need to be recreated.

*/
sub rebuild_room(void *pParam)
{
IF pParam
{
CreateRoom(*(RestObj)pParam.pScreen,20,20,50,*(RestObj)pParam.pRoom);
//cubemaps are not automatically restored like normal textures.  So we need to recreate it also.
*(RestObj)pParam.pSphere->CreateCubeTexture(0,256,"cubemap");
for( x = 0;x <6;x++)
{
*(RestObj)pParam.pSphere->BeginRenderCubeTexture(0,x,0,0,0);
*(RestObj)pParam.pScreen->Clear(RGBA(0,0,255,255));
*(RestObj)pParam.pRoom->Draw();
*(RestObj)pParam.pSphere->EndRenderCubeTexture();
}
}
return;
}
Ionic Wind Support Team

J B Wood (Zumwalt)

December 31, 2006, 09:40:33 AM #6 Last Edit: December 31, 2006, 10:12:39 AM by Jonathan (zumwalt) Wood
Thanks :)
Going to play with this today, hopefully I can 'invert' changing the binside to true and have it flipped the way I want it.
edit:

Ok, thats impressive!
Floor is doing something funky though, floor 'fractures' into black squares.
Anyway, this example rocks, going to take a hard look at it.

Ok Paul, I see in the code where the box is being created and manipulated, but I do not see how you are applying the specific textures to which face of the cube. I even see where you are loading them. I have 6 textures instead of 3, what lines are you applying the specific texture to which side of the cube?

Ionic Wind Support Team

The textures are loaded in the CreateRoom subroutine.  There are actually two cubes superimposed on each other.  I am using the fixed function pipeline to modulate texture colors using the alpha value and diffuse colors.  Which is why lighting is turned off for the cube.

It is the same technique the landscape object uses internally.

As for the floor tearing...I know and it only happens with certain video cards when superimposing two identically sized objects at the same location in 3D space.  Since it is card related I never have been able to duplicate it on my machine. 

The simpler way to do this, although a bit harder to manage, is to use the CreateRectangle method of C3DMesh.  Create six rectangles as the children of a transform object and position them as a cube.  Each rectangle could have its own texture then and allow lighting.

Paul.
Ionic Wind Support Team

J B Wood (Zumwalt)

Thanks, I'll look into the rectangle and see about using that instead.