Use of InitBakeTexture and BakeTexture?
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/12/2007 at 05:35, xxxxxxxx wrote:
Hi there!
Sry I haven't answered yet, have been away til just now. I'll look up how I managed to get texture baking working. Actually, exporting the proper UVs (meaning UVs generated by mappings other than UVW mapping) was one of the things to do on my list. I think I asked here in the forums for a way to do that. Will have to look that one up again, too. My exporter has been "asleep" for quite some time due to other stuff I have to do. Anyway: I'll check how I used InitBakeTexture and BakeTexture now and post some code snippets. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/12/2007 at 06:05, xxxxxxxx wrote:
Okay, I looked up how exactly I do my baking, and I suppose it won't help you much, because your main concern seem to be the UV coordinates, which I currently don't care for at all.
My TextureBaker results in a new bitmap file for every unique shader, a single quad with the shader applied gets rendered and saved. I do that by creating a temporary plane object, converting that to a polygon object and using the resulting UVW-tag to bake the texture.
I chose that way because I want to reuse those textures for every object that uses the material without relying on the UV-mapping (the BakeTexture process somehow only writes pixels for actually used areas on the texture, therefore relying on the UV-coordinates of the object).
Furthermore, because I had problems with some of the material channels not getting baked properly (read: the way I wanted them, being just the clean result of the shader, not something with lighting or other "obscure" effects), I copy the requested material channel to a dummy material into the color channel. Pretty much a workaround, but it does the job.
Once I get proper export of UV-coordinates running I should be fine.Here's the code I thought could be interesting for you, which is basically the complete main method of my TextureBaker thread:
> _
> BaseDocument* bakeDoc = NULL;
> BaseContainer bakeSettings;
> TextureTag* tTagToBake;
> Material* matToBake;
>
> // create plane
> BaseContainer planeData;
> planeData.InsData(PRIM_PLANE_SUBW, GeData(1));
> planeData.InsData(PRIM_PLANE_SUBH, GeData(1));
> BaseObject* plane = GeneratePrimitive(g_pDocument, Oplane, planeData,1.0, false, this->Get());
>
> // make plane editable
> ModelingCommandData mcData = ModelingCommandData();
> mcData.doc = g_pDocument;
> mcData.op = plane;
> if(!SendModelingCommand(MCOMMAND_CURRENTSTATETOOBJECT, mcData))
> {
> GeConsoleOut("ERROR: TextureBaker failed creating dummy plane!");
> BaseObject::Free(plane);
> return;
> }
> BaseObject::Free(plane);
> //get editable plane to get UVW set
> BaseObject* vPlane = static_cast<BaseObject*>(mcData.result->GetIndex(0));
> UVWTag* quadUV = (UVWTag* )vPlane->GetTag(Tuvw,0);
> //set texture tag for editable plane
> tTagToBake = TextureTag::Alloc();
> tTagToBake->SetParameter(DescID(TEXTURETAG_PROJECTION), TEXTURETAG_PROJECTION_UVW, 0);
> vPlane->InsertTag(tTagToBake);
>
> g_pDocument->InsertObject(vPlane, 0,0,0);
>
> //iterate through assigned jobs
> for(std::vector<BakerInstruction>::iterator i = this->m_vWorkList.begin(); i != this->m_vWorkList.end(); i++)
> {
> bakeDoc = NULL;
> //creates default settings in bakeSettings
> MakeDefaultBakeSettings(bakeSettings, *i);
>
> if(i->ChannelToBake != CHANNEL_BUMP)
> {
> //create copy of source material with desired channel copied to color channel of result material 'matToBake'
> Material* sourceMat = (Material* )i->TexTag->GetMaterial();
> //clone original material
> matToBake = (Material* )sourceMat->GetClone(0,0);
> //disable all channels
> for(LONG j = CHANNEL_COLOR; j < CHANNEL_NORMAL; j++)
> {
> matToBake->SetChannelState(j, FALSE);
> }
> //enable color channel
> matToBake->SetChannelState(CHANNEL_COLOR, TRUE);
> //set temp material name and copy source channel from source material to color channel of temp material
> matToBake->SetName(i->TexTag->GetMaterial()->GetName()+String("_Copy"));
> CopyChannel(sourceMat, i->ChannelToBake, matToBake, CHANNEL_COLOR);
>
> //add material to document
> g_pDocument->InsertMaterial(matToBake);
> //enable color channel baking
> bakeSettings.SetData(BAKE_TEX_COLOR, GeData(TRUE));
> //set temp material in temp TextureTag
> tTagToBake->SetMaterial(matToBake);
> }
> else
> {
> // enable bumpmap baking
> bakeSettings.SetData(BAKE_TEX_NORMAL, GeData(TRUE));
> // set original material in temp TextureTag
> tTagToBake->SetMaterial(i->TexTag->GetMaterial());
> }
>
>
> bakeDoc = InitBakeTexture(g_pDocument, tTagToBake, quadUV, i->ResultUVs, bakeSettings, &i-;>ResultError, this->Get());
> if(i->ResultError || !bakeDoc)
> {
> GeConsoleOut(i->ToString());
> continue;
> }
>
> //create multipass bitmap (needed for bumpmap baking)
> MultipassBitmap* resultBitmap = MultipassBitmap::Alloc(i->TargetResX, i->TargetResY, MODE_RGB);
>
> i->ResultError = BakeTexture(bakeDoc, bakeSettings, resultBitmap, this->Get(), NULL, NULL);
> if(i->ResultError)
> {
> GeConsoleOut(i->ToString());
> continue;
> }
> //get valid version of materialname
> String matName = NameManager::GetInstance()->ReformatString(i->ExpMat->GetName());
> i->ResultFile = Filename(matName+String("_")+TexChannelToString(i->ChannelToBake));
> i->ResultFile.SetSuffix("tif");
>
> switch(i->ChannelToBake)
> {
> case CHANNEL_COLOR: i->ExpMat->SetDiffuseTex(i->ResultFile); break;
> case CHANNEL_TRANSPARENCY: i->ExpMat->SetTransparencyTex(i->ResultFile); break;
> case CHANNEL_SPECULARCOLOR: i->ExpMat->SetSpecTex(i->ResultFile); break;
> case CHANNEL_BUMP: i->ExpMat->SetBumpTex(i->ResultFile); break;
> default: GeConsoleOut("Can't set new filename for exportmaterial"); break;
> }
>
> GeConsoleOut(i->ToString());
> if(!resultBitmap->Save(Filename(i->TargetFolder.GetString()+String("\")+i->ResultFile.GetFileString()), FILTER_TIF, 0, 0))
> {
> GeConsoleOut("ERROR: Failed writing texture to disc!");
> }
>
> MultipassBitmap::Free(resultBitmap);
> if(i->ChannelToBake != CHANNEL_BUMP)
> {
> matToBake->Remove();
> Material::Free(matToBake);
> }
> BaseDocument::Free(bakeDoc);
> }
>
> //clean up
> tTagToBake->Remove();
> TextureTag::Free(tTagToBake);
> quadUV = NULL;
> vPlane->Remove();
> BaseObject::Free(vPlane);
> vPlane = NULL;
>
> bakeSettings.FlushAll();
> _That 'BakerInstruction' is a struct I defined for this job. It contains everything needed to bake the material channel and also stores the results from a baking process. The names of its members should be pretty self-explanatory.
I could also post the 'MakeDefaultBakeSettings(...)' and 'CopyChannel' functions, but they just do what their names imply, although copying the channel of a material to another was a bit tricky.
If you got any questions, feel free to ask.
Hope this helps. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/12/2007 at 09:35, xxxxxxxx wrote:
Hey Match,
Thanks for the info! My forum search was just on the titles, so I only saw this thread... but later (just before going to sleep) I did a search on the body and saw your other/later thread where you seemed to get some of the above working (but ultimately needed to switch to MultipassBitmap). Thanks for the updated code snippet. I may do something similar with the textures in the future, so this will come in handy.
I still have some questions relative to the UV-baking, but I guess I'll do some experiments while I wait for more definative answers to my above questions.
Thanks again,
Keith -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/12/2007 at 18:28, xxxxxxxx wrote:
No problem.
It is quite possible that I get some time to work on that exporter some more in the next few days. So if you find out something about exporting the proper UV coordinates (I'm guessing you're also wanting to export the ones used for rendering by C4D?), please keep me updated. If I find something before that, I'll post my findings.Good luck!
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/12/2007 at 20:49, xxxxxxxx wrote:
I tried some things out today and so far, no joy. I'm currently working with the R9.1 SDK, but it looks like there were substantial changes made by R9.6, so later versions may work (or work differently).
The current problem I'm seeing is that InitBakeTexture() is not filling in the destUVTag under any circumstances that I've tried so far. I had the thought that maybe BakeTexture() is actually supposed to alter it, but so far, it's not either.
The R9.1 c4d_tools.h file has the following comments.../* textag : the texture tag you want to bake (must be assigned to an object) data : bake parameters - see below bmp : the destination bitmap th : the current thread texuvw : must be valid, if UVW pojection is selected in the tag, ignored otherwise destuvw : if not NULL, the current projection is transformed into the uvw tag */
...but neither function is altering the destuvw tag as expected.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/12/2007 at 11:04, xxxxxxxx wrote:
Ok, I'm giving up on InitBakeTexture() and BakeTexture() for getting the UVs fixed... I'm just not having an luck getting them to work at all.
Instead, I've developed a work-around by using GenerateUVW() (c4d_baseobject.h utility function). It seems to handle the various Projection types and texture axis adjustments for me, but I still have to jump through some hoops to handle the Offset/Length/Tiles values of the Texture Tag, as well as account for the fact that there may be multiple Texture Tags on a mesh, each with different Projection types, but restricted to some subset of polygons.
Fortunately, my exporter pre-parsing has already determined which texture tags affect which polygons and set up structures for easy access to everything. Here's my current code (it uses many internal structures, but you should be able to follow along)...//------------------------------------------------------------------------------------------------------ //****************************************************************************************************** // BakeUVs() - create a consolidated and uv-mapping resolved UVWTag // // Because a mesh can have multiple Texture Tags on it (usually restricted to a subset of polygons of // that mesh), with each potentially set to some different Projection type, this routine will loop // through all the various Texture Tags on the mesh and create a consolidated UVWTag for the export // code to use. It also resolves all Offset and Scaling (tiling) adjustments of those tags. //****************************************************************************************************** //------------------------------------------------------------------------------------------------------ Bool ObjSaver::BakeUVs(PolygonObject *op, UVWTag *pDstUVs) { Matrix mg = op->GetMg(); DWORD i,j; // start by grabbing the current UVWTag UVWTag *pSrcUVs = (UVWTag* )(op->GetTag(Tuvw, 0)); if( !pSrcUVs ) return false; // create a working sand-box UVWTag *pWrkUVs = UVWTag::Alloc(m_numFaces); if( !pWrkUVs ) return false; // before we start, set the default state of caller's UVWTag to src for(i=0; i<m_numFaces; i++) pDstUVs->Cpy(i, pSrcUVs, i); objMaterial *pMat = &m_pMats[0]; for(i=0; i<m_numMaterials; i++) { // ================================================================================== // if we have a pointer to a TextureTag for this material, we may need to adjust the // uv values for the polygons assigned to it. If we don't have a pointer, then the // default values filled in above should be good. // ================================================================================== if( pMat->pTex ) { // ================================================================================== // if the texture tag projection is set to something besides UVW, then GenerateUVW() // will resolve it into UVW format. This operation also includes any texture matrix // adjustments, but does not include the offset and tiling values of the tag. If the // call returns NULL, then it's already set to UVW, so we just copy the orginal UVs // into our working tag. // ================================================================================== UVWTag *pGenUVs = GenerateUVW(op, mg, pMat->pTex, mg, NULL); if( pGenUVs ) { for(i=0; i<m_numFaces; i++) pWrkUVs->Cpy(i, pGenUVs, i); UVWTag::Free(pGenUVs); } else { for(i=0; i<m_numFaces; i++) pWrkUVs->Cpy(i, pSrcUVs, i); } // ================================================================================== // next we need to get the offset and tiling (scaling) values from the tag... // ================================================================================== Real uScale = 1.0; Real vScale = 1.0; BaseContainer tagvals = pMat->pTex->GetData(); Real uOffset = -tagvals.GetReal(TEXTURETAG_OFFSETX); Real vOffset = -tagvals.GetReal(TEXTURETAG_OFFSETY); Real lenX = tagvals.GetReal(TEXTURETAG_LENGTHX); Real lenY = tagvals.GetReal(TEXTURETAG_LENGTHY); if( lenX ) uScale /= lenX; if( lenY ) vScale /= lenY; // ================================================================================== // and finally, we loop through all the polygons assigned to this particular Texture // Tag and apply any offset and scaling, transfering the resulting UVs into the caller's // UVWTag // ================================================================================== for(j=0; j<pMat->numFaces; j++) { objFacet *pFacet = &m_pFaces[pMat->pFaceIndices[j]]; // get working uv values UVWStruct uvw = pWrkUVs->Get(pFacet->iPolyNdx); // apply offset and scaling uvw.a.x = (uvw.a.x * uScale) + uOffset; uvw.b.x = (uvw.b.x * uScale) + uOffset; uvw.c.x = (uvw.c.x * uScale) + uOffset; uvw.d.x = (uvw.d.x * uScale) + uOffset; uvw.a.y = (uvw.a.y * vScale) + vOffset; uvw.b.y = (uvw.b.y * vScale) + vOffset; uvw.c.y = (uvw.c.y * vScale) + vOffset; uvw.d.y = (uvw.d.y * vScale) + vOffset; // store adjusted values in caller's UVWTag pDstUVs->Set(pFacet->iPolyNdx, uvw); } } pMat++; } UVWTag::Free(pWrkUVs); return true; }
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/12/2007 at 18:09, xxxxxxxx wrote:
wow, that looks much simpler than I was afraid of Thx for posting this, would have taken me quite a while to figure that out, I guess.
I have something along the lines of your TextureTag->Polygons relation already implemented (I'm writing an Ogre export, so I have to work with submeshes anyway for multiple materials on one object), so I should be able to use that code 1:1 more or less. Thx again! -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 14/12/2007 at 18:46, xxxxxxxx wrote:
Sure thing... after a bit of testing, it looks like it may not be fully cooked yet, but I haven't had a chance to look into it again yet. If I find/fix anything, I'll report back.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 15/12/2007 at 02:05, xxxxxxxx wrote:
Ahh.. ok, too much cutting and pasting... change this:
if( pGenUVs ) { for(i=0; i<m_numFaces; i++) pWrkUVs->Cpy(i, pGenUVs, i); UVWTag::Free(pGenUVs); } else { for(i=0; i<m_numFaces; i++) pWrkUVs->Cpy(i, pSrcUVs, i); }
...to this...
if( pGenUVs ) { for(j=0; j<m_numFaces; j++) pWrkUVs->Cpy(j, pGenUVs, j); UVWTag::Free(pGenUVs); } else { for(j=0; j<m_numFaces; j++) pWrkUVs->Cpy(j, pSrcUVs, j); }
...replace the 'i' variable with 'j'. The original code above was re-using i inside an i loop, so it was blowing out of the outer loop early :).
Aside from that typo, it looks like it's working now (barring any misunderstanding on my part about the order the math is applied). -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 22/12/2007 at 04:02, xxxxxxxx wrote:
I implemented UV baking two days ago. Thx for your help. Although the structure I'm working in didn't allow to just copy & paste your method especially the pointer to GenerateUVW(...) was extremely helpful.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 22/12/2007 at 09:09, xxxxxxxx wrote:
Cool.. btw, you don;t happen to know where I can find the DTS file format specs (Torque engine) do you?
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 22/12/2007 at 13:49, xxxxxxxx wrote:
No, sorry. I'm exporting for Ogre, the currently available exporter discards phong breaks for example, and I'm implementing an exporter for complete scenes. So, I've only looked into Ogre's XML file format for meshes, haven't looked into Torque at all.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 04/12/2008 at 09:41, xxxxxxxx wrote:
Hey Match,
Hehe... this is kinda funny... I just looked up this thread for someone else and re-read it to refresh my memory. I just saw your post above about exporting for Ogre... guess what I've been working on recently?
Frankly, it never registered with me that you were working on an Ogre exporter when you wrote that a year ago, because I didn't even know what Ogre was until June of this year (I was surprised just now to see Ogre mentioned in your post above).
At that time (June 2008) I got interested/curious and tried out the existing exporter. It's broke in more than one way... I started with the thought of just fixing a few bugs for him, but as I was doing that, I kept running into more and more issues and finally scrapped that source and started from scratch (well, re-working and re-using a lot of my own pre-existing code from Riptide).
I have the .mesh part mostly working and done now, but am still working on the .skeleton file (specifically the animation export part).