Jump to content
  • Advertisement
Sign in to follow this  
alireza.pir

OpenGL OpenGL- Render to texture- a specific area of screen

This topic is 1081 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I implemented FBO on my OpenGL Game. and Im rendering what is rendered to screen to a texture, the problem is that rendering to texture starts from lower left corner. look:

what is rendered to Default Frame Buffer:

YvN25.jpg

what is rendered to texture attached to FBO:

r7LnJ.jpg

But Where i want to be Rendered to Texture is:

d8TRv.jpg

how can i do this? here is the renderer Calass (the FBO operation is done in onDrawFrame function):

public class CurlRenderer implements GLSurfaceView.Renderer {

// Constant for requesting right page rect.
public static final int PAGE = 1;
// Set to true for checking quickly how perspective projection looks.
private static final boolean USE_PERSPECTIVE_PROJECTION = false;
// Background fill color.
private int mBackgroundColor;
// Curl meshes used for static and dynamic rendering.
private CurlMesh mCurlMesh;
private RectF mMargins = new RectF();
private CurlRenderer.Observer mObserver;
// Page rectangles.
private RectF mPageRect;
// View mode.
// Screen size.
private int mViewportWidth, mViewportHeight;
// Rect for render area.
private RectF mViewRect = new RectF();
private boolean first = true;
int[] fb, renderTex; 
int texW = 300; 
int texH = 256; 
IntBuffer texBuffer;
int[] buf = new int[texW * texH];
GL11ExtensionPack gl11ep ;
/**
* Basic constructor.
*/
public CurlRenderer(CurlRenderer.Observer observer) {
mObserver = observer;
mCurlMesh = new CurlMesh(0);
mPageRect = new RectF();
}

/**
* Adds CurlMesh to this renderer.
*/
public synchronized void addCurlMesh(CurlMesh mesh) {
mCurlMesh = mesh;
}

/**
* Returns rect reserved for left or right page. Value page should be
* PAGE_LEFT or PAGE_RIGHT.
*/
public RectF getPageRect(int page) {
if (page == PAGE) {
return mPageRect;
}
return null;
}
public void setup(GL10 gl){
fb = new int[1];
renderTex = new int[1];
// generate
((GL11ExtensionPack)gl).glGenFramebuffersOES(1, fb, 0);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glGenTextures(1, renderTex, 0);// generate texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, renderTex[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
// texBuffer = ByteBuffer.allocateDirect(buf.length*4).order(ByteOrder.nativeOrder()).asIntBuffer();
// gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,GL10.GL_MODULATE);
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, texW, texH, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_SHORT_4_4_4_4, null);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
boolean RenderStart(GL10 gl){
// Bind the framebuffer
((GL11ExtensionPack)gl).glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, fb[0]);

// specify texture as color attachment
((GL11ExtensionPack)gl).glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL10.GL_TEXTURE_2D, renderTex[0], 0);


int error = gl.glGetError();
if (error != GL10.GL_NO_ERROR) {
Log.d("err", "Background Load GLError: " + error+" ");
}
int status = ((GL11ExtensionPack)gl).glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES)
{
Log.d("err", "Background Load GLError: " + status+" ");;
return true;
}
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
return true;
}
void RenderEnd(GL10 gl){
((GL11ExtensionPack)gl).glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);

gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(GL10.GL_TEXTURE_2D, renderTex[0]);
gl.glColor4f(1,1,1,1);
gl.glDisable(GL10.GL_TEXTURE_2D);
}

@Override
public synchronized void onDrawFrame(GL10 gl) {
if(first){
int h = GLES20.glGetError();
this.setup(gl);
if(h!=0){
Log.d("ERROR", "ERROR Happend"+h+"");
}
first = false;
}
mObserver.onDrawFrame();
//glClearColor miad rangi ke maa entekhaab kardim ro tooye carde Graphic register mikone
gl.glClearColor(Color.red(mBackgroundColor) / 255f,
Color.green(mBackgroundColor) / 255f,
Color.blue(mBackgroundColor) / 255f,
Color.alpha(mBackgroundColor) / 255f);
//glClear miad oon rangi ke bala register karde boodim ro dige az buffer paak mikone
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

//miad matris ro be MabdaEsh barmigardoone, ke bAd baraye glRotate va glTranslate moshkeli ijaad nashe
//chon maa asle jaabejaa kardan hamoon baraye safhe, baste be makaane avalieye
// kaaghazemoon hast, na oon makani ke dar haale hazer gharaar dare
gl.glLoadIdentity();

if (USE_PERSPECTIVE_PROJECTION) {
gl.glTranslatef(0, 0, -6f);
}


RenderStart(gl);
mCurlMesh.onDrawFrame(gl);
RenderEnd(gl);
mCurlMesh.onDrawFrame(gl);

}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
mViewportWidth = width;
mViewportHeight = height;

float ratio = (float) width / height;
mViewRect.top = 1.0f;
mViewRect.bottom = -1.0f;
mViewRect.left = -ratio;
mViewRect.right = ratio;
updatePageRects();

gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
if (USE_PERSPECTIVE_PROJECTION) {
GLU.gluPerspective(gl, 20f, (float) width / height, .1f, 100f);
} else {
GLU.gluOrtho2D(gl, mViewRect.left, mViewRect.right,
mViewRect.bottom, mViewRect.top);
}

gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// mCurlMesh.setup(gl);
gl.glClearColor(0f, 0f, 0f, 1f);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
gl.glHint(GL10.GL_LINE_SMOOTH_HINT, GL10.GL_NICEST);
//gl.glHint(GL10.GL_POLYGON_SMOOTH_HINT, GL10.GL_NICEST);
gl.glEnable(GL10.GL_LINE_SMOOTH);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glDisable(GL10.GL_CULL_FACE);
}


/**
* Change background/clear color.
*/
public void setBackgroundColor(int color) {
mBackgroundColor = color;
}

/**
* Set margins or padding. Note: margins are proportional. Meaning a value
* of .1f will produce a 10% margin.
*/
public synchronized void setMargins(float left, float top, float right,
float bottom) {
mMargins.left = left;
mMargins.top = top;
mMargins.right = right;
mMargins.bottom = bottom;
updatePageRects();
}
/**
* Translates screen coordinates into view coordinates.
* mokhtassate ye noghte (masalan pointer Position) roye safhe ro, be moAdele mokhtasaatesh
* rooye CurlView Tabdil mikene
*/
public void translate(PointF pt) {
pt.x = mViewRect.left + (mViewRect.width() * pt.x / mViewportWidth);
pt.y = mViewRect.top - (-mViewRect.height() * pt.y / mViewportHeight);
}

/**
* Recalculates page rectangles.
*/
private void updatePageRects() {
if (mViewRect.width() == 0 || mViewRect.height() == 0) {
return;
}
/**
* @ TODO inja daghighan hamnoon kaari ke mikham, yAni size dadan be Page ro anjaam mide
* mpageRect... khode meshe va mViewRect view E layout
*/
mPageRect.set(mViewRect);
mPageRect.left += mViewRect.width() * mMargins.left;
mPageRect.right -= mViewRect.width() * mMargins.right;
mPageRect.top += mViewRect.height() * mMargins.top;
mPageRect.bottom -= mViewRect.height() * mMargins.bottom;

int bitmapW = (int) ((mPageRect.width() * mViewportWidth) / mViewRect.width());
int bitmapH = (int) ((mPageRect.height() * mViewportHeight) / mViewRect.height());
mObserver.onPageSizeChanged(bitmapW, bitmapH);

}

/**
* Observer for waiting render engine/state updates.
*/
public interface Observer {
/**
* Called from onDrawFrame called before rendering is started. This is
* intended to be used for animation purposes.
*/
public void onDrawFrame();

/**
* Called once page size is changed. Width and height tell the page size
* in pixels making it possible to update textures accordingly.
*/
public void onPageSizeChanged(int width, int height);

}
}
Edited by alireza.pir

Share this post


Link to post
Share on other sites
Advertisement

You have to set the projection and view matrices so that "your camera sees what you want to render" into the texture. You have to use glViewPort and perhaps glScissor to which area of the texture rendering goes. 

Share this post


Link to post
Share on other sites

You have to set the projection and view matrices so that "your camera sees what you want to render" into the texture. You have to use glViewPort and perhaps glScissor to which area of the texture rendering goes. 

 

Thank you haegarr you helped a lot, what exactly i want is to render all of the rendered scene in the FBO, meaning:

rfoxR.jpg

 

i have calculated the Hypothetical Rectangle (red Dots) positions. But I dont Know how to exactly render that area.

does i still have to work with projection matrix? can you give me some trick how to do so and which way should i follow exactly?

 

im sorry for my Novice questions.

Share this post


Link to post
Share on other sites


does i still have to work with projection matrix?

Yes, you still have to do a projection. In this concern an FBO is not different from the default framebuffer. Moreover, you also need to find the suitable view matrix.

 


can you give me some trick how to do so and which way should i follow exactly?

As already mentioned, you need the full MVP matrix. You can take the situation as an own scene, i.e. the sheet of paper is the only object in the world. That allows to set the camera to a standard position and orientation and to place the object somewhat in front of i onto the z axist. As a result both M and V are easy to build, where V is just the identity matrix or perhaps just some scaling.

 

Regarding P you need to know the left, right, top, bottom, near and far planes of the view volume, all this in view space (which is, if following the above, the same as the world space perhaps with the exception of scaling). Now you can build P by either setting element by element (see e.g. here for details), or use one of the usual glm or OpenGL / GLU routines. 

 

Its not clear to me how far you have progressed, and which kind of projection you use. In which co-ordinate system have you calculated the red borders?

 


im sorry for my Novice questions.

There is nothing that need to be excused here :) 

Share this post


Link to post
Share on other sites

Thanks again for your great and clear answers, i'll be working on what you said and i'll ask again if there was a problem :)

 


Its not clear to me how far you have progressed, and which kind of projection you use. In which co-ordinate system have you calculated the red borders?

 

look i made a peace of paper, its non-folded first, the user can fold it freely, what i want is to capture the whole folded paper cause i need it later as texture.

 

here is were i set projection (in on surface changed method) :

 

 

gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, mViewRect.left, mViewRect.right,
mViewRect.bottom, mViewRect.top);
gl.glMatrixMode(GL10.GL_MODELVIEW);gl.glLoadIdentity(); 

i calculated the red dots according to OpenGl view, for example if i have this paper in My scene:
(-1,-1),(-1,1),(1,-1),(1,1)


 

non-folded.png

 

 

after folding like this :

folded.png

 

i have these values for that rectangle bounding new folded mesh:
 

x1: -0.4466667833030039
y1: -0.9999999999999999
x2: 0.6626666349952657
y2: 0.6679999686921029
x3: -0.004000285912699797
y3: -1.332000031307897
x4: 1.1960000801947253
y4: 0.26799969411146873

Share this post


Link to post
Share on other sites

looks like now you haven't reset the viewport before rendering to the screen

 

gl.glViewport(0, 0, texturewidth, textureheight);

[render to texture]

gl.glViewport(0, 0, screenwidth, screenheight);

[render texture to screen]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!