• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

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. OpenGL

    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. OpenGL

    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 [CODE] 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); } [/CODE] 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[/size][/size]
  4. [quote name='tanzanite7' timestamp='1337076064' post='4940340'] 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. [/quote] 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? [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); } [/CODE]
  5. Thanks [url="http://www.gamedev.net/user/92858-tanzanite7/"][color=#284B72]tanzanite7[/color][/url] 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. [CODE] // 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; } [/CODE] 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. 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. [quote name='Batch2' timestamp='1337018608' post='4940149'] [I will check out per-pixel lighting however [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] [/quote] 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. [quote name='swiftcoder' timestamp='1336964206' post='4939947'] It's because you are averaging the vertex normals for quads, rather than triangles. Triangles by their nature are flat, but your quads are actually formed of two triangles, so they have a crease in the middle. Linear interpolation of normals on the GPU doesn't take the crease into account, so you get bright spots... The simplest solution is to convert your quads to pairs of triangles, and calculate normals per-triangle int he first pass (rather than per-quad). Even better solution is to switch to per-pixel lighting after that. [/quote] 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][color=#666600]([/color][color=#000000]sheet_size [/color][color=#666600]-[/color] [color=#006666]1[/color][color=#666600],[/color] [color=#006666]2[/color][color=#666600])[/color] [color=#666600]*[/color] [color=#006666]2[/color] 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. 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. [CODE] 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[i] = (vert2 - vert1) % (vert3 - vert1); // normalize surface normal surfaceNormals[i] = normalizeVert(surfaceNormals[i]); } // 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; } [/CODE] 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.