Showing posts with label cg. Show all posts
Showing posts with label cg. Show all posts

Sunday, November 14, 2010

Putting CG shaders where VS can find them

For a while, I was having problems running my CG tests out of visual studio. It couldn't find my shader files, so I had to run from the command line. Not only did this add some steps, it meant I couldn't debug.

Turns out, all I had to do was move the shader to where VS creates new classes by default (another level deeper in the directory than where I normally put my source code). I went ahead and moved all my code and shaders there, and now it will happily find the shaders when I run via F5.

Sunday, May 16, 2010

Compile Cg shaders from command line

Use cgc to compile Cg shader programs from the command line. (cgc --help for usage). Useful for seeing errors/warnings and instruction counts.

Cheat sheet:
Vertex shader: cgc vert.cg -entry main -profile arbvp1
Fragment shader: cgc frag.cg -entry main -profile arbfp1

Sunday, October 4, 2009

Cg syntax highlighting in vim


  1. Download cg.vim to ~/.vim/syntax/. (more info here. Note: the file on that page is DOS formatted; my link is to a converted version)

  2. Enable automatic highlighting by adding this to ~/.vimrc:
    au BufNewFile,BufRead *.cg setf cg

Monday, June 1, 2009

Matrix transformations and gluLookAt in Cg

OpenGL has some nice helper functions for matrix manipulation: glTranslate, glRotate, and glScale.

GlRotate is especially involved, so I made a version in Cg (based on the matrix in the spec):

float4x4 getRotateMatrix(float theta, float3 axis) {
float x = axis.x, y = axis.y, z = axis.z, c = cos(theta), s = sin(theta);
float4x4 matrix = float4x4(
x*x*(1-c)+c, x*y*(1-c)-z*s, x*z*(1-c)+y*s, 0,
y*x*(1-c)+z*s, y*y*(1-c)+c, y*z*(1-c)-x*s, 0,
x*z*(1-c)-y*s, y*z*(1-c)+x*s, z*z*(1-c)+c, 0,
0, 0, 0, 1
);
return matrix;
}


Another especially useful function is gluLookAt, which lets you specify camera position and tell it to look at a specific point. I downloaded the Mesa3D code and made the following Cg function based on it:

float4x4 getLookAt(float3 eye, float3 center, float3 up) {
float3 forward = normalize(center - eye);
float3 side = normalize(cross(forward, up)); /* Side = forward x up */
up = cross(side, forward); /* Recompute up as: up = side x forward */

return float4x4(
side.x, up.x, -forward.x, -eye.x,
side.y, up.y, -forward.y, -eye.y,
side.z, up.z, -forward.z, -eye.z,
0, 0, 0, 1
);
}

Thursday, May 28, 2009

Using opengl, glut, and cg with Visual Studio

These pages describe the process (the first one is out of date, but the changes to directory structure are minor):

OpenGL and GLUT
Cg

In case those pages go away, it boils down to this:

GLUT

  • Get GLUT for Win32

  • Copy...


    • glut32.dll to %WinDir%\System

    • glut32.lib to $(VSDir)\VC\lib

    • glut.h to $(VSDir)\include\GL


  • ...where $(VSDir) is something like C:\Program Files\Microsoft Visual Studio 9.0\VC


Cg


Visual Studio

  • Make a new Win32 Console Application project: File->New Project->Visual C++->Win32->Win32 Console Application

    • In the "Application Settings" page of the wizard, make sure Application type is Console Application and Empty project (under Additional options) is checked.

  • Go to Project->(project name) Settings


    • Set Configuration to All Configurations

    • Expand Configuration Properties

    • In C/C++->General, add $(CG_INC_PATH) to Additional Include Directories

    • In Linker->General, add $(CG_LIB_PATH) to Additional Library Directories

    • In Linker->Input, add opengl32.lib glu32.lib glut32.lib cg.lib cgGL.lib to Additional Dependencies


Friday, May 22, 2009

Changing vertex processing inside glBegin()/glEnd()

It appears you CAN NOT change shaders in the middle of a glBegin()/glEnd() block. That is, the following code will not switch between vert_main and vert_shadow:

glBegin(GL_TRIANGLE_STRIP); {
for (int v = 0; v < 4; v ++) { cgGLBindProgram(vert_main); glVertex3fv(VERTS[FACES[f][v]].xyz); cgGLBindProgram(vert_shadow); glVertex3fv(VERTS[FACES[f][v]].xyz); } } glEnd();


Looks like I *should* have seen this in the documentation: "Only a subset of GL commands can be used between glBegin and glEnd."

Friday, January 23, 2009

error C1019: scalar Boolean expression expected

While working on my GPU raytracer, I've come across the following Cg error a few times: error C1019: scalar Boolean expression expected. Weirdly, it only threw this error on the machines at school (the Cg shader code is compiled at run-time). Though the line numbers don't make this clear, the problem code appears to be this:

float4 val = readFloat4FromTexture();
if (val != float4(1,1,1,1)) {
...
}


I haven't investigated why this works at home and not school (different Cg compiler versions?), but I fixed it by changing to this:

...
if (val.x != 1 && val.y != 1 && val.z != 1 && val.w != 1) {
...
}


I wasn't able to find *anything* about the error on Google or in the Cg documentation, so hopefully this is useful if anyone else has this problem.

Wednesday, January 7, 2009

Getting useful errors from Cg

Since Cg programs are compiled at the program's runtime, you must catch Cg compile and runtime errors from within your program. Here's how:

First, you will need a callback. Cg will call this function whenver there is an error. Example:

void MyErrorCallback(void) {
CGerror error = cgGetError();
const char* errorString = cgGetErrorString(cgGetError());
printf("Cg error: %s\n", errorString);

// check for compiler errors
if (error == CG_COMPILER_ERROR)
printf("%s\n", cgGetLastListing(context));
}


Next, you need to set the callback:
cgSetErrorCallback(MyErrorCallback);

Now you should get more useful output when Cg has problems.

And easy way to make for loops unrollable

Cg will let you use for loops in your shaders, but only if they can be unrolled. Though it loses you the performance benefits of loop unrolling, you can make a for loop unrollable by moving the guard (or "are we done yet?" check) into the loop body.

For example:

int arr[] = {2, 1, 3};
for (int i = 1; i < arr[0]; i ++) {
doStuff(arr[i]);
}

That snippet gives an error like this when you try to compile it:
frag.cg(71) : error C5013: profile does not support "for" statements and "for" could not be unrolled.

Instead, try the following:

int arr[] = {2, 1, 3};
for (int i = 1; i < MAX_LEN; i ++) {
doStuff(arr[i]);
if (i == arr[0])
break;
}


EDIT:
Or better yet, just do this:

int arr[] = {2, 1, 3};
for (int i = 1; i < MAX_LEN && i < arr[0]; i ++) {
doStuff(arr[i]);
if (i == arr[0])
break;
}


Note that I found order to be important (it didn't like arr[0] before MAX_LEN).