Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 13 May 2012
Offline Last Active Oct 23 2014 08:23 AM

Posts I've Made

In Topic: Read framebuffer pixels without rendering on screen

16 May 2012 - 12:15 PM

I can think of three different approaches to do this. Well depending on what you need. I'm not 100% clear...

glReadBuffer is supposed to let you choose to either read from the FrontBuffer (screen) or the BackBuffer. I think this is what you're looking for.

Alternatively you could also just render to a texture and then display that on an object.

You may also just use glViewPort to define the rendering to a small area of the window so you don't even need to bother about reading pixels from buffers or dealing with textures. This approach isn't as flexible and you'd still need to use one of the others if you want to save the image. But it's probably the fastest...

In Topic: Buffer corruption or is my code breaking?

16 May 2012 - 09:10 AM

The code I passed should still work for your string sprite since it does not appear that you are adding or removing any vertex data. That's the protion of the code I was was looking at when I suggested it. I apologize that I missed how you were doing the buttons and windows, but you have alot of code posted and none of your methods or functions have comments describing what they do. It is very time consuming to read...

You only need to resize the vbo if you're going to be passing in more vertex data than is already allocated. Which happens when you're expanding the window size. I'd make a conditional statement that remakes the vbo when a window is enlargened and just works within the current space if it's the same size or smaller. The unused space in the vbo is definitely worth the performance gain of not having to continueously call glBUFFERDATA, which is slower than glBUFFERSUBDATA.

At the very least this should help you to issolate the problem.

I implement a simular solution in my project for constantly updating text display (my FPS counter etc.). I have the full font as a texture atlas and render the individual characters to an array of quads. The quad array is only resized when increasing the amount of characters. Obviously this doesn't makes sense for your text but an approach like this should work for your windows and buttons.

In Topic: Buffer corruption or is my code breaking?

15 May 2012 - 04:56 PM

It would be alot easier to use glBufferSubData to update the vbo with new vertex information on resize than to delete and remake all the objects...
something like this

	 float texW = (float)mDiffuse->getWidth();	  
	 float texH = (float)mDiffuse->getHeight();	  
	 float srcW = 1;	  
	  float srcH = 1;	  
// Calculate the verticies	  
	 Vertex verts[] = {{0, 0, 0, 0, 0},										  
		  {texW, 0, 0, srcW, 0},											  
		  {0, texH, 0, 0, srcH},											  
		  {texW, texH, 0, srcW, srcH}};					  
		  int vertSize = sizeof(verts);	  
// Bind the VBO	  
glBindBuffer(GL_ARRAY_BUFFER_ARB, mVbo);	  
// Submit the vertex data to the GPU	  
glBufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(Vertex) * 4, verts);	  
// Unbind the VBO	  
glBindBuffer(GL_ARRAY_BUFFER_ARB, 0);
This would also check if indeed the problem is with deleting and recreating the objects or if there is some error in setting the new vertex positions you missed.

Also if you're going to be updating the VBO declare it as GL_DYNAMIC_DRAW

In Topic: Terrain lighting

15 May 2012 - 10:30 AM

Last i had problems with normals i made a trivial geometry shade to send my geometry to, might be worth sharing (in case you have not used a geometry shader before):

Just send another copy of your usual world geometry to this shader program to be drawn as GL_POINTS. Helps to ensure the normals are the way you assume they are and spot errors if not. Easier to see where the vertices are and hence judge what is interpolated with what etc.

Hey thanks for the geometry shader. I was able to implement it and display the normals. They appear fine to me from what I can tell
Attached File  normal display.png   223.5KB   38 downloads

Maybe the problem is in my shader code?
// Vertex shader
#version 330
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 normalMatrix;
layout(location = 0) in vec4 in_position;
layout(location = 1) in vec4 in_colour;
layout(location = 2) in vec3 in_normal;
out vec4 pass_colour;
smooth out vec3 vNormal;
void main()
   gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_position;
   vec4 ad_normal = normalMatrix*vec4(in_normal, 0.0);
   vNormal = ad_normal.xyz;
   pass_colour = in_colour;

// Fragment Shader
#version 330
in vec4 pass_colour;
smooth in vec3 vNormal;
out vec4 out_colour;
struct SimpleDirectionalLight
   vec3 vColor;
   vec3 vDirection;
   float fAmbientIntensity;
uniform SimpleDirectionalLight sunLight;
void main()
   float fDiffuseIntensity = max(0.0, dot(normalize(vNormal), -sunLight.vDirection));
   out_colour = pass_colour*vec4(sunLight.vColor*min(sunLight.fAmbientIntensity+fDiffuseIntensity,1.0), 1.0);

In Topic: Terrain lighting

15 May 2012 - 08:14 AM

Thanks tanzanite7 I'll implement those shaders next.

In the meantime I have rewritten and greately simplified my code. I decided that keeping track of the surface normals was unecessary and just complicated the code, due to having to ensure that they're later assigned to the appropriate vertex.

Instead whenever I calculate a surface normal I immediately add it to the normal of the contributing vectors. This ensures that each vertex normal always gets the correct surface normal contribution. All the normal computation and assingment happens within the second small loop. The first and last loop just load the vertex data and offload the normal data respectively.

// This struct gives a vertex a surface normal
struct LinkedVert : Vert{
	 Vert normal;

// Calculate normals for terrain.
void NSheet::calculateNormals(void) {

	 unsigned int num_surfaceNormals = pow(sheet_size - 1, 2) * 2;

	 // create a temporary array to hold vertices temporarily
	 LinkedVert* verts = new LinkedVert[amesh->num_verts/4];

	 // pointer to mesh data
	 Face* mesh_data = amesh->faces;

	 // First load vertex data and set normal to 0,0,0
	 for (unsigned int i = 0; i < amesh->num_verts/4; i++){
	   verts[i].xcorr = mesh_data->verts[i*4];
	   verts[i].ycorr = mesh_data->verts[i*4+1];
	   verts[i].zcorr = mesh_data->verts[i*4+2];
	   verts[i].normal.xcorr = 0.0f;
	   verts[i].normal.ycorr = 0.0f;
	   verts[i].normal.zcorr = 0.0f;

	 //retrieve pointer to indices
	 unsigned int* indices = mesh_data->indices;
	 // compute surface normals and add to normal of contributing vertex
	 for (unsigned int i = 0; i < num_surfaceNormals; i++) {
	   Vert surfaceNormal;
	   // index values
	   unsigned int index1 = indices[i*3];
	   unsigned int index2 = indices[i*3 + 1];
	   unsigned int index3 = indices[i*3 + 2];
	   // Calculate surface normal.  % overloaded to produce cross product
	   surfaceNormal = (verts[index2] - verts[index1]) % (verts[index3] - verts[index1]);
	   // normalize surface normal
	   surfaceNormal = normalizeVert(surfaceNormal);
	   // add normal to normal of whichever vert was used to calculate it
	   verts[index1].normal += surfaceNormal;
	   verts[index2].normal += surfaceNormal*2.0f;  // normal contributes twice to second vertex
	   verts[index3].normal += surfaceNormal;

	 // create an array to store normal data for later buffering
	 mesh_data->num_normals = pow(sheet_size, 2) * 3;
	 amesh->num_normals = mesh_data->num_normals;
	 mesh_data->normals = new float[mesh_data->num_normals];

	 // Normalize and transfer all vertex normals to normal array
	 for (unsigned int i = 0; i < amesh->num_verts/4; i++){
	   verts[i].normal = normalizeVert(verts[i].normal);
	   mesh_data->normals[i*3] = verts[i].normal.xcorr;
	   mesh_data->normals[i*3+1] = verts[i].normal.ycorr;
	   mesh_data->normals[i*3+2] = verts[i].normal.zcorr;

	 amesh->has_normals = true; // set to true automatically once normals are calculated
	 // Free memory
	 delete[] verts;

I've also included an illustration of how I index the vertices. The second vertex index in each triangle corresponds to the top left and bottom right corners of the containing quad. Thus whenever I add normal data I add it twice for these vertices to properly weight the triangles. In red are the triangles I add per vertex.
Attached File  indexorder.jpg   38.73KB   38 downloads

At this point since I'm getting the same result with this new method I suspect that my problem lies elsewhere. I'll try that geometry shader and examine more closely my vector math. I overloaded quite a few operators and may have made a small mistake