Jump to content
  • Advertisement

Kacper Kuryllo

  • Content Count

  • Joined

  • Last visited

Community Reputation

119 Neutral

About Kacper Kuryllo

  • Rank
  1. 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...
  2. Kacper Kuryllo

    Buffer corruption or is my code breaking?

    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.
  3. Kacper Kuryllo

    Buffer corruption or is my code breaking?

    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 onResize(){ 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 [size=2][size=2]GL_DYNAMIC_DRAW
  4. Kacper Kuryllo

    Terrain lighting

    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 [attachment=8907:normal display.png] 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); }
  5. Kacper Kuryllo

    Terrain lighting

    Thanks [color=#284B72]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.xcorr = mesh_data->verts[i*4]; verts.ycorr = mesh_data->verts[i*4+1]; verts.zcorr = mesh_data->verts[i*4+2]; verts.normal.xcorr = 0.0f; verts.normal.ycorr = 0.0f; verts.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.normal = normalizeVert(verts.normal); mesh_data->normals[i*3] = verts.normal.xcorr; mesh_data->normals[i*3+1] = verts.normal.ycorr; mesh_data->normals[i*3+2] = verts.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. [attachment=8906:indexorder.jpg] 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
  6. Kacper Kuryllo

    Terrain lighting

    What really confuses me is how all 3 corners of each triangle are shaded dark and two of the edges are dark as expected, but the one edge (the one across the middle of the quad) is shaded light. Strange enough if I make it display only wireframe all 3 edges are dark are expected Could it have something to do with how opengl iterpolates between the points? Maybe there's an opengl state I need to tweek?
  7. Kacper Kuryllo

    Terrain lighting

    Oh turns out I already am doing per-pixel lighting. I pass normals to the vertex shader which interpolates them when passing to the fragment shader. Then I calculating the lighting per-pixel in the fragment shader using the interpolated normals. I wasn't aware that there was any other way to do it...
  8. Kacper Kuryllo

    Terrain lighting

    Hmmm I don't like to disagree with someone helpful enough to post a response, but unless there is an error in my code, I believe I am calculating it per triangle. At least that was my intention when I wrote the code... [color=#000000]pow[color=#666600]([color=#000000]sheet_size [color=#666600]- [color=#006666]1[color=#666600], [color=#006666]2[color=#666600]) [color=#666600]* [color=#006666]2 gives the number of triangles not quads. i.e. number of quads * 2. Then I use the index values (which represent triangles) to set the vertex values prior to computing the cross-product... So I should be calculating it per triangle if my code is correct. Unless there's an error you can find which accidently results in it actually being per quad... Maybe I gave that impression since I have comments refering to "squares at top left" etc... That's just used to consider the position of the vertex so I don't go out of bounds on the edges. What I sum up are the normals of the two triangles. At least that's what I intended. Please let me know if there is some code accidently making me calculate or sum up quad normals instead... I will check out per-pixel lighting however
  9. Kacper Kuryllo

    Terrain lighting

    Hi so I've been trying to calculate normals and lighting for randomly generated terrain. Largely the process has been sucessful however I have notice one odd effect. If you look at the picture below you will see that I get an odd checker effect on the terrain on poorly lit portions. [attachment=8868:Untitled.jpg] The edges appear dark but the center is bright. I believe this to be an issue with calculation of the surface normals. To test this I have disabled lighting and output the normals as color in my fragment shader. I see the same effect. Here's the code I use to calculate the surface normals. Vert normalizeVert(Vert old_vert) { Vert new_vert; float old_length; old_length = sqrt(pow(old_vert.xcorr, 2.0f) + pow(old_vert.ycorr, 2.0f) + pow(old_vert.zcorr, 2.0f)); new_vert.xcorr = old_vert.xcorr / old_length; new_vert.ycorr = old_vert.ycorr / old_length; new_vert.zcorr = old_vert.zcorr / old_length; return new_vert; } ; // Calculate normals for terrain. void NSheet::calculateNormals(void) { // First create an object to store all the surface normals unsigned int num_surfaceNormals = pow(sheet_size - 1, 2) * 2; Vert* surfaceNormals = new Vert[num_surfaceNormals]; Face* faces = amesh->faces; // temporary vertices used in calculation Vert vert1, vert2, vert3, temp_vert; //retrieve pointer to indices unsigned int* indices = faces->indices; // retrieve pointer to mesh data float* verts = faces->verts; // compute all surface normals for (unsigned int i = 0; i < num_surfaceNormals; i++) { vert1.xcorr = verts[indices[i * 3 + 0] * 4 + 0]; vert1.ycorr = verts[indices[i * 3 + 0] * 4 + 1]; vert1.zcorr = verts[indices[i * 3 + 0] * 4 + 2]; vert2.xcorr = verts[indices[i * 3 + 1] * 4 + 0]; vert2.ycorr = verts[indices[i * 3 + 1] * 4 + 1]; vert2.zcorr = verts[indices[i * 3 + 1] * 4 + 2]; vert3.xcorr = verts[indices[i * 3 + 2] * 4 + 0]; vert3.ycorr = verts[indices[i * 3 + 2] * 4 + 1]; vert3.zcorr = verts[indices[i * 3 + 2] * 4 + 2]; // Calculate surface normal. % overloaded to produce cross product surfaceNormals = (vert2 - vert1) % (vert3 - vert1); // normalize surface normal surfaceNormals = normalizeVert(surfaceNormals); } // create an array to hold vertex normal data faces->num_normals = pow(sheet_size, 2) * 3; amesh->num_normals = faces->num_normals; faces->normals = new float[faces->num_normals]; // This variable represents that distance in the normal array between y units in the array of surface normals unsigned int y_step = 2 * (sheet_size - 1); // calculate the normal values for each vertex for (unsigned int i = 0; i < sheet_size; i++) for (unsigned int j = 0; j < sheet_size; j++) { // the current location in the surface normal array unsigned int displacement = i * y_step + j * 2; // the current location in the vertex normal array unsigned int vertex_displacement = (i * sheet_size + j) * 3; // blank the temp vertex temp_vert.xcorr = 0.0f; temp_vert.ycorr = 0.0f; temp_vert.zcorr = 0.0f; // average the vertices for the surrounding polygons if (i > 0 && j < sheet_size - 1) { // if has square at top right temp_vert = temp_vert + (surfaceNormals[displacement - y_step] * 2); } if (i > 0 && j > 0) { // if has square at top left temp_vert = temp_vert + surfaceNormals[displacement - y_step - 2] + surfaceNormals[displacement - y_step - 1]; } if (i < sheet_size - 1 && j < sheet_size - 1) { // if has square at bottom right temp_vert = temp_vert + surfaceNormals[displacement] + surfaceNormals[displacement + 1]; } if (i < sheet_size - 1 && j > 0) { // if square at bottom left temp_vert = temp_vert + (surfaceNormals[displacement - 1] * 2); } // normalize the temporary vertex temp_vert = normalizeVert(temp_vert); // set the normal data faces->normals[vertex_displacement] = temp_vert.xcorr; faces->normals[vertex_displacement + 1] = temp_vert.ycorr; faces->normals[vertex_displacement + 2] = temp_vert.zcorr; } amesh->has_normals = true; // set to true automatically once normals are calculated // Free memory delete[] surfaceNormals; } It uses that standard method that I have seen where you calculate a surface normal for each polygon and then average those for the verts. My best guess is that my error is here somewhere but I can't figure out where... Anyways thanks for taking the time to read this post.
  • 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!