Sign in to follow this  
dvlfrnd

OpenGL opengl/malloc beginner

Recommended Posts

dvlfrnd    127
hi, im trying to learn C and openGL,i gave myself an assignment for no spesific purpose,but then came across a problem. the program might not make sense,its purpose is to teach me pointers and malloc,,there is probably a way better way to solve it,but since im learning,i have to know if im on the right track. my funky program uses glut to open a window,fills it black etc.. follow from here: dragging the mouse creates white points on the screen. so im drawing a smiley face,which is represented by white dots on screen. goal: when i type 's' on the keyboard, all the points that i drew should be connected by GL_LINES my path: first i thought i should collect all the point coordinates.because the lines arent drawn right away,they are only drawn if the user asks for it.so they have to be stored somewhere. important key factor is speed, while gathering the point coordinates,the function that stores the points should be fast enough,so that it wont miss anything while trying to store things. at first i made two simple int arrays.but then realised their size would be limited. and would require lots of ram that the user might now even facilitate. so i tried to implement it with malloc: there is a struct called pointcoord. struct pointcoord { int *chunkX; int *chunkY; struct pointcoord *next; struct pointcoord *prev; }; chunkX and Y store the coordinates of the mouse while its being dragged. then we have these babies: struct pointcoord *handle1,*handle2; when the program starts, they are initialised: handle1=handle2=NULL; handle1 = (struct pointcoord *)malloc(sizeof(struct pointcoord)); handle1->chunkX = (int *)malloc(POINT_BUFFER_SIZE * sizeof(int)); handle1->chunkY = (int *)malloc(POINT_BUFFER_SIZE * sizeof(int)); handle1->prev = NULL; POINT_BUFFER_SIZE defines when the program needs to allocate more ram to store more point data. in our example it shall be 16, which means, when the program first starts, it allocates enough space to hold,16 x and 16 y coordinates. total 32. what happens if the user draws something that consists of more than 16 points, (a smiley face for example) well i thought,while drawing,if the buffer size is exceeded,handle1 and handle2 should switch places,and handle1 should allocate more ram for the pointcoord structure. after that handle1 is linked back to handle2 heres the function: void gatherPoints(int x,int y) { if (point_count < POINT_BUFFER_SIZE) { (handle1->chunkX)[point_count] = x; (handle1->chunkY)[point_count] = y; } else { point_count = 0; handle2 = handle1; handle1 = (struct pointcoord *)malloc(sizeof(struct pointcoord)); handle1->chunkX = (int *)malloc(POINT_BUFFER_SIZE * sizeof(int)); // point data will be stored here handle1->chunkY = (int *)malloc(POINT_BUFFER_SIZE * sizeof(int)); // point data will be stored here handle2->next = handle1; handle1->prev = handle2; (handle1->chunkX)[point_count] = x; (handle1->chunkY)[point_count] = y; } point_count++; } upon user's request for drawing, this function is called (partial) while (handle1->prev != NULL) { for (i=point_count-1;i>=1;i--){ //draw here with x and y glBegin(GL_LINES); glLoadIdentity(); x = (handle1->chunkX)[i]; y = (handle1->chunkY)[i]; glVertex2f(x,480.0-y); glLoadIdentity(); x = (handle1->chunkX)[i-1]; y = (handle1->chunkY)[i-1]; glVertex2f(x,480.0-y); glLoadIdentity(); glEnd(); glutPostRedisplay(); } handle2 = handle1; handle1 = handle1->prev; point_count = POINT_BUFFER_SIZE; free(handle2); handle2 = NULL; } well,result is,the program works as expected. but there is a problem,and thats why im here bugging you. the lines that are being drawn, have little gaps between them. if i increase the buffer size, they occur less frequently. and the buffer size should be a much bigger value,im aware of that,but,how do i prevent this? i counted the points,and gaps occur at the exact number where the allocation occurs.. for ex: buffer size = 16 i draw smtg that has more than 16 points ----- ----- ----- ------ -------- it looks like this. -------------------------------- but it should look like this the reason behind this is probably the time spent to allocate data.(???) while the function gatherpoints, is allocating more ram,it is missing some of the points,because the user is still drawing.(???) the problem is obvious(???),so how do i make it work without missing any points. any other approaches to this problem are welcome,but i'd rather like to hear,how to fix this particular thing. i thought about utilizing some an idle function,but still,if the user is 3 yrs old,and keeps drawing forever without taking a break, no matter how big the buffer is,the gaps will occur. when the buffer is around 512-1024, it is acceptable,the gaps are rarely seen. i think this actually cant be solved unless its approached with a different view,coz ultimately,memory will be allocated some time in the program. so the solution is either finding a way to allocate memory faster,or preemptively allocate memory when idle(which isnt our case,think about the obsessed 3 yr old guy drawing for 10 mins without releasing them mouse button) anyway, im not very experienced and all help,+/- criticism is appreciated

Share this post


Link to post
Share on other sites
Palidine    1315
not related to your problem:

you're leaking memory. you're calling free on the handle's but not on the chunkX and chunkY member variables of the struct. C does _not_ "do the right thing" it only does exactly what you told it.

you should have:

free(handle2->chunkX);
free(handle2->chunkY);
free(handle2);


perhaps related to your problem:

Been a while since i openGL'd, but i think the glBegin and glEnd calls should be _outside_ your for loop. right now you're creating a new line with each iteration rather than one continuous line.

certainly the glutPostRedisplay should be outside the for loop. dunno what calling that multiple times per frame does. this could be more of a problem than the previous paragraph. but i don't know glut at all.

-me

Share this post


Link to post
Share on other sites
Palidine    1315
And not that it should have an effect but you are making excessive number of calls to glLoadIdentity. There's no need to have more than one call to that given your code; and it should be outside the for loop.

And as a word of advice: learning pointers _and_ graphics at the same time might end up being very confusing. Generally you should already have a firm grasp of pointers before starting graphics; graphics tends to use them all over the place, so if you don't already know them the coding is going to hurt your brain. But that's just advice, it's certainly possible the route you're going just a lot more difficult.

-me

Share this post


Link to post
Share on other sites
dvlfrnd    127
Quote:
Original post by Palidine
not related to your problem:
you're leaking memory. you're calling free on the handle's but not on the chunkX and chunkY member variables of the struct. C does _not_ "do the right thing" it only does exactly what you told it.

you should have:

free(handle2->chunkX);
free(handle2->chunkY);
free(handle2);

-me


that is a very important thing indeed,thanks for pointing that out!
i never considered freeing the chunks

Quote:
Original post by Palidine
perhaps related to your problem:

Been a while since i openGL'd, but i think the glBegin and glEnd calls should be _outside_ your for loop. right now you're creating a new line with each iteration rather than one continuous line.

-me


i think you are right, i noticed a detail that might be causing this;

point_count = POINT_BUFFER_SIZE;

it starts reading from the last buffer to the first.
so it draws backwards,
gap might be occuring,coz the loop is jumping from buffer to buffer.

draw buffer2 16,15,14,13...2,1,0 // this is the way buffers are drawn
draw buffer1 16,15,14....0

a continuous line would be (imagine we have a connect function)

connect(buffer2.point[0],buffer1.point[16]);

it might be skipping that first point of buffer2 and last point of buffer1,not connecting them

i will inspect it, THANK YOU!
and sorry for blaming malloc with me being the actual bug :)





Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Similar Content

    • By Kjell Andersson
      I'm trying to get some legacy OpenGL code to run with a shader pipeline,
      The legacy code uses glVertexPointer(), glColorPointer(), glNormalPointer() and glTexCoordPointer() to supply the vertex information.
      I know that it should be using setVertexAttribPointer() etc to clearly define the layout but that is not an option right now since the legacy code can't be modified to that extent.
      I've got a version 330 vertex shader to somewhat work:
      #version 330 uniform mat4 osg_ModelViewProjectionMatrix; uniform mat4 osg_ModelViewMatrix; layout(location = 0) in vec4 Vertex; layout(location = 2) in vec4 Normal; // Velocity layout(location = 3) in vec3 TexCoord; // TODO: is this the right layout location? out VertexData { vec4 color; vec3 velocity; float size; } VertexOut; void main(void) { vec4 p0 = Vertex; vec4 p1 = Vertex + vec4(Normal.x, Normal.y, Normal.z, 0.0f); vec3 velocity = (osg_ModelViewProjectionMatrix * p1 - osg_ModelViewProjectionMatrix * p0).xyz; VertexOut.velocity = velocity; VertexOut.size = TexCoord.y; gl_Position = osg_ModelViewMatrix * Vertex; } What works is the Vertex and Normal information that the legacy C++ OpenGL code seem to provide in layout location 0 and 2. This is fine.
      What I'm not getting to work is the TexCoord information that is supplied by a glTexCoordPointer() call in C++.
      Question:
      What layout location is the old standard pipeline using for glTexCoordPointer()? Or is this undefined?
       
      Side note: I'm trying to get an OpenSceneGraph 3.4.0 particle system to use custom vertex, geometry and fragment shaders for rendering the particles.
    • By markshaw001
      Hi i am new to this forum  i wanted to ask for help from all of you i want to generate real time terrain using a 32 bit heightmap i am good at c++ and have started learning Opengl as i am very interested in making landscapes in opengl i have looked around the internet for help about this topic but i am not getting the hang of the concepts and what they are doing can some here suggests me some good resources for making terrain engine please for example like tutorials,books etc so that i can understand the whole concept of terrain generation.
       
    • By KarimIO
      Hey guys. I'm trying to get my application to work on my Nvidia GTX 970 desktop. It currently works on my Intel HD 3000 laptop, but on the desktop, every bind textures specifically from framebuffers, I get half a second of lag. This is done 4 times as I have three RGBA textures and one depth 32F buffer. I tried to use debugging software for the first time - RenderDoc only shows SwapBuffers() and no OGL calls, while Nvidia Nsight crashes upon execution, so neither are helpful. Without binding it runs regularly. This does not happen with non-framebuffer binds.
      GLFramebuffer::GLFramebuffer(FramebufferCreateInfo createInfo) { glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); textures = new GLuint[createInfo.numColorTargets]; glGenTextures(createInfo.numColorTargets, textures); GLenum *DrawBuffers = new GLenum[createInfo.numColorTargets]; for (uint32_t i = 0; i < createInfo.numColorTargets; i++) { glBindTexture(GL_TEXTURE_2D, textures[i]); GLint internalFormat; GLenum format; TranslateFormats(createInfo.colorFormats[i], format, internalFormat); // returns GL_RGBA and GL_RGBA glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, createInfo.width, createInfo.height, 0, format, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); DrawBuffers[i] = GL_COLOR_ATTACHMENT0 + i; glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, textures[i], 0); } if (createInfo.depthFormat != FORMAT_DEPTH_NONE) { GLenum depthFormat; switch (createInfo.depthFormat) { case FORMAT_DEPTH_16: depthFormat = GL_DEPTH_COMPONENT16; break; case FORMAT_DEPTH_24: depthFormat = GL_DEPTH_COMPONENT24; break; case FORMAT_DEPTH_32: depthFormat = GL_DEPTH_COMPONENT32; break; case FORMAT_DEPTH_24_STENCIL_8: depthFormat = GL_DEPTH24_STENCIL8; break; case FORMAT_DEPTH_32_STENCIL_8: depthFormat = GL_DEPTH32F_STENCIL8; break; } glGenTextures(1, &depthrenderbuffer); glBindTexture(GL_TEXTURE_2D, depthrenderbuffer); glTexImage2D(GL_TEXTURE_2D, 0, depthFormat, createInfo.width, createInfo.height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthrenderbuffer, 0); } if (createInfo.numColorTargets > 0) glDrawBuffers(createInfo.numColorTargets, DrawBuffers); else glDrawBuffer(GL_NONE); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) std::cout << "Framebuffer Incomplete\n"; glBindFramebuffer(GL_FRAMEBUFFER, 0); width = createInfo.width; height = createInfo.height; } // ... // FBO Creation FramebufferCreateInfo gbufferCI; gbufferCI.colorFormats = gbufferCFs.data(); gbufferCI.depthFormat = FORMAT_DEPTH_32; gbufferCI.numColorTargets = gbufferCFs.size(); gbufferCI.width = engine.settings.resolutionX; gbufferCI.height = engine.settings.resolutionY; gbufferCI.renderPass = nullptr; gbuffer = graphicsWrapper->CreateFramebuffer(gbufferCI); // Bind glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); // Draw here... // Bind to textures glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, textures[2]); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, depthrenderbuffer); Here is an extract of my code. I can't think of anything else to include. I've really been butting my head into a wall trying to think of a reason but I can think of none and all my research yields nothing. Thanks in advance!
    • By Adrianensis
      Hi everyone, I've shared my 2D Game Engine source code. It's the result of 4 years working on it (and I still continue improving features ) and I want to share with the community. You can see some videos on youtube and some demo gifs on my twitter account.
      This Engine has been developed as End-of-Degree Project and it is coded in Javascript, WebGL and GLSL. The engine is written from scratch.
      This is not a professional engine but it's for learning purposes, so anyone can review the code an learn basis about graphics, physics or game engine architecture. Source code on this GitHub repository.
      I'm available for a good conversation about Game Engine / Graphics Programming
    • By C0dR
      I would like to introduce the first version of my physically based camera rendering library, written in C++, called PhysiCam.
      Physicam is an open source OpenGL C++ library, which provides physically based camera rendering and parameters. It is based on OpenGL and designed to be used as either static library or dynamic library and can be integrated in existing applications.
       
      The following features are implemented:
      Physically based sensor and focal length calculation Autoexposure Manual exposure Lense distortion Bloom (influenced by ISO, Shutter Speed, Sensor type etc.) Bokeh (influenced by Aperture, Sensor type and focal length) Tonemapping  
      You can find the repository at https://github.com/0x2A/physicam
       
      I would be happy about feedback, suggestions or contributions.

  • Popular Now