I've been having a odd issue while using the render the texture feature.
I've copied the code from the examples (the radial blur example) that came with libgl and I'm rendering the texture into a quad (using ortho projection).
I'm initializing the texture just like the example and, if I comment out the call to
Code: Select all
glutCopyBufferToTexture(RENDER_TEXTURE, &RENDER_TEXTURE_W, &RENDER_TEXTURE_H);
I must note that the function above is only called AFTER i send all the geometry out (via direct mode or vertex arrays)
When the code above is uncommented, well, odd behavior is observed.
(Is there some form of flushing that I'm not aware of ?)
The quad only appears mid scene, and sometimes it just vanishes and reappears some seconds later.
This is the expected behavior :
This occurs mid scene :
This is the following (relevant) code :
Spoiler!
Code: Select all
#include <kos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <sys/time.h>
#include <time.h>
#include <sys/time.h>
//#include <arch/time.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <pcx/pcx.h>
#include <math.h>
#include "data_estructures.h"
//to be removed as soon as the scene and asset loader are put into order
//#include "obj_loader.h"
//#include "pcx_loader.h"
void pmesh_draw_array();
void pmesh_draw(pmesh p);
void pmesh_draw_test();
void draw_p(pmesh m);
extern pDemoAssetList demo_content;
//pvr_stats_t stats;
// RENDER TO TEXTURE TEST
static pvr_ptr_t *RENDER_TEXTURE = NULL; /* PVR Memory Pointer for Render-To-Texture result */
static GLuint RENDER_TEXTURE_ID; /* Render-To-Texture GL Texture ID */
static long unsigned int RENDER_TEXTURE_W; /* Render-To-Texture width */
static long unsigned int RENDER_TEXTURE_H; /* Render-To-Texture height */
extern GLuint glTextureLoadPVR(char *fname, unsigned char isMipMapped, unsigned char glMipMap);
void InitRenderTexture(long unsigned int width, long unsigned int height) {
/* 1.) Allcoate PVR Texture Memory for Render-To-Texture */
RENDER_TEXTURE_W = width;
RENDER_TEXTURE_H = height;
RENDER_TEXTURE = pvr_mem_malloc(RENDER_TEXTURE_W * RENDER_TEXTURE_H * 2);
/* 2.) Generate a texture for Open GL, and bind that texxture */
glGenTextures(1, &RENDER_TEXTURE_ID);
glBindTexture(GL_TEXTURE_2D, RENDER_TEXTURE_ID);
/* 3.) Use glKosTexImage2D() to bind the texture address for the Render-To-Texture */
glKosTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
RENDER_TEXTURE_W, RENDER_TEXTURE_H, 0,
PVR_TXRFMT_NONTWIDDLED, PVR_TXRFMT_RGB565, RENDER_TEXTURE);
/* 4.) Enable GL_LINEAR Texture Filter to enable the PVR's bilinear filtering */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FILTER, GL_LINEAR);
}
//void RTT_test(pDemoAssetList d, char* font_name) //Render to Texture Test
void RTT_test(GLuint a, pDemoAssetList d) //Render to Texture Test
{
// int curr_texture_pos = getTexturePos(d->t, "checkerboard");
// int curr_texture = retrieveTextureHandle(d->t, curr_texture_pos);
// glBindTexture(GL_TEXTURE_2D, curr_texture);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, a);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
//glLoadIdentity();
glOrtho(0,640,0,480, -1,1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// glLoadIdentity();
// glEnable(GL_BLEND); // Enable Blending
// glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Set Blending Mode
glBegin(GL_QUADS); // Draw A Quad
glTexCoord2f(0,0);
glVertex2f(0,0); // Top Left
glTexCoord2f(1,0);
glVertex2f( 256, 0);
glTexCoord2f(1,1); // Top Right
glVertex2f( 256,256);
glTexCoord2f(0,1); // Bottom Right
glVertex2f(0,256);
// Bottom Left
glEnd(); // Done Drawing The Quad
glBegin(GL_QUADS); // Draw A Quad
glTexCoord2f(1,0);
glVertex2f(512,0); // Top Left
glTexCoord2f(0,0);
glVertex2f( 256, 0);
glTexCoord2f(0,1); // Top Right
glVertex2f( 256,256);
glTexCoord2f(1,1); // Bottom Right
glVertex2f(512,256);
// Bottom Left
glEnd();
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPopMatrix(); // Restore The Old Projection Matrix
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glPopMatrix(); // Restore The Old Projection Matrix
// glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
}
//
void gridDraw(pmesh mesh, pmesh grid, pDemoAssetList asl)
{
int i = 0 ;
vec3* iter_ptr = grid->vertex_data ; // to make the syntax more tolerable
float z_value = 0.0f ;
int x_iter = 0;
int y_iter = 0;
for( x_iter = 0 ; x_iter < grid->indices_count ; x_iter++)
{
for (y_iter = 0 ; y_iter < grid->uv_count ; y_iter++ )
{
z_value = 7 * fsin(asl->milisec_elapsed * 0.0009 + (iter_ptr[i].x / 5) ) ;
//z_value = fsin(asl->milisec_elapsed * 0.0005 + iter_ptr[i].x) + fcos(asl->milisec_elapsed * 0.0005 + iter_ptr[i].y) ;
//z_value = fsin(iter_ptr[i].x * iter_ptr[i].y * i) ;
glPushMatrix();
// glScalef(0.5, 0.5, 0.5);
glTranslatef(iter_ptr[i].x, iter_ptr[i].y , z_value);
//printf("t : x : %f, y: %f i : %d \n ", iter_ptr[i].x, iter_ptr[i].y, i);
draw_p(mesh);
glPopMatrix();
i++;
}
}
}
inline float new_width(const float fwsize,const float fhsize,const float req_size_w)
{
if(fwsize == 0)
{
return 0 ;
}
if(fhsize == 0)
{
return 0 ;
}
return (float) (req_size_w * fwsize) / fhsize ;
}
inline float new_height(const float f_old_wsize,const float f_new_wsize,const float f_height)
{
if(f_old_wsize == 0)
{
return 0 ;
}
if(f_new_wsize == 0)
{
return 0 ;
}
return (float) (f_height * f_new_wsize) / f_old_wsize ;
}
pTexFontList getTexFont(pTexFontList p, char* a)
{
pTexFontList curr = p ;
for (curr = p ; curr != NULL ; curr = curr->next)
{
if ( strcmp(curr->name, a) == 0 )
{
// printf("\n seeking : %s ; %s found \n",curr->name, a);
return curr ;
}
}
return p ; // if nothing was found......
}
void print_text(pDemoAssetList d, char* font_name, char* txt, int xpos, int ypos, const float scale)
{
int curr_texture_pos = getTexturePos(d->t, font_name);
int curr_texture = retrieveTextureHandle(d->t, curr_texture_pos);
int tex_w = retrieveTextureWidth(d->t, curr_texture_pos);
int tex_h = retrieveTextureHeight(d->t, curr_texture_pos);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, curr_texture);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0,640,0,480, -1,1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
int txt_len = strlen(txt);
int i = 0 ;
unsigned int c ;
float cursor = 0;
float n_width = 0 ;
float n_height = 0.5 ;
float spacing = 5 ;
float uv_x, uv_y, uv_wx, uv_wy;
vec2 uv_up_l, uv_up_r;
vec2 uv_bottom_r, uv_bottom_l;
vec2 quad_up_l, quad_up_r;
vec2 quad_down_l, quad_down_r;
pTexFontList f = getTexFont(d->f, font_name);
glBegin(GL_QUADS);
for(i = 0; i < txt_len ; i++)
{
c = txt[i];
n_width = new_width(f->charCoord[c].width, f->charCoord[c].height, scale) ;
uv_x = (f->charCoord[c].x / (float) tex_w);
uv_y = (f->charCoord[c].y / (float)tex_h);
uv_wx = ((f->charCoord[c].x + f->charCoord[c].width) / (float) tex_w) ;
uv_wy = ((f->charCoord[c].y + f->charCoord[c].height) / (float) tex_h) ;
uv_bottom_l.u = uv_x ;
uv_bottom_l.v = uv_y ;
uv_bottom_r.u = uv_wx ;
uv_bottom_r.v = uv_y ;
uv_up_r.u = uv_wx ;
uv_up_r.v = uv_wy ;
uv_up_l.u = uv_x ;
uv_up_l.v = uv_wy ;
//old uv coords
/*
uv_bottom_l.u = uv_x ;
uv_bottom_l.v = uv_wy ;
uv_bottom_r.u = uv_wx ;
uv_bottom_r.v = uv_wy ;
uv_up_r.u = uv_wx ;
uv_up_r.v = uv_y ;
uv_up_l.u = uv_x ;
uv_up_l.v = uv_y ;
*/
// quad old coords
/*
quad_up_l.u = xpos + cursor;
quad_up_l.v = ypos + (f->charCoord[c].height * scale) ;
quad_up_r.u = xpos + cursor + (f->charCoord[c].width * scale) ;
quad_up_r.v = ypos + (f->charCoord[c].height * scale);
quad_down_r.u = xpos + cursor + (f->charCoord[c].width * scale);
quad_down_r.v = ypos ;
quad_down_l.u = xpos + cursor;
quad_down_l.v = ypos;
*/
//quad new coords
quad_up_l.u = xpos + cursor;
quad_up_l.v = ypos ;
quad_up_r.u = xpos + cursor + (f->charCoord[c].width * scale) ;
quad_up_r.v = ypos ;
quad_down_r.u = xpos + cursor + (f->charCoord[c].width * scale);
quad_down_r.v = ypos - (f->charCoord[c].height * scale) ;
quad_down_l.u = xpos + cursor;
quad_down_l.v = ypos - (f->charCoord[c].height * scale) ;
// Draw A Quad
glTexCoord2f(uv_up_l.u , uv_up_l.v);
glVertex2f(quad_up_l.u , quad_up_l.v);
glTexCoord2f(uv_up_r.u , uv_up_r.v);
glVertex2f( quad_up_r.u , quad_up_r.v);
glTexCoord2f(uv_bottom_r.u , uv_bottom_r.v);
glVertex2f( quad_down_r.u , quad_down_r.v );
glTexCoord2f(uv_bottom_l.u , uv_bottom_l.v);
glVertex2f(quad_down_l.u , quad_down_l.v );
cursor = cursor + (f->charCoord[c].width * scale) + spacing;
}
glEnd();
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glPopMatrix(); // Restore The Old Projection Matrix
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glPopMatrix(); // Restore The Old Projection Matrix
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
}
// timming functions -
inline unsigned long diff_msec(uint64 start,uint64 end)
{
if(end > start)
{
return (unsigned long) (end - start);
}
else
{
return (unsigned long) (start - end);
}
}
void draw_p(pmesh p)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, p->vertex_data);
if(p->uv_data != NULL)
{
//glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, p->uv_data);
}
glDrawArrays(GL_TRIANGLES,0, p->vertex_count);
glDisableClientState(GL_VERTEX_ARRAY);
if(p->uv_data != NULL)
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
// glDisable(GL_TEXTURE_2D);
}
}
void new_draw(pDemoAssetList a)
{
// measures the time it took to render in order to keep the animation time dependent instead of frame rate dependent.
// the scene descriptor WILL get modified during the demo execution
uint64 ms_start;
uint64 ms_end;
uint64 ms_elapsed ;
// unsigned long total_render_time_ms ;
pDemoAssetList iter ;
p3DModelList m;
pTextureList t;
pSceneDescription d;
pCameraList c ;
pTransformList tr;
pmesh curr_model ;
pmesh aux_model ;
int curr_texture ;
int curr_texture_pos ;
iter = a ;
m = iter->m ; // model list
t = iter->t ; // texture list
d = iter->d ; // scene descriptor
c = iter->c ; // camera descriptor
ms_start = timer_ms_gettime64();
while(isCameraInTime(c, iter->milisec_elapsed) == 0)
{
c = c->next ; // seeks the camera in the current time frame
}
// glKosBeginFrame(); // REMOVED DUE TO PH3N0N's API
glLoadIdentity();
gluLookAt( c->start_pos.x,
c->start_pos.y,
c->start_pos.z,
c->start_looking_direction.x,
c->start_looking_direction.y,
c->start_looking_direction.z,
0.0,
0.0,
1.0 );
while (d != NULL) // goes trough all the meshes on the asset list
{
glPushMatrix();
if(d->render_effects & DRAW_WIREFRAME)
{
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
if(d->render_effects & DRAW_FLAT)
{
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
for ( tr = d->transforms ; tr != NULL ; tr = tr->next)
{
printf("CURRENT MESH \n \n");
if(tr->transformType == ROTATION)
{
printf("ROTATION APPLIED : %f %f %f %f\n", tr->scalar_val , tr->transformData.x, tr->transformData.y, tr->transformData.z);
glRotatef(tr->scalar_val , tr->transformData.x, tr->transformData.y, tr->transformData.z);
}
if(tr->transformType == TRANSLATION)
{
printf("TRANSLATION APPLIED : %f %f %f\n", tr->transformData.x, tr->transformData.y, tr->transformData.z);
glTranslatef(tr->transformData.x *1.5 , tr->transformData.y*1.5, tr->transformData.z*1.5);
}
if(tr->transformType == SCALE)
{
printf("SCALE APPLIED : %f %f %f\n", tr->transformData.x, tr->transformData.y, tr->transformData.z);
glScalef(tr->transformData.x, tr->transformData.y, tr->transformData.z);
}
}
printf("END TRANSFORMS \n");
if( !(d->render_effects & DRAW_GRID)) // regular model drawing
{
curr_texture_pos = getTexturePos(t, d->texture_name);
curr_texture = retrieveTextureHandle(t, curr_texture_pos);
glBindTexture(GL_TEXTURE_2D, curr_texture);
curr_model = retrieveMesh (m, getMeshPos(m, d->mesh_name) );
draw_p(curr_model) ;
}
else // renders a given mesh multiple times on a grid mesh
{
curr_texture_pos = getTexturePos(t, d->texture_name);
curr_texture = retrieveTextureHandle(t, curr_texture_pos);
glBindTexture(GL_TEXTURE_2D, curr_texture);
// printf("d->name : %s (%d) ; d->mesh_name %s (%d)\n",d->name, getMeshPos(m, d->name) , d->mesh_name, getMeshPos(m, d->mesh_name) );
curr_model = retrieveMesh (m, (getMeshPos(m, d->name)) ); // the grid mesh. Cant figure out WHY I must -1 on the position.
aux_model = retrieveMesh (m, getMeshPos(m, d->mesh_name) ); // the mesh to be rendered on the grid
// printf(" get_curr_model 1st arg : %s (pos : %d) \n get_aux_model 2nd arg : %s (pos : %d) \n", d->name , getMeshPos(m, d->name), d->mesh_name, getMeshPos(m, d->mesh_name) );
// printf(" curr_model 1st arg : %d\n aux_model 2nd arg : %d \n", curr_model->vertex_count, aux_model->vertex_count);
gridDraw(aux_model, curr_model, a);
}
d = d -> next ; // goes to the next element
glPopMatrix();
}
ms_end = timer_ms_gettime64();
ms_elapsed = diff_msec(ms_start, ms_end);
// HACKJOB
char hackjob[512];
hackjob[511] = 0 ;
sprintf(hackjob, "Render Time : %d ms", ms_elapsed );
print_text(a, "font_2" ,"Vollumetric Illusions Demo Framework v0.0.1", 0, 440, 0.4);
print_text(a, "font" ,hackjob, 0,400, 0.8);
glutCopyBufferToTexture(RENDER_TEXTURE, &RENDER_TEXTURE_W, &RENDER_TEXTURE_H);
RTT_test(RENDER_TEXTURE_ID, a);
glutSwapBuffers();
// glutCopyBufferToTexture(RENDER_TEXTURE, &RENDER_TEXTURE_W, &RENDER_TEXTURE_H);
iter->milisec_elapsed += ms_elapsed;
CameraListPosUpdate(iter->c, (iter->milisec_elapsed));
}
void demo_render(pDemoAssetList a)
{
InitRenderTexture(1024, 512);
while(1)
{
new_draw(a);
}
}