PDA

View Full Version : Ask for example of rendering to texture and then sample using shader



newbiecow
12-29-2012, 10:04 AM
I have tried to code in such case, render to texture and then sample using shader but failed due to missing something I guess.
Can anyone provide an example of this case, as simple as possible or give a linkage to such source for downloading.

cireneikual
12-29-2012, 10:58 AM
It requires a bit too much code to display on these forums, so here is a link to some classes from my engine:

FBO in https://github.com/222464/EvolvedVirtualCreaturesRepo/tree/master/VirtualCreatures/Volumetric_SDL/Source/Renderer/BufferObjects
Shader in https://github.com/222464/EvolvedVirtualCreaturesRepo/tree/master/VirtualCreatures/Volumetric_SDL/Source/Renderer/Shader

Render to the FBO, and then set it's texture in the shader (SetShaderTexture).

Dark Photon
12-29-2012, 07:43 PM
Web-search for:

glGenFramebuffer
glBindFramebuffer
glFramebufferTexture2D
...

for the render-to-texture. For instance, here's a random hit from the discussion boards on this site: link (http://www.opengl.org/discussion_boards/showthread.php/174752-Rendering-the-depth-buffer-to-a-texture-in-a-FBO).

For the sampler-using-shader piece, just glBindTexture the texture handle to a texture unit, set the texture unit number on the sampler2D, sampler2D, or other sampler uniform with glUniform1i, and sample in the shader with texture(), texelFetch(), or whatever your favorite GLSL texture sampling function is.

Note that if you use an old pre-GLSL 1.3 version (via "#version ###" in your shader, or by not even specifying a #version that's >= 130), then your texture sampling functions will have the sampler type in them (e.g. texture2D(), shadow2D(), etcetc.), but in GLSL 1.3 this was all simplified to texture().

Take a good stab at, and if questions, post your code -- we'll help you out. When doing this the first time, don't forget to check for GL errors after each call -- that can find many problems. For instance, call this periodically to see if a GL error was tripped sometime since the last check:


void check( const char hdr[] = "" )
{
int err;

while ( ( err = glGetError() ) != GL_NO_ERROR )
fprintf( stderr, "OpenGL Error at %s: %s\n", hdr, gluErrorString(err) );
}

newbiecow
12-29-2012, 09:13 PM
OK. I now put my code here.



//----------------------------------------------------------------------------------------
//Here is our initialization of shader in Cg language (Because I'm using Cg language also)

myCgContext = cgCreateContext();
checkForCgError("creating context");
cgGLSetDebugMode(CG_FALSE);
cgSetParameterSettingMode(myCgContext, CG_DEFERRED_PARAMETER_SETTING);

myCgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
cgGLSetOptimalOptions(myCgVertexProfile);
checkForCgError("selecting vertex profile");

myCgVertexProgram =
cgCreateProgramFromFile(
myCgContext, /* Cg runtime context */
CG_SOURCE, /* Program in human-readable form */
myVertexProgramFileName, /* Name of file containing program */
myCgVertexProfile, /* Profile: OpenGL ARB vertex program */
myVertexProgramName, /* Entry function name */
NULL); /* No extra compiler options */
checkForCgError("creating vertex program from file");
cgGLLoadProgram(myCgVertexProgram);
checkForCgError("loading vertex program");

/* No uniform vertex program parameters expected. */

myCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
cgGLSetOptimalOptions(myCgFragmentProfile);
checkForCgError("selecting fragment profile");

myCgFragmentProgram =
cgCreateProgramFromFile(
myCgContext, /* Cg runtime context */
CG_SOURCE, /* Program in human-readable form */
myFragmentProgramFileName, /* Name of file containing program */
myCgFragmentProfile, /* Profile: OpenGL ARB vertex program */
myFragmentProgramName, /* Entry function name */
NULL); /* No extra compiler options */
checkForCgError("creating fragment program from file");
cgGLLoadProgram(myCgFragmentProgram);
checkForCgError("loading fragment program");

myCgFragmentParam_decal =
cgGetNamedParameter(myCgFragmentProgram, "decal");
checkForCgError("getting decal parameter");

//--------------------------------------------------------------------------------------------

GLuint toTexture;

glGenTextures(1,&toTexture);
glBindTexture(GL_TEXTURE_2D,toTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,FINAL_WIDTH,F INAL_HEIGHT,0,GL_RGB,GL_UNSIGNED_BYTE,NULL);

GLuint texFramebuffer;
glGenFramebuffers(1,&texFramebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,texFramebuff er);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,GL_COLO R_ATTACHMENT0,GL_TEXTURE_2D,toTexture,0);

glEnable(GL_TEXTURE_2D);
glDrawPixels(FINAL_WIDTH,FINAL_HEIGHT,GL_RED,GL_UN SIGNED_BYTE,pboImageStore); /*Here pboImageStore is the image pixels.*/
glDisable(GL_TEXTURE_2D);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* Tightly packed texture data. */
glBindTexture(GL_TEXTURE_2D,toTexture);

glGetTexImage(GL_TEXTURE_2D,0,GL_RED,GL_UNSIGNED_B YTE,pboImageRead); /*This line just for test to have found the texture is

really rendered.*/

glGenerateMipmap(toTexture);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);

//--------------------------------------------------------------------------------------
//Load shaders (I'm also using Cg language shader)

cgGLBindProgram(myCgVertexProgram);
checkForCgError("binding vertex program");

cgGLEnableProfile(myCgVertexProfile);
checkForCgError("enabling vertex profile");

cgGLBindProgram(myCgFragmentProgram);
checkForCgError("binding fragment program");

cgGLEnableProfile(myCgFragmentProfile);
checkForCgError("enabling fragment profile");

//---------------------------------------------------------------------------------------
//Bind the drew picture for shader processing

cgGLSetTextureParameter(myCgFragmentParam_decal, toTexture);
checkForCgError("setting decal 2D texture");

cgGLEnableTextureParameter(myCgFragmentParam_decal );
checkForCgError("enable decal texture");

//---------------------------------------------------------------------------------------
//Draw the image

glBegin(GL_QUADS);
glVertex2f(-1, -1);

glVertex2f(1, -1);

glVertex2f(1, 1);

glVertex2f(-1, 1);
glEnd();

//----------------------------------------------------------------------------------------
//Unload shader

cgGLDisableProfile(myCgVertexProfile);
checkForCgError("disabling vertex profile");

cgGLDisableProfile(myCgFragmentProfile);
checkForCgError("disabling fragment profile");

cgGLDisableTextureParameter(myCgFragmentParam_deca l);
checkForCgError("disabling decal texture");

//----------------------------------------------------------------------------------------

glBindFramebuffer(GL_READ_FRAMEBUFFER,0);

//----------------------------------------------------------------------------------------
//Read red component out from the color buffer

glReadPixels(0,0,FINAL_WIDTH,FINAL_HEIGHT,GL_RED,G L_UNSIGNED_BYTE,pboImageReadBackRed); /*To find the pixel of texture was not

rendered.*/



My shader program:

Vertex shader:


struct Output {
float4 position : POSITION;
float3 color : COLOR;
float2 texCoord : TEXCOORD0;
};

Output justpass(float2 position : POSITION,
float3 color : COLOR,
float2 texCoord : TEXCOORD0)
{
Output OUT;

OUT.position = float4(position,0,1);
OUT.color = color;
OUT.texCoord = texCoord;

return OUT;
}



Fragment shader:


struct Output {
float4 color : COLOR;
};

Output texture(float2 texCoord : TEXCOORD0,
uniform sampler2D decal : TEX0)
{
Output OUT;
OUT.color = tex2D(decal,texCoord);
return OUT;
}


Can anyone fix this bug? Thanks in advance.
:doh:

Dark Photon
12-30-2012, 06:33 AM
Can anyone fix this bug?

What's the bug? You need to do the analysis and give us some details. What works -- what doesn't -- what have you discovered in trying to find the bug -- etc.

Also, are these shaders you posted for 1) rendering to the texture via FBO, or 2) reading back from it in the shader? They certainly don't go with your drawing code, which does not set any varying texture coordinates -- they only set vertex positions.

newbiecow
12-30-2012, 07:04 AM
What's the bug? You need to do the analysis and give us some details. What works -- what doesn't -- what have you discovered in trying to find the bug -- etc.

Also, are these shaders you posted for 1) rendering to the texture via FBO, or 2) reading back from it in the shader? They certainly don't go with your drawing code, which does not set any varying texture coordinates -- they only set vertex positions.


OK.

After I modified the following code block as


glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(-1, -1);

glTexCoord2f(1, 0);
glVertex2f(1, -1);

glTexCoord2f(1, 1);
glVertex2f(1, 1);

glTexCoord2f(0, 1);
glVertex2f(-1, 1);
glEnd();


There is still nothing was read from the final result or the texture was not mapped at all.

Can you please explain why?

newbiecow
12-31-2012, 02:15 AM
Why nobody answers? Is it a really hard question?

Dark Photon
12-31-2012, 04:10 PM
Well, beyond the fact that it's holiday break and probably fewer folks are reading the forums, I think it has a lot to do with that you don't seem to have tried to figure out the problem yourself at all. Seems like you just pasted some code and asked folks to fix your bug(s). You need to do some digging yourself -- try some things, read, see if you can make progress. Ask specific questions about OpenGL and how to use it -- don't just ask folks to fix your code.

The code you did paste isn't even a stand-alone test prog so the bug could be in code you didn't provide. Also, it uses Cg, whereas most folks here use OpenGL's shading language (GLSL). There is an NVidia Cg/CgFX forum here (https://devtalk.nvidia.com/default/board/89/cg-and-cgfx/) for questions related to their NVidia's shading language.