View Full Version : Vertex shaders and pixel shaders for real-time rendering?

04 April 2002, 09:47 PM
Other than the Nvidia/developer site does anyone know some other sites for vertex and pixel shaders.....Also any implimentation techniques for maya?

04 April 2002, 06:01 AM
Why is it when the complicated questions arise, no one feels like giving a shot at finding a solution....i.e implimentation of vertex shaders in maya... or anything they know about them.

04 April 2002, 01:42 PM
Well, I read your question when you first posted it, and I looked all over the internet for an answer, but I'm afraid I couldn't find any info :(
And especially as I do not know Maya very well yet, ummm, I was sure if there was a way of using them within Maya. I must admit, I don't really know all that much about vertex and pixels shaders, as I've never had any use for them, so I'm afraid I can't help (although I did try)

04 April 2002, 07:46 PM
Thanks ,'s the problem... on the nvidia site Developers section/how to use dcc vertex shaders with software / link to aliaswavefront site/ then there is a plugin to impliment hardware shaders..yet,when I dl it it has *cpp and *.dpp files...It say to compile these with VisualC++ (I can do mel but I really suck at C++)even though they are so simalar)....My question compile to WHat? then where do I go from there.....? I really want to get these real-time shaders working...When I was at Siggraph last year watching the Final Fantasy/quadro dcc demo ,seeing them render ff out in realtime can really make you cream your pants!..... I think this is really important to figure out since everybody on the whole channel was geeked about the quadro 4 coming out...and this is one of its major features..everybody can benifit from this.

04 April 2002, 07:51 PM
if you post a link id be willing to give it a try. ive been deving in vc++ for a few years now.

04 April 2002, 11:20 AM
here is the link to the alias site,which has the vc++ files..... the files are under" hardware shader examples"

this is the link to the nvidia site...

just for ref.

Thanks Much...Nick

04 April 2002, 11:23 AM
The developers site s all the references on how to implement real time rendering and techniques .....this is the basics on how final fantasy was rendered in real time...... I think if we build a learning base on figuring this out it will be useful fro newbies later on.

04 April 2002, 05:32 AM
im afraid i might not be able to help you out nick.

it looks like you need a maya plugin sdk to create maya plugins. theres references to header files in a maya/include directory which apparently dont come with maya 4 ple, which is the version i have.

ive searched the alias/wavefront website you listed (thanks for the links) but have come up emtpy so far. im trying a broader search now...

04 April 2002, 07:39 PM
yea, I kinda ran across that last night...I found the Mstring.h in the maya/plugins/ directory
but Im confused on how to link the project to be able to use that file.. Also,Im confused on the whole compile/build options....... when compiling I figure Im just taking all the code and putting it together as one thing. but then what is the building?

(side note:when it says compile it to a .mll , do I have to specify the final product as a .mll or does the .cpp automatically make that file from being compiled?)

04 April 2002, 09:50 PM
jeez. looks like they wanted 1/4 mill when the sdk first came out :)

anyway, cant do it myself but i certainly can help you with the build.

assuming you have vc++ installed, go to the directory that you unzipped the file to. in the devkit/plug-ins directory should be 3 project workspace files. 2 of them are specifc to nvidia and have _NV20 at the end of their filenames.

double-clicking on one of these should bring up the project files necesary to build the corresponding mll. under vc++s build menu you should see a "Build hwDecalBumpShaded_NV20.mll" menu item. thats what you use to build the mll (its basically a renamed dll.)

the only thing you should have to do before you do this is set up the include and library paths to the nvidia and may sdks. this is done in the Tools->Options->Directories tab.

select the "Include files" item in the "Show directories for" drop down, then see if you have an nvidia (and maya) include path in the "Directories" list box. the nvidia include path would be (assuming you use the defaults on its install) "c:\program files\nvidia corporation\nvidia opengl sdk\include\glh".

if you dont, create a new entry using the "New" button and just type it in, or to be safer, browse to the diretory using the "..." button on the right of the newly added listbox row.

once youve done this, do the same thing for the lib files. for now you can just choose the release lib directory as where to find the appropriate lib files. later on, if you want to do some runtime debugging, you would need to add the debug diretory as well (or use a different method to separate the two which i will not explain here :) )

remember that you may need to do this for the maya include and lib directorys as well, if it wasnt done for you during the maya install or you have not already done this yourself. you also may not need to do this if you unzipped the plugin example files into a special maya plugin project directory (sorry cant help wth this.)

if the build is successful, your proejct diretory should contain a new directory called releasedebug and in that directory should be the mll file you just built. move that into the appropriate maya directory and then fire up maya and it should show up as a new plugin available for use.

assumging all of that works, you could then go back and build just a release verson of the plugin. do that by going into the "Set Active Project Configuraiton" dialog, available from the Build->Set Active Configuration menu item. select the "Release" item in the listbox, click OK, then rebuild (F7). or you can use the Build->Batch Build menu item option to build all of the versions at once if you want.

hope this helps. ill check back later to see how things went for ya. good luck. :)

05 May 2002, 08:22 AM
:annoyed: Im tearing my hair out......
I get everything to start building...but then I get a fatal error C1030 can find MImage.h

this file is not in the mayasdk or nvidia sdk

05 May 2002, 04:32 PM

dont know if its the most recent, but it looks right

05 May 2002, 06:19 PM
Interested to read this thread. I've been trying to find similar information about the implimentation of real time shaders in Max.

For what it's worth Max ships with a harware shader on the disc. To activate it configure these paths:
Add \3dsmax4\plugins\HardwareShaders\ to your Plug-ins path list
Add \3dsmax4\plugins\HardwareShaders\ to your Bitmaps path list

Launch Max again with the drivers set to Direct 3D and 'Pixel Shader' now appears in the material editor. The shader is a cubic mapped reflection which will work on older Geforce cards.

I down loaded the Nvidia 'Effects Browser' software but couldn't 'plug' any of the shaders into Max. Contacting our re-seller we were given a few shaders which are nvidia shaders recompiled by Discreet to work in Max. These are a Reflection+Bump, a fur, a cartoon and a membrane(falloff) shader. All seem to work pretty well.

I'm not very techy, basically what I've been trying to find is an artists tool for developing Xbox shaders (nvidia) that can be used on an Nvidia equiped PC running Max.

Lithtech seem to be the only people developing an artists shader generation tool as part of their total games dev package. If anyone out there has any more information/ideas on this topic I'd love to hear them.

05 May 2002, 07:26 PM
foung that Mimage.h at that site before I wrote the last reply. give me a couple of days and maybe I can figgure it out.... I am wondering is the mimage.h class searching for an image file or is this a problem with my directories....I place it in a folder and link the directory to it but it says it cant find it.. the MImage.h is linked to the Mtexture.cpp

05 May 2002, 07:28 PM
This also raises another question? when we do get this working... how will we implement the *.h files from the Nvidia shaders to a final shader or are they ready to go as is.

05 May 2002, 04:51 PM
Eventhough you linked the .h file in your project, you also have to put in a <include *.h> preprocessing directive in your main .cpp file (or whatever file is looking for this class) so that it knows where these are.

Once this is compiled you will have a plugin file that you can load into the plugins directory of your software package that will give you the functionality of the compiled code.

Hope this helps.

05 May 2002, 07:14 AM
--------------------Configuration: hwUnlitShader - Win32 ReleaseDebug--------------------
C:\AW\Maya4.0\nvidia\HWexamples\devkit\plug-ins\MTexture.cpp(49) : error C2065: 'MImage' : undeclared identifier
C:\AW\Maya4.0\nvidia\HWexamples\devkit\plug-ins\MTexture.cpp(49) : error C2146: syntax error : missing ';' before identifier 'image'
C:\AW\Maya4.0\nvidia\HWexamples\devkit\plug-ins\MTexture.cpp(49) : error C2065: 'image' : undeclared identifier
C:\AW\Maya4.0\nvidia\HWexamples\devkit\plug-ins\MTexture.cpp(50) : error C2228: left of '.readFromFile' must have class/struct/union type
C:\AW\Maya4.0\nvidia\HWexamples\devkit\plug-ins\MTexture.cpp(79) : error C2228: left of '.getSize' must have class/struct/union type
C:\AW\Maya4.0\nvidia\HWexamples\devkit\plug-ins\MTexture.cpp(102) : error C2228: left of '.resize' must have class/struct/union type
C:\AW\Maya4.0\nvidia\HWexamples\devkit\plug-ins\MTexture.cpp(119) : error C2228: left of '.pixels' must have class/struct/union type
Generating Code...
Error executing cl.exe.

hwUnlitShader.mll - 7 error(s), 0 warning(s)

here the code
// MTexture.cpp
// Copyright (C) 2000-2001 Alias|Wavefront, a division of Silicon Graphics Limited.
// The information in this file is provided for the exclusive use of the
// licensees of Alias|Wavefront. Such users have the right to use, modify,
// and incorporate this code into other products for purposes authorized
// by the Alias|Wavefront license agreement, without fee.

// DESCRIPTION: Texture object, that can be mipmapped. Eventually,
// this class will likely end up in the Maya API.
// AUTHOR: Christian Laforte

#include "MTexture.h"
#include <Maya/MStatus.h>
#include <Maya/MGlobal.h>
#include "MNormalMapConverter.h"

// Initialize everything
m_levels = NULL;
m_numLevels = 0;

#define MIN(x, y) (((x) < (y)) ? (x) : (y) )
#define MAX(x, y) (((x) > (y)) ? (x) : (y) )

bool MTexture::load(MString filename,
MTexture::Type type,
bool mipmapped /* = true */,
GLenum target /* = GL_TEXTURE_2D */)
unsigned int i; // used as a temporary index.

MImage image;
MStatus stat = image.readFromFile(filename);
if (!stat)
MGlobal::displayWarning("In MTexture::load(), file not found: \"" + filename + "\".");
return false;

// Store the type of texture, and derive other parameters.
// (Depth is assumed to be 4 bytes per pixel RGBA.
// MImage always returns that pixel format anyway.)
m_type = type;
if ( (m_type == RGBA) || (m_type == NMAP) )
m_internalFormat = GL_RGBA8;
m_format = GL_RGBA;
m_componentFormat = GL_UNSIGNED_BYTE;
else if (m_type == HILO)
m_internalFormat = GL_SIGNED_HILO_NV;
m_format = GL_HILO_NV;
m_componentFormat = GL_SHORT;
else assert(0);

// Get the dimension of the texture.
stat = image.getSize(m_width, m_height);
m_mipmapped = mipmapped;

unsigned int maxWidthLevels = highestPowerOf2(m_width);
unsigned int maxHeightLevels = highestPowerOf2(m_height);

// Standard OpenGL doesn't accept width or height that are not power of 2.
// If that's the case we resize the picture to the closest larger valid rectangle.
bool widthIsExponent = (m_width == (unsigned int) (1 << maxWidthLevels));
bool heightIsExponent = (m_height == (unsigned int) (1 << maxHeightLevels));

if (!widthIsExponent || !heightIsExponent)
// Calculate the new width/height.
if (!widthIsExponent)
if (!heightIsExponent)

// Resize the image, without bothering to preserve the aspect ratio.
m_width = 1 << maxWidthLevels;
m_height = 1 << maxHeightLevels;
image.resize(m_width, m_height, false);

// The number of mipmap levels cannot be greater than the exponent of width or height.
// The number of mipmap levels is 1 for a non-mipmapped texture.
// For mipmapped textures, m_numLevels = max level + 1.
m_numLevels = mipmapped ? MAX(maxWidthLevels, maxHeightLevels) + 1 : 1;

// Allocate the proper amount of memory, for the base level and the mipmaps.
assert(!m_levels); // Make sure that all levels are originally empty.
m_levels = new unsigned char* [m_numLevels];
for (i=0; i < m_numLevels; i++)
m_levels[i] = new unsigned char [width(i) * height(i) * 4];

// Copy the base level. (the actual file texture)
memcpy(m_levels[0], image.pixels(), m_width * m_height * 4);

// Create the mipmapped levels.
// NOTE REGARDING THE width_ratio and height_ratio:
// The smallest mipmap levels of non-square textures must be handled
// carefully. Say we have a 8x2 texture. Mipmap levels will be
// 4x1, 2x1, 1x1. We cannot simply multiply the current st coordinate by
// 2 like we do for square textures to find the source st coordinates,
// or we'll end up fetching outside of the source level. Instead, we
// multiply the target s, t coordinates by the width and height ratio respectively.
for (unsigned int current_level = 1; current_level < m_numLevels; current_level++)
unsigned int width_ratio = width(i-1) / width(i);
unsigned int height_ratio = height(i-1) / height(i-1);
unsigned int previous_level = current_level - 1;

for (unsigned int target_t = 0; target_t < height(current_level); target_t++)
for (unsigned int target_s = 0; target_s < width(current_level); target_s++)
// The st coordinates from the source level.
unsigned int source_s = target_s * width_ratio;
unsigned int source_t = target_t * height_ratio;
unsigned int source_s2 = source_s + ((width_ratio == 2) ? 1 : 0);
unsigned int source_t2 = source_t + ((height_ratio == 2) ? 1 : 0);

unsigned char *destination = internalFetch(target_s, target_t, current_level);
unsigned char *source1 = internalFetch(source_s, source_t, previous_level);
unsigned char *source2 = internalFetch(source_s2, source_t, previous_level);
unsigned char *source3 = internalFetch(source_s, source_t2, previous_level);
unsigned char *source4 = internalFetch(source_s2, source_t2, previous_level);

// Average byte per byte.
unsigned int average1 = (*source1++ + *source2++ + *source3++ + *source4++) / 4;
*destination++ = average1;

unsigned int average2 = (*source1++ + *source2++ + *source3++ + *source4++) / 4;
*destination++ = average2;

unsigned int average3 = (*source1++ + *source2++ + *source3++ + *source4++) / 4;
*destination++ = average3;

unsigned int average4 = (*source1++ + *source2++ + *source3++ + *source4++) / 4;
*destination++ = average4;

if( type == NMAP )
// Convert each level to the NORMAL map format
MNormalMapConverter mapConverter;

for (unsigned int i = 0; i < m_numLevels; i++)
mapConverter.convertToNormalMap( m_levels[i], width(i), height(i), MNormalMapConverter::RGBA, 2.0f );


return true;

bool MTexture::specify(GLenum target /* = GL_TEXTURE_2D */)
assert(glGetError() == GL_NO_ERROR);


assert(glGetError() == GL_NO_ERROR);

for (unsigned int i=0; i < m_numLevels; i++)
glTexImage2D(target, i, m_internalFormat, width(i), height(i), 0,
m_format, m_componentFormat, m_levels[i]);

assert(glGetError() == GL_NO_ERROR);

if (mipmapped())
// Mipmapping enabled
assert(glGetError() == GL_NO_ERROR);

assert(glGetError() == GL_NO_ERROR);

m_texObj.parameter(GL_TEXTURE_WRAP_S, GL_CLAMP);
m_texObj.parameter(GL_TEXTURE_WRAP_T, GL_CLAMP);

return true;

bool MTexture::bind()

return true;

int highestPowerOf2(int num)
int power = 0;

while (num > 1)
num = num >> 1;

return power;

05 May 2002, 07:21 AM
I obviously can see that I need values in some of these spaces but I dont exactly know C++ so i get alittle confused........also is this saying I need to supply my own picture...if so how? could someone fill this out. use "retard.tif" as the hypothetical picture if needed.

Thanx soooo muuuch.....Nick

05 May 2002, 07:32 AM
You need to find the MImage.h file and #include it at the top of this file or this will never compile correctly.

check it out.

05 May 2002, 07:57 AM
I changed the #include "MImage.h" still get the same I need to change something in the MImage.h class


#include <windows.h>
#include <gl\gl.h>
#include <gl\glaux.h>
#include <gl\glu.h>

#ifndef mImageDef
#define mImageDef

class mImage
mImage(const mImage &copy); //copy constructot
mImage(int width,int height,int planes); //creates a blank image of those dimensions
mImage(char *filename); //creates an image from a filename , or a blank image if it can't
~mImage(); //destructor

int height(); //these return the height and width of the image respectively
int width();
void setPixel(int,int,BYTE,BYTE,BYTE);//sets RGB to three byte vals
void setPixel(int,int,RGBTRIPLE);//sets to RGBTRIPLE
void setPixel(int,int,BYTE); //sets RGB to all same vals.
RGBTRIPLE getPixel(int,int); //returns color of pixel in an RGBTRIPLE struct
void resize(int,int); //resizes the image using linear interpolation
void setmask(mImage * maskbit); //sets another image as the alpha mask for this image
void setallred(); //sets the pixels RGB to either RRR ,GGG ,BBB , or an average of the three
void setallgreen();
void setallblue();
void setallaverage();
int blank(); //sets all pixels = 0;
HBITMAP handle(HDC dc); //returns a windows System HBITMAP handle for device context display
HBITMAP mhandle; //the actual handle of the image

char name[64]; //name of this image
unsigned char *idata; //the actual image data , probably not a good idea to have it public ,but any
//risks are outweighed by the benefits.
BOOL wrapped; //image is wrapped or not


//int mplanes; //defunct
RGBQUAD *palette; //the palette ,not actually used except in the load constructor

BITMAPFILEHEADER bmphd; //the FILEHEADER loaded from file
BITMAPINFOHEADER bmpinfo; //the INFOHEADER loaded from file or created in the constructor
BOOL masked; //whether this image is masked or not.



05 May 2002, 03:43 PM
c/c++ is case sensitive syntax - either switch all references to MImage to mImage or change the mImage class to be MImage.

you can use find in files under edit to do this.

CGTalk Moderation
01 January 2006, 05:00 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.