Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to switch shader programs in glsl
    primarykey
    data
    text
    <p>I want to do volume rendering using programmable pipeline (using glsl) and no fixed pipelines. I implement it with 2 passes with 2 shader programs, <code>exitPointProg</code> and <code>rayCastProg</code>. the first pass is to get the exit points (i.e. the back face) of a cube bounding box which will be used as a texture in the next pass which doing the raycasting. the idea to do the raycasting volume rendering comes from <a href="http://www.daimi.au.dk/~trier/?page_id=98" rel="nofollow">here</a>. I think I have done the most of the things right cause I have implemented this with fixed pipeline combined with the programmable pipeline. the things that confused me is that I achieved the result with the very first frame, and with a flash the display on the screen turn totally white (I set the <code>glClearColor(1.0f, 1.0f, 1.0f, 1.0f)</code>. I think there maybe some wrong with the switch of the shader programs or the FBO. here is what I do in the render() function.</p> <ol> <li>1st pass, render to a fbo with <code>exitPoints</code> texture bound to it to get the exit points of cube bounding box, using shader program <code>exitPointProg</code>.</li> <li><p>2ed pass, mapped the <code>exitPoints</code> texture (bound to <code>GL_TEXTURE1</code>) into the shader program <code>rayCastProg</code> as a uniform sampler2D variable which will used in the shader. here is the <code>setupFBO</code> and <code>render</code> and two subroutines: the <code>setupFBO()</code> function:</p> <pre><code>void SimpleRayCasting::setupFBO() { GLuint textureHandles[1]; glGenTextures(1, textureHandles); entryPoints = textureHandles[0]; glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, exitPoints); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL); GLuint depthRenderBuffer; glGenRenderbuffers(1, &amp;depthRenderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, depthRenderBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); glGenFramebuffers(1, &amp;frameBuffer); glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, exitPoints, 0/* level */); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderBuffer); checkFramebufferState(__FILE__, __LINE__); GLenum drawbufs[] = {GL_COLOR_ATTACHMENT0}; glDrawBuffers(1, drawbufs); glBindFramebuffer(GL_FRAMEBUFFER,0); } </code></pre> <p>the <code>render()</code> function:</p> <pre><code>void SimpleRayCasting::render() { getExitPoints(); GLUtils::checkForOpenGLError(__FILE__,__LINE__); rayCasting(); GLUtils::checkForOpenGLError(__FILE__,__LINE__); } </code></pre> <p>the <code>getExitPoints()</code> function:</p> <pre><code>void SimpleRayCasting::getExitPoints() { // render to the texture glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); glEnable(GL_DEPTH_TEST); glViewport(0, 0, width, height); // checkFramebufferState(__FILE__, __LINE__); glClearColor(0.2f, 0.2f, 0.2f, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); exitPointsProg.use(); // note that the model will recalculated. model = mat4(1.0f); model *= glm::rotate(angle , vec3(0.0f,1.0f,0.0f)); model *= glm::rotate(90.0f, vec3(1.0f, 0.0f, 0.0f)); model *= glm::translate(vec3(-0.5f, -0.5f, -0.5f)); view = glm::lookAt(vec3(0.0f,0.0f,2.0f), vec3(0.0f,0.0f,0.0f), vec3(0.0f,1.0f,0.0f)); projection = mat4(1.0f); projection = glm::perspective(60.0f, (float)width/(float)height,0.01f, 400.0f); setMatrices(exitPointsProg); glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); drawBoundBox(); glDisable(GL_CULL_FACE); glBindFramebuffer(GL_FRAMEBUFFER, 0); } </code></pre> <p>the <code>rayCasting</code> function:</p> <pre><code>void SimpleRayCasting::rayCasting() { // Directly render to the screen glBindFramebuffer(GL_FRAMEBUFFER, 0); glEnable(GL_DEPTH_TEST); glViewport(0, 0, width, height); glClearColor(1.0f, 1.0f, 1.0f, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); rayCastProg.use(); model = mat4(1.0f); model *= glm::rotate(angle, vec3(0.0f,1.0f,0.0f)); model *= glm::rotate(90.0f, vec3(1.0f, 0.0f, 0.0f)); model *= glm::translate(vec3(-0.5f, -0.5f, -0.5f)); view = glm::lookAt(vec3(0.0f,0.0f,2.0f), vec3(0.0f,0.0f,0.0f), vec3(0.0f,1.0f,0.0f)); projection = mat4(1.0f); projection = glm::perspective(60.0f, (float)width/(float)height,0.01f, 400.0f); setMatrices(rayCastProg); rayCastProg.setUniform("StepSize", stepSize); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, exitPoints); rayCastProg.setUniform("ExitPoints", 1); glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_3D, volume_to); rayCastProg.setUniform("VolumeTex", 4); glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_1D, transferFunc_to); rayCastProg.setUniform("TransferFunc", 5); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); drawBoundBox(); glDisable(GL_CULL_FACE); glBindFramebuffer(GL_FRAMEBUFFER, 0); } </code></pre> <p>I am using a class inherited from QGLWidget in Qt. As I have mentioned early, I got the right result with just the 1st frame and quickly it flash away and turn totally white. I don't know what's wrong with this, is there something wrong with the switch of the shader program or the FBO thing? I have been working on this a long time and can't figure it out, any help will be appreciated!</p></li> </ol> <p><strong>edit to ask</strong> is there any demo or tutorial demonstrate how to use multiple glsl shader programs with FBO?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload