Новичок
Профиль
Группа: Участник
Сообщений: 4
Регистрация: 8.8.2012
Репутация: нет Всего: нет
|
Пишу для себя простенькую игру и столкнулся с проблемой. Изначально игра писалась на СИ, но потом те крохотные участки кода были перенесены на C++. В чём, собственно, проблема: не рисуются части текстур - проблема появилась после переноса. Я проверял во всех местах: никаких эксцэсов нет. Помогите, пожалуйста. файл CRender.h: Код | #include <SDL/SDL.h> #include <GL/gl.h> #include <Base.h> #ifndef CRENDER_H #define CRENDER_H
#define GFX_TASK_L0_COUNT 1024 #define GFX_TASK_L1_COUNT 128 #define GFX_TEXLOAD_COUNT 64
struct gfx_texture_t { GLuint width,height; GLuint texID; SDL_Surface *sys; };
struct gfx_tex_load_t { gfx_texture_t *dest; char *path; bool free; };
struct gfx_task_l0_t { uint8_t flag; #define GFX_FLAG_FILLED (1<<7) #define GFX_FLAG_WH 1 //назначить свою ш/д #define GFX_FLAG_ROT (1<<1) //угол наклона #define GFX_FLAG_TEX (1<<2) //только часть текстуры #define GFX_FLAG_DEPTH (1<<3) //своя глубина ( по дефолту - 0.5) #define GFX_FLAG_BLEND (1<<4) //режим бленда uint32_t x,y,w,h; gfx_texture_t tex; float rot; float depth; uint16_t tex_x,tex_y,tex_w,tex_h; };
struct gfx_task_l1_t { uint8_t status; #define GFX_L1_STATUS_FREE 0 #define GFX_L1_STATUS_FILLED 1 float out_x,out_y;//y уже инвертирован! float out_w,out_h; float tex_x1,tex_y1; float tex_x2,tex_y2; float rot,depth; unsigned int tex_id; };
class CRender { public: void Init(int,int,bool,bool); void Halt(); int ThreadRFunc(void*); int ThreadCFunc(void*); int Timer(uint32_t,void*); void Stop(); void Continue(); void TextureLoadingBegin(); void TextureLoadingAdd(gfx_texture_t*,char*); void TextureLoadingEnd(); struct { uint32_t X,Y; } Camera; //drawing void Draw(gfx_texture_t*,uint32_t,uint32_t ); void Draw(gfx_texture_t*,uint32_t,uint32_t,uint16_t,uint16_t,uint16_t,uint16_t ); void Draw(gfx_texture_t*,uint32_t,uint32_t,rect_t ); void Draw(gfx_texture_t*,uint32_t,uint32_t,rect_t,uint32_t,uint32_t); //inline inline void gfx_l0_add(gfx_task_l0_t); private: gfx_task_l0_t *task_l0; gfx_task_l1_t *task_l1; gfx_tex_load_t *tex_load; int coord_w, coord_h; int fps_tmp,fps; int tex_load_i; bool stop; bool stop_answerR, stop_answerC; bool quit; bool tex_load_signal; SDL_Thread *threadR, *threadC; SDL_TimerID timer; SDL_Surface *window; };
#endif // CRENDER_H
|
Crender.cpp: Код | #include <CRender.h> #include <Base.h> #include <SDL/SDL.h> #include <SDL/SDL_image.h> #include <X11/Xlib.h> #include <GL/gl.h> #include <GL/glu.h>
CRender Render;
int __tmp_render_func(void *ptr); int __tmp_conventer_func(void *ptr); unsigned int __tmp_timer_func(unsigned int,void *ptr);
inline void CRender::gfx_l0_add(gfx_task_l0_t newtask) { int a; gfx_task_l0_t *task=task_l0; for(a=0;a<GFX_TASK_L0_COUNT;a++) { if(memcmp(&task[a],&newtask,sizeof(gfx_task_l0_t))==0)break; if(task[a].flag==0) { task[a]=newtask; break; } } }
void CRender::Init(int w,int h,bool fs,bool db) { struct { int w; int y; bool fs; bool db; } values = {w,h,fs,db};
task_l0 = new gfx_task_l0_t[GFX_TASK_L0_COUNT]; task_l1 = new gfx_task_l1_t[GFX_TASK_L1_COUNT]; tex_load = new gfx_tex_load_t[GFX_TEXLOAD_COUNT];
coord_w = w; coord_h = h;
Camera.X = Camera.Y = 0;
fps_tmp = fps = 0; tex_load_i = 0; stop = stop_answerR = stop_answerC = false; quit = tex_load_signal = false;
threadR = SDL_CreateThread(__tmp_render_func,&values); threadC = SDL_CreateThread(__tmp_conventer_func,NULL); timer = SDL_AddTimer(1000,__tmp_timer_func,NULL); }
void CRender::Stop() { stop = true; //waiting R and C threads SDL_Delay(20); }
void CRender::Continue() { stop = false; //waiting R and C threads SDL_Delay(20); }
int CRender::ThreadRFunc(void *params) { struct { int w; int h; bool fs; bool db; } values = *((typeof(values)*)params);
window = SDL_SetVideoMode(values.w, values.h, 32, SDL_OPENGL | (values.fs?SDL_FULLSCREEN:0) | (values.db?SDL_DOUBLEBUF:0));
//hide system cursor int tmp[4]={0,0,0,0}; SDL_SetCursor(SDL_CreateCursor((uint8_t*)&tmp,(uint8_t*)&tmp,2,2,1,1));
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,8); glClearColor(0.7f, 0.7f, 0.9f, 1.0f); glClearDepth(1.0f); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(0.0f,(values.w/values.h), 0.1f,100.0f); glMatrixMode(GL_MODELVIEW); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glEnable(GL_ALPHA); glEnable(GL_ALPHA_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_LEQUAL,0.3f); glAlphaFunc(GL_GEQUAL,0.1f); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, // GL_LINEAR_MIPMAP_NEAREST); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//start main Render Loop while(quit==false) { gfx_task_l1_t *task; int i=0;
if(stop==true) {
if(tex_load_signal==true) { for(int i=0;i<tex_load_i;i++) { //Здесь мы загружаем/освобождаем текстуру if(tex_load[i].free==true) { SDL_FreeSurface(tex_load[i].dest->sys); glDeleteTextures(1,&(tex_load[i].dest->texID)); } else { printf("[Render]loading %s... \n",tex_load[i].path); tex_load[i].dest->sys=IMG_Load(tex_load[i].path); if(tex_load[i].dest->sys==NULL)puts("IMG_Load() error\n"); tex_load[i].dest->width=tex_load[i].dest->sys->w; //Ничего не стоящяя оптимизация tex_load[i].dest->height=tex_load[i].dest->sys->h; //Меньше обращений к памяти glGenTextures(1, &(tex_load[i].dest->texID)); glBindTexture(GL_TEXTURE_2D,tex_load[i].dest->texID); gluBuild2DMipmaps(GL_TEXTURE_2D, 4, tex_load[i].dest->width, tex_load[i].dest->height, GL_RGBA,GL_UNSIGNED_BYTE,tex_load[i].dest->sys->pixels); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, // GL_LINEAR_MIPMAP_NEAREST); //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
} } tex_load_signal=false; }
if(stop_answerR==false) stop_answerR=true; else { //пропускаем ход SDL_Delay(20); continue; } } else if(stop_answerR==true) stop_answerR==false;
//очищаем экран перед прорисовкой glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearDepth(1.0f);
for(task=task_l1;i++<GFX_TASK_L0_COUNT;task++) { if(task->status==GFX_L1_STATUS_FILLED) { glTranslatef(task->out_x,task->out_y,task->depth);
glBindTexture(GL_TEXTURE_2D, task->tex_id); glBegin(GL_QUADS); glTexCoord2f(task->tex_x1,task->tex_y2); glVertex3f(-task->out_w, -task->out_h, 0); glTexCoord2f(task->tex_x2,task->tex_y2); glVertex3f(task->out_w, -task->out_h, 0); glTexCoord2f(task->tex_x2,task->tex_y1); glVertex3f(task->out_w, task->out_h, 0); glTexCoord2f(task->tex_x1,task->tex_y1); glVertex3f(-task->out_w, task->out_h, 0); glEnd();
glTranslatef(-task->out_x,-task->out_y,-task->depth); task->status=GFX_L1_STATUS_FREE; } }
glFlush(); fps_tmp++; SDL_GL_SwapBuffers(); SDL_Delay(30); } SDL_FreeSurface(window); SDL_Delay(50); return 0; }
int CRender::ThreadCFunc(void *params) { register gfx_task_l0_t *task; register int i,a;
while(quit==false) { task=task_l0;
if(stop==true) { if(stop_answerC==false) stop_answerC=true; else { //пропускаем ход SDL_Delay(30); continue; }
} else if(stop_answerC==true) stop_answerC==false;
for(i=0;i++<GFX_TASK_L1_COUNT;task++) { if(task->flag !=0) { gfx_task_l1_t *dst; //ищем свободную ячейку for(a=0;a<GFX_TASK_L1_COUNT;a++) if(task_l1[a].status==GFX_L1_STATUS_FREE)break;
dst=&(task_l1[a]);
if(task->flag & GFX_FLAG_DEPTH == GFX_FLAG_DEPTH) dst->depth=1.0f-task->depth;//Z тоже инвертирован else dst->depth=0.5f;
if(task->flag&GFX_FLAG_ROT==GFX_FLAG_ROT) dst->rot=task->rot; else dst->rot=0.0f;
if(task->flag&GFX_FLAG_WH==GFX_FLAG_WH) { dst->out_w=(float)task->w/(float)coord_w; dst->out_h=(float)task->h/(float)coord_h; } else { dst->out_w=(float)task->tex.width/(float)coord_w; dst->out_h=(float)task->tex.height/(float)coord_h; }
if(task->flag&GFX_FLAG_TEX==GFX_FLAG_TEX) { dst->tex_x1=(float)task->tex_x/(float)task->tex.width; dst->tex_x2=dst->tex_x1+((float)task->tex_w/(float)task->tex.width); dst->tex_y1=(float)task->tex_y/(float)task->tex.height; dst->tex_y2=dst->tex_y1+((float)task->tex_h/(float)task->tex.height); } else { dst->tex_x1=0.0f; dst->tex_x2=1.0f; dst->tex_y1=0.0f; dst->tex_y2=1.0f; }
dst->out_x=-1.0f+((float)task->x/(float)coord_w)*2.0f; dst->out_y=1.0f-((float)task->y/(float)coord_h)*2.0f;
dst->tex_id=task->tex.texID;
dst->status=GFX_L1_STATUS_FILLED; task->flag=0; } } SDL_Delay(20); }
SDL_Delay(50); return 0; }
int CRender::Timer(uint32_t time, void *params) { fps=fps_tmp; fps_tmp=0; return 1000; }
void CRender::Halt() { if(stop==false) Stop(); quit = true; SDL_RemoveTimer(timer); SDL_Delay(800); }
void CRender::TextureLoadingBegin() { Stop(); tex_load_i = 0; }
void CRender::TextureLoadingAdd(gfx_texture_t *tex,char *path) { if(tex_load_i>GFX_TEXLOAD_COUNT) { //Список переполнен. Выполняем сначала то, что уже есть. TextureLoadingEnd(); TextureLoadingBegin(); }
tex_load[tex_load_i].free=false; tex_load[tex_load_i].dest = tex; tex_load[tex_load_i++].path = path; }
void CRender::TextureLoadingEnd() { tex_load_signal = true; while(tex_load_signal == true) SDL_Delay(10); Continue(); }
void CRender::Draw(gfx_texture_t *tex, uint32_t x, uint32_t y ) { gfx_task_l0_t newtask;
newtask.flag=GFX_FLAG_FILLED ; newtask.x=x-Camera.X; newtask.y=y-Camera.Y; newtask.tex=*tex;
gfx_l0_add(newtask); }
void CRender::Draw(gfx_texture_t *tex,uint32_t x,uint32_t y,uint16_t pX,uint16_t pY,uint16_t pW,uint16_t pH) { gfx_task_l0_t newtask;
newtask.flag=GFX_FLAG_FILLED | GFX_FLAG_TEX | GFX_FLAG_WH; newtask.x=x-Camera.X; newtask.y=y-Camera.Y; newtask.w=(uint32_t)pW; newtask.h=(uint32_t)pH; newtask.tex_x=pX; newtask.tex_y=pY; newtask.tex_w=pW; newtask.tex_h=pH; newtask.tex=*tex;
gfx_l0_add(newtask); }
void CRender::Draw(gfx_texture_t *tex,uint32_t x,uint32_t y,rect_t rect) { gfx_task_l0_t newtask;
newtask.flag=GFX_FLAG_FILLED + GFX_FLAG_TEX + GFX_FLAG_WH; newtask.x=x-Camera.X; newtask.y=y-Camera.Y; newtask.w=rect.w; newtask.h=rect.h; newtask.tex_x=rect.x; newtask.tex_y=rect.y; newtask.tex_w=rect.w; newtask.tex_h=rect.h; newtask.tex=*tex;
gfx_l0_add(newtask); }
void CRender::Draw(gfx_texture_t *tex,uint32_t x,uint32_t y,rect_t rect, uint32_t w, uint32_t h) { gfx_task_l0_t newtask;
newtask.flag=GFX_FLAG_FILLED + GFX_FLAG_TEX + GFX_FLAG_WH; newtask.x=x-Camera.X; newtask.y=y-Camera.Y; newtask.w=w; newtask.h=h; newtask.tex_x=rect.x; newtask.tex_y=rect.y; newtask.tex_w=rect.w; newtask.tex_h=rect.h; newtask.tex=*tex;
gfx_l0_add(newtask); }
////
int __tmp_render_func(void *ptr) { return Render.ThreadRFunc(ptr); }
int __tmp_conventer_func(void *ptr) { return Render.ThreadCFunc(ptr); }
unsigned int __tmp_timer_func(unsigned int time, void *ptr) { return (unsigned int)Render.Timer(((uint32_t)time), ptr); }
|
|