Jump to content
  • Advertisement
Sign in to follow this  
spek

VBO with tangent data

This topic is 4273 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I want to use VBO's for my objects, but I can't find space for putting the tangent data in it as well. My vertex-data contains this: - Vertices(3f) - Texcoords(2f) - Normals(3f) - Tangents(3f) - BiTangents(3f) Its a while ago since I used VBO's, so correct me if I'm wrong. Normally I would use the "glInterleavedArrays" function to tell what the data format is. For example, I can choose for "GL_C4UB_V3F" format, which means it the vertex-data contains 4 unsigned bytes for the color, and a vertices with 3 components. But what format to use for the stuff I want? Normally I put my tangents/biTangents inside texture coordinates on channel 1 and 2. But I can't find a format for that. greetings, Rick

Share this post


Link to post
Share on other sites
Advertisement
It is, perhaps, time to switch to defining your own layouts. I never even bothered trying those pre-packaged configurations. Modern 3D cards, and most certainly VBO processing, are designed for vertex-structures that contain some multiple of 32-bytes (32-bytes, 64-bytes, etc).

I have two vertex structures in my engine, one with 32-bytes that contains:
    position: x,y,z
    tcoords: u,v
    color: r,g,b,a
    normal: nx,ny,[nz]
and another with 64-bytes that contains:
    position: x,y,z
    tcoords: u,v
    color: r,g,b,a
    normal: nx,ny,nz
    tangent: tx,ty,tz
    bitangent: bx,by,bz

You are being pushed in this direction now, and this is where you should go. Once you have it working, you will never look back! However, you will probably want/need to consider making some of your components with integers. For example, to make my vertex-structures and VBO arrangement "work out", I store my colors and texture-coordinates as u16 values (unsigned 16-bit integers). This required me to NOT put the z component of the normal vector into the VBO, to make room for the four u16 RGBA color values in one-half of the vertex. But that is no problem since the shader can compute nz from nx,ny! :-)

Share this post


Link to post
Share on other sites
64 bytes should be sufficient. But... how to render it in that case? I didn't know this was possible as well. Is there a constant to tell OpenGL 64 bytes is coming? And ifso, how to set the data up?

Before I made an array with floats, something like this:

// format = GL_T2F_C4UB_V3F
data[n][0] = texcoord.x
data[n][1] = texcoord.y
data[n][2] = <packed rgba in 1 float>
data[n][3] = vertex.x
data[n][4] = vertex.y
data[n][5] = vertex.z


But what to do now? Is there an example somewhere?

greetings,
Rick

Share this post


Link to post
Share on other sites
Don't use GL's built in glInterleavedArrays, setup the arrays yourself.

Make a struct and put the vertex attributes in it you need. Than allocate the memory you need and fill the data and upload the data to the VBO as a whole unit if you want or map it. Then you use offsets in bytes of the size of the data you want to access. e.g.


struct Vertex
{
float vx,vy,vz;
float nx,ny,nz;
float tx,ty,tz;
//others
};

//then you get the size of the data
unsigned int normalsOffset = sizeof(float) * 3;
unsigned int tangentOffset = sizeof(float) * 6;




then you use the offsets in the array pointer functions with the Bufferoffset macro from the extension doc.

hope that helps

Share this post


Link to post
Share on other sites
Uhm... I understand how to make the data array. But with which function to pass it? So far I always use "glDrawElements". Its a while ago I used VBO's. Possibly I also have an older version of the OpenGL function library.

greetings and thanks for helping,
Rick

Share this post


Link to post
Share on other sites
Well, this is a somewhat involved process that you need to grind through once to get right. For me, it took reading the OpenGL information carefully about thirty-seven million, nine-hundred and fifty-six thousand, eight-hundred and twenty-six times. I think I looked in "OpenGL SuperBible" and the "OpenGL Programmer Manual" a few times too. Oh, and after I got it working I got "OpenGL Distilled" and it would have saved me a couple years I think.

All the above just means "it ain't trivial".

Here is some code to read to get hints from. This code WORKS, so I know it is correct, but many of the variables are specific to my engine, and therefore make no sense to you (though they are pretty descriptive names). However, all the OpenGL function calls are what you need to understand, and this code shows you what order they come in. The first function is where the shaders are created and initialized and all the vertex-element positions are registered with OpenGL and double-checked by the code (to make sure it happened correctly).

This code is called once to set up the shaders and its variables (which are specific to processing the vertex structure I outlined previously).

The second chunk of code is a function the first function/code-chunk calls.

The third chunk of code is code that sets up OpenGL before every draw call (and you can see the draw call down at the bottom).

If all this code isn't enough to drive you crazy, then you will end up very happy and never return to fixed predefined vertex arrangements - which are hopelessly ancient and inflexible and inefficient in new video cards.

Sorry, but you will need to do some reading and learning to understand this. But you'll probably find lots of VBO experts to explain this a hundred times better than I ever could. I only know how to slog until it works! And since I have the worst memory on earth, I cannot remember all the hows and whys. :-(




cpu ig_shader_create (cpu vertex, cpu pixel) { // function entry

buffer = memory_buffer_create (maxbytes);

file_load (L"igtan003.vs", &vsource, &vbytes); // vertex shader
file_load (L"igtan003.ps", &psource, &pbytes); // pixel shader
//
// create vertex shader and pixel shader
//
vshader = glCreateShader (GL_VERTEX_SHADER); // GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
pshader = glCreateShader (GL_FRAGMENT_SHADER); // GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
//
// specify vertex shader and pixel shader source-code text
//
const GLchar** vstext = (const GLchar**)&vsource; // vstext is an array of pointers to strings that contain vertex-shader-programs-or-functions (source code)
const GLchar** pstext = (const GLchar**)&psource; // pstext is an array of pointers to strings that contain pixel-shader-programs-or-functions (source code)
glShaderSource (vshader, vlines, vstext, &vbytes); //
glShaderSource (pshader, plines, pstext, &pbytes); //
//
// compile vertex shader
//
glCompileShader (vshader); // compile vertex shader
glGetShaderiv (vshader, GL_COMPILE_STATUS, &success); // success or failure ???
if (success == 0) {
glGetShaderiv (vshader, GL_INFO_LOG_LENGTH, &ebytes);
log = memory_buffer_create (ebytes + 1);
if (log == 0) { return (CORE_ERROR_MEMORY_ALLOCATION); }
glGetShaderInfoLog (vshader, ebytes, NULL, (GLchar*)log);
error = file_log_c08 (log);
memory_buffer_destroy (log);
memory_buffer_destroy (buffer);
memory_buffer_destroy (vsource);
memory_buffer_destroy (psource);
return (CORE_ERROR_INTERNAL);
}
//
// compile pixel shader and test for error message
//
glCompileShader (pshader); // compile pixel shader
glGetShaderiv (pshader, GL_COMPILE_STATUS, &success); // success or failure ???
if (success == 0) {
glGetShaderiv (pshader, GL_INFO_LOG_LENGTH, &ebytes);
log = memory_buffer_create (ebytes + 1);
if (log == 0) { return (CORE_ERROR_MEMORY_ALLOCATION); }
glGetShaderInfoLog (pshader, ebytes, NULL, (GLchar*)log);
error = file_log_c08 (log);
memory_buffer_destroy (log);
memory_buffer_destroy (buffer);
memory_buffer_destroy (vsource);
memory_buffer_destroy (psource);
return (CORE_ERROR_INTERNAL);
}
//
// create empty "program object"
//
program = glCreateProgram (); // create "program object"
//
// attach vertex-shader and pixel-shader to this "program object"
//
glAttachShader (program, vshader); // attach vertex shader to program
glAttachShader (program, pshader); // attach pixel shader to program
//
// establish:
// - vertex structure component types and offsets
// - generic vertex attribute variables
// - uniform variables [and others?]
// - other shader stuff
//
error = ig_shader_setup (program, vshader, pshader, 0);
if (error < 0) { return (error); }
//
// link vertex-shader and pixel-shader in this "program object"
//
char* logc = (char*)log;
glLinkProgram (program); // link program object
glGetProgramiv (program, GL_LINK_STATUS, &success); // success or failure ???
if (success == 0) {
glGetProgramiv (program, GL_INFO_LOG_LENGTH, &ebytes);
log = memory_buffer_create (ebytes + 1);
if (log == 0) { return (CORE_ERROR_MEMORY_ALLOCATION); }
glGetProgramInfoLog (program, ebytes, NULL, (GLchar*)log);
logc = (char*)log;
error = file_log_c08 (log);
memory_buffer_destroy (log);
memory_buffer_destroy (buffer);
memory_buffer_destroy (vsource);
memory_buffer_destroy (psource);
return (CORE_ERROR_INTERNAL);
}
//
// attempt to validate this program-object (try to validate vertex-shader and pixel-shader in this program-object)
//
glValidateProgram (program);
glGetProgramiv (program, GL_VALIDATE_STATUS, &success);
if (success == 0) {
glGetProgramiv (program, GL_INFO_LOG_LENGTH, &ebytes);
log = memory_buffer_create (ebytes + 1);
if (log == 0) { return (CORE_ERROR_MEMORY_ALLOCATION); }
glGetProgramInfoLog (program, ebytes, NULL, (GLchar*)log);
error = file_log_c08 (log);
memory_buffer_destroy (log);
memory_buffer_destroy (buffer);
memory_buffer_destroy (vsource);
memory_buffer_destroy (psource);
return (CORE_ERROR_INTERNAL);
}
//
// tell GPU to activate our program-object (our vertex-shader and pixel-shader)
//
glstate.active_vshader = vshader;
glstate.active_pshader = pshader;
glstate.active_program = program;
igstate.active_shaders = program;
igstate.shaderprogram = program;
//
// make program active (GPU executes shader rather than current shaders --- or default fixed pipeline)
//
glUseProgram (program);

glGetShaderiv (vshader, GL_INFO_LOG_LENGTH, &vsbytes);
glGetShaderiv (pshader, GL_INFO_LOG_LENGTH, &psbytes);
glGetProgramiv (program, GL_INFO_LOG_LENGTH, &prbytes);

glGetShaderInfoLog (vshader, maxbytes, &readbytes, (GLchar*)buffer);
glGetShaderInfoLog (pshader, maxbytes, &readbytes, (GLchar*)buffer);
glGetProgramInfoLog (program, maxbytes, &readbytes, (GLchar*)buffer);
//
// load and install any textures required for this shader
//
// [special-purpose texture-map/normal-map loading code snipped]
//
//
GLuint texid;
glGenTextures (1, &texid);
glstate.texid_texturemap = texid; // remember OpenGL texture-object ID #
//
// set-up the necessary textures for texture/height/normal/relief/parallax/distance/occlusion/displacement mapping (normal-tweaking tricks in tangent-space)
//
// first a simple texture map to apply to surface
//
glActiveTexture (GL_TEXTURE0); // set active texture unit # = 0
glBindTexture (GL_TEXTURE_2D, glstate.texid_texturemap); // attach the "texturemap" texture to texture-unit #0
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, twidth, theight, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmap);
//
// second a height-map in the A channel and a normal-map in the RGB channels
//
glGenTextures (1, &texid);
glstate.texid_surfacemap = texid; // remember OpenGL texture-object ID #

glActiveTexture (GL_TEXTURE1); // set active texture unit # = 1
glBindTexture (GL_TEXTURE_2D, glstate.texid_surfacemap); // attach the "surfacemap" texture to texture-unit #1
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, swidth, sheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, smap);

glActiveTexture (GL_TEXTURE0); // set active texture unit # = 0 == default-location
//
// see if we can verify our attributes
//
glstate.index_position = glGetAttribLocation (program, "ig_position"); // position
glstate.index_tcoord = glGetAttribLocation (program, "ig_tcoord"); // tcoord
glstate.index_up = glGetAttribLocation (program, "ig_up"); // up-vector AKA zenith-vector AKA normal-vector
glstate.index_color = glGetAttribLocation (program, "ig_color"); // color == RGBA
glstate.index_east = glGetAttribLocation (program, "ig_east"); // east-vector AKA tangent-vector
glstate.index_north = glGetAttribLocation (program, "ig_north"); // north-vector AKA bitangent-vector
glstate.index_select = glGetAttribLocation (program, "ig_select"); // select behavior in vertex-shader and pixel-shader

glstate.index_pcamera = glGetUniformLocation (program, "ig_pcamera"); // uniform variable == camera position
glstate.index_plight0 = glGetUniformLocation (program, "ig_plight0"); // uniform variable == light0 position
glstate.index_plight1 = glGetUniformLocation (program, "ig_plight1"); // uniform variable == light1 position
glstate.index_plight2 = glGetUniformLocation (program, "ig_plight2"); // uniform variable == light2 position
glstate.index_texturemap = glGetUniformLocation (program, "ig_texturemap"); // texture-map #0 == texture-unit #0
glstate.index_surfacemap = glGetUniformLocation (program, "ig_surfacemap"); // texture-map #1 == texture-unit #1
//
// NOTE: We do not assign values to pcamera, plight0, plight1, plight2 here,
// because they must be set every frame (since they can be moved every frame).
// However, we do assign values to texturemap, surfacemap, [foldingmap], [steppermap],
// because they remain fixed [probably] as long as these shaders remain installed.
//
glUniform1i (glstate.index_texturemap, 0); // specify texture unit # that contains "texturemap"
glUniform1i (glstate.index_surfacemap, 1); // specify texture unit # that contains "surfacemap"
//
// If we execute the rest of this function (below),
// we cannot switch back to default-pipeline processing
// and THEN back to this program (cuz it has been trashed)!
//
// Therefore, we really should not detach and delete these resource,
// we should do that when the program is done executing (to clean up).
//
if (1) {
glDetachShader (program, vshader);
glDetachShader (program, pshader);

glDeleteShader (vshader);
glDeleteShader (pshader);
glDeleteProgram (program);
}

memory_buffer_destroy (log);
memory_buffer_destroy (buffer);
memory_buffer_destroy (vsource);
memory_buffer_destroy (psource);
}






//
// the following is the guts of function ig_shader_setup() --- called from the other code
//
cpu ig_shader_setup (cpu program, cpu vshader, cpu pshader, cpu options) {

//
// [snip internal setup code]
//
// get offset to each element in ig_vertex32 structure (vertex structure we put into VBO)
//
u08* base = (u08*)&vertex;
u08* offsetp = (u08*)((u08*)&vertex.position - (u08*)base); // 0x0000 to 0x000B ::: 3 * f32 position.xyz
u08* offsett = (u08*)((u08*)&vertex.tcoords - (u08*)base); // 0x000C to 0x000F ::: 2 * u16 tcoord.st
u08* offsetu = (u08*)((u08*)&vertex.up - (u08*)base); // 0x0010 to 0x0018 ::: 2 * f32 up.xy
u08* offsetc = (u08*)((u08*)&vertex.coloru16[0] - (u08*)base); // 0x0018 to 0x001F ::: 4 * u16 color.rgba
u08* offsete = (u08*)((u08*)&vertex.east - (u08*)base); // 0x0020 to 0x002F ::: 4 * f32 east.xyz + up.z
u08* offsetn = (u08*)((u08*)&vertex.north - (u08*)base); // 0x0030 to 0x003B ::: 3 * f32 north.xyz
u08* offsets = (u08*)((u08*)&vertex.selectu08[0] - (u08*)base); // 0x003C to 0x003F ::: 4 * u08 select.xyzw
//
// define vertex attributes --- each corresponds to one component of the vertex structure we put into the VBO
//
glVertexAttribPointer (1, 2, GL_UNSIGNED_SHORT, 1, vbytes, offsett); // 2 * u16 == tcoord.st
glVertexAttribPointer (2, 2, GL_FLOAT, 0, vbytes, offsetu); // 2 * f32 == up.xy
glVertexAttribPointer (3, 4, GL_UNSIGNED_SHORT, 1, vbytes, offsetc); // 4 * u16 == color
glVertexAttribPointer (4, 4, GL_FLOAT, 0, vbytes, offsete); // 4 * f32 == east.xyz + up.z
glVertexAttribPointer (5, 3, GL_FLOAT, 0, vbytes, offsetn); // 3 * f32 == north.xyz
glVertexAttribPointer (6, 4, GL_UNSIGNED_BYTE, 1, vbytes, offsets); // 4 * u08 == select.xyzw
glVertexAttribPointer (0, 3, GL_FLOAT, 0, vbytes, offsetp); // 3 * f32 == position (must be executed LAST)
//
// enable every vertex attribute --- evidentally not needed (!!!!! until we implement long AND short (halfsize) vertices !!!!!)
//
glEnableVertexAttribArray (0); // enable vertex position
glEnableVertexAttribArray (1); // enable vertex tcoords
glEnableVertexAttribArray (2); // enable vertex up-vector
glEnableVertexAttribArray (3); // enable vertex color
glEnableVertexAttribArray (4); // enable vertex east-vector
glEnableVertexAttribArray (5); // enable vertex north-vector
glEnableVertexAttribArray (6); // enable vertex select-behavior
// glEnableVertexAttribArray (0); // enable vertex position
//
// just curious whether the following function exist and function
//
void* attr00 = 0;
void* attr01 = 0;
void* attr02 = 0;
void* attr03 = 0;
void* attr04 = 0;
void* attr05 = 0;
void* attr06 = 0;
glGetVertexAttribPointerv (0, GL_VERTEX_ATTRIB_ARRAY_POINTER, (GLvoid**)&attr00);
glGetVertexAttribPointerv (1, GL_VERTEX_ATTRIB_ARRAY_POINTER, (GLvoid**)&attr01);
glGetVertexAttribPointerv (2, GL_VERTEX_ATTRIB_ARRAY_POINTER, (GLvoid**)&attr02);
glGetVertexAttribPointerv (3, GL_VERTEX_ATTRIB_ARRAY_POINTER, (GLvoid**)&attr03);
glGetVertexAttribPointerv (4, GL_VERTEX_ATTRIB_ARRAY_POINTER, (GLvoid**)&attr04);
glGetVertexAttribPointerv (5, GL_VERTEX_ATTRIB_ARRAY_POINTER, (GLvoid**)&attr05);
glGetVertexAttribPointerv (6, GL_VERTEX_ATTRIB_ARRAY_POINTER, (GLvoid**)&attr06);
error = glGetError ();
//
// assocatiates attribute variable names in vertex shader with vertex structure components
//
glBindAttribLocation (program, 0, "ig_position"); // 0 == position
glBindAttribLocation (program, 1, "ig_tcoord"); // 1 == tcoord
glBindAttribLocation (program, 2, "ig_up"); // 2 == up-vector
glBindAttribLocation (program, 3, "ig_color"); // 3 == color
glBindAttribLocation (program, 4, "ig_east"); // 4 == east-vector
glBindAttribLocation (program, 5, "ig_north"); // 5 == north-vector
glBindAttribLocation (program, 6, "ig_select"); // 6 == select

return (0);
}







cpu ig_batch_draw (cpu batchid, cpu mode) {

//
// #######################################
// THE FOLLOWING CODE SHOULD NOT BE NEEDED
// #######################################
//
// get offset to each element in ig_vertex32 structure (vertex structure we put into VBO)
//
ig_vertex32 vertex;
cpu vbytes = sizeof(ig_vertex32);

u08* base = (u08*)&vertex;
u08* offsetp = (u08*)((u08*)&vertex.position - (u08*)base); // 0x0000 to 0x000B ::: 3 * f32 position.xyz
u08* offsett = (u08*)((u08*)&vertex.tcoords - (u08*)base); // 0x000C to 0x000F ::: 2 * u16 tcoord.st
u08* offsetu = (u08*)((u08*)&vertex.up - (u08*)base); // 0x0010 to 0x0018 ::: 2 * f32 up.xy
u08* offsetc = (u08*)((u08*)&vertex.coloru16[0] - (u08*)base); // 0x0018 to 0x001F ::: 4 * u16 color.rgba
u08* offsete = (u08*)((u08*)&vertex.east - (u08*)base); // 0x0020 to 0x002F ::: 4 * f32 east.xyz + up.z
u08* offsetn = (u08*)((u08*)&vertex.north - (u08*)base); // 0x0030 to 0x003B ::: 3 * f32 north.xyz
u08* offsets = (u08*)((u08*)&vertex.selectu08[0] - (u08*)base); // 0x003C to 0x003F ::: 4 * u08 select.xyzw
//
// define vertex attributes --- each corresponds to one component of the vertex structure we put into the VBO
//
// glVertexAttribPointer (0, 3, GL_FLOAT, 0, vbytes, offsetp); // 3 * f32 == position.xyz (must be executed LAST)
glVertexAttribPointer (1, 2, GL_UNSIGNED_SHORT, 1, vbytes, offsett); // 2 * u16 == tcoord.st
glVertexAttribPointer (2, 2, GL_FLOAT, 0, vbytes, offsetu); // 2 * f32 == up.xy
glVertexAttribPointer (3, 4, GL_UNSIGNED_SHORT, 1, vbytes, offsetc); // 4 * u16 == color
glVertexAttribPointer (4, 4, GL_FLOAT, 0, vbytes, offsete); // 4 * f32 == east.xyz + up.z
glVertexAttribPointer (5, 3, GL_FLOAT, 0, vbytes, offsetn); // 3 * f32 == north.xyz
glVertexAttribPointer (6, 4, GL_UNSIGNED_BYTE, 1, vbytes, offsets); // 4 * u08 == select.xyzw
glVertexAttribPointer (0, 3, GL_FLOAT, 0, vbytes, offsetp); // 3 * f32 == position (must be executed LAST)
error = glGetError ();
//
// enable every vertex attribute --- evidentally not needed (until we implement long AND short vertices)
//
if (0) {
glEnableVertexAttribArray (0); // enable vertex position
glEnableVertexAttribArray (1); // enable vertex tcoords
glEnableVertexAttribArray (2); // enable vertex up-vector
glEnableVertexAttribArray (3); // enable vertex color
glEnableVertexAttribArray (4); // enable vertex east-vector
glEnableVertexAttribArray (5); // enable vertex north-vector
glEnableVertexAttribArray (6); // enable vertex select-behavior
// glEnableVertexAttribArray (0); // enable vertex position
error = glGetError ();
}
//
//
// OpenGL draw modes - IG support ::: IG primitive
//
// GL_POINTS - IG supports == IG_PRIMITIVE_POINT
// GL_LINES - IG supports == IG_PRIMITIVE_LINE
// GL_TRIANGLES - IG supports == IG_PRIMITIVE_TRIANGLE == IG_PRIMITIVE_SURFACE
//
// GL_LINE_STRIP - no -------- but IG supports line strips with GL_LINES
// GL_LINE_LOOP - no -------- but IG supports line loops with GL_LINES
//
// GL_TRIANGLE_STRIP - no
// GL_TRIANGLE_FAN - no
// GL_QUAD - no
// GL_QUAD_STRIP - no
// GL_POLYGON - no
//
// trying to disable our shaders for points and lines --- disables our shaders COMPLETELY and PERMANENTLY --- FIX THIS
//
u32 activeshaders = igstate.active_shaders;
u32 shaderprogram = igstate.shaderprogram;

error = GL_TRIANGLES;
error = GL_LINES;
error = GL_POINTS;

switch (ptype) {
case IG_PRIMITIVE_TRIANGLE:
gmode = GL_TRIANGLES;
break;
case IG_PRIMITIVE_LINE:
gmode = GL_LINES;
break;
case IG_PRIMITIVE_POINT:
gmode = GL_POINTS;
break;
default:
gmode = GL_TRIANGLES;
break;
}
//
// draw IBO/VBO pair == draw batch
// - separate batches for points versus lines versus triangles/surfaces
//
if (icount) {
glDrawElements (gmode, icount, GL_UNSIGNED_SHORT, 0);
error = glGetError();
}

return (0);
}


Share this post


Link to post
Share on other sites
You need to use the offsets with the pointerarray functions. As for the VBO side, just upload the whole array into glBufferData().

Share this post


Link to post
Share on other sites
One of you other VBO experts will have to tell him how many things he does NOT need to do if he has no shaders (just lets the fixed function run). I have never run OpenGL without IBOs and VBOs or without vertex and pixel shaders, so I have no idea whatsoever how to advise about those situations! :-(

Share this post


Link to post
Share on other sites
Wow, thanks for the code :) I'm studying it now. That probably takes a while, I never used some of the OpenGL calls.

I'm using (cg) shaders as well, so I have one more question about that, how to get the data in the shader? I guess the positions, texcoords and normals come in the "usual" way. But where to get other data, the tangents for example? Are they inside another texture coordinate channel?

-edit-
I see you are sending the data to parameters inside the shaders ("ig_position", "ig_tcoord", and so on). Are these uniform array parameters in your shader program? Could you show how you get these values back in your shader? Normally I use the "vertex", "normal" and "texcoord(s)" in my Cg shader, but I guess its a little different now.

greetings,
Rick

[Edited by - spek on April 7, 2007 1:20:49 PM]

Share this post


Link to post
Share on other sites
If you look in the code, you will see references to "up", "east", "north". These are my way of saying "normal", "tangent", "bitangent" (or "binormal"). The names I choose are easy to visualize which direction they point relative to each other, that's all.

So when you look at the code, you will find the "east" (tangent) vector and "north" (bitangent/binormal) vector are in the vertex-structure, just like the "up" (normal) vector.

At the top of the "shader_setup" function you will see code that shows exactly what each of the vertex-structure elements is, how big it is, what type it is, and how the information about it is told to OpenGL (the glVertexAttribPointer functions and the code-section just above that finds the offsets of each of those vertex elements in the vertex-structure (which goes in the VBO) so OpenGL knows where each vertex element is in each vertex-structure.

You can mix "conventional" vertex component (position, normal, color, etc) with extra application-defined "vertex attributes", but I find that confusing. So I made *every* vertex component an application-defined "vertex attribute" - so everything is defined the same way. The vertex and pixel shaders the code refers to "igtan003.vs" and "igtan003.ps" also access two textures, one of which contains pixel-colors (as usual), while the other contains a normal-map with nx,ny,nz,h components. I removed the code that loads these two maps from memory because it is totally irrelevant code that you don't need to copy.

PS: My shaders are GLSL shaders, and I know nothing about Cg shaders. Therefore your questions that might have different answers for Cg shaders are totally outta my knowledge. Some of the code refers to the variable names in my shader code, but I'm not sure that is part of your question. I will send you the corresponding shader code by PM in case that helps you understand.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!