![]() |
|
![]() |
![]() |
Новости | Конференция | Чат | База данных | Творчество | Сообщество | О сайте | English |
![]() |
Помощь сайту |
![]() |
![]() |
![]() |
![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Глава 9. Спрайты на шейдерах Как я и обещал – мы перепишем рендер спрайтов. Сейчас у нас он выглядит следующим образом: procedure JLSprite.Render(WithChild:boolean); var v1,v2,v3,v4:TDotVector3; const Tex1:TDotVector2=(x:0;y:0); Tex2:TDotVector2=(x:1;y:0); Tex3:TDotVector2=(x:1;y:1); Tex4:TDotVector2=(x:0;y:1); begin v1:=dotVecAdd3(JLGetActiveCamera.V1,trans.pos); v2:=dotVecAdd3(JLGetActiveCamera.V2,trans.pos); v3:=dotVecAdd3(JLGetActiveCamera.V3,trans.pos); v4:=dotVecAdd3(JLGetActiveCamera.V4,trans.pos); if TexID<>'' then textures.GetObjByName(TexID).Bind; glColor3fv(@ color); glBegin(GL_QUADS); glTexCoord2fv(@ tex1); glVertex3fv(@ v1); glTexCoord2fv(@ tex2); glVertex3fv(@ v2); glTexCoord2fv(@ tex3); glVertex3fv(@ v3); glTexCoord2fv(@ tex4); glVertex3fv(@ v4); glEnd; end; Нам нужно убрать векторы v1, v2, v3, v4 отсюда, а значит и вообще (из класса камеры). Мы расширим рендер спрайтов, теперь они будут иметь параметр «вращение». Он нужен для того чтобы спрайты не выглядели одинаково. Итак, опишем псевдокодом, что нужно шейдеру. -Позиция вершины (стандарт) -Размер спрайта (передадим через нормаль) -Матрица 2х2 поворота (передадим через специальную команду glProgramLocalParameter4fARB) Объявим входящие и исходящие данные: ATTRIB inPos = vertex.position; ATTRIB inColor = vertex.color; ATTRIB inSize = vertex.normal; ATTRIB inTex = vertex.texcoord[0]; OUTPUT outPos = result.position; OUTPUT outColor = result.color; OUTPUT outTex = result.texcoord[0]; PARAM rotmat[2] = { program.local[0..1] }; PARAM mv[4] = { state.matrix.modelview }; PARAM pr[4] = { state.matrix.projection }; В mv пихаем modelview матрицу в pr projection. Почему не сразу mvp? Да потому что мы будем делать промежуточные расчеты. TEMP vec,vecT; Объявили темповые переменные. inSize – это некий вектор в экранных координатах. MOV vec.x,inSize.x; MOV vec.y,inSize.y; MOV vec.z,0; MOV vec.w,1; Запихиваем его в vec. DP3 vecT.x, rotmat[0], vec; DP3 vecT.y, rotmat[1], vec; DP3 vecT.z, vec.zzzw, vec; Умножаем его на матрицу поворота, которую мы передали в шейдер. DP4 vec.x, mv[0], inPos; DP4 vec.y, mv[1], inPos; DP4 vec.z, mv[2], inPos; DP4 vec.w, mv[3], inPos; Переводим координаты вершины в modelview пространство. ADD vec, vecT, vec; Прибавляем этот вектор. И теперь остается перевести координату вершины в пространство экрана с помощью матрицы проекции: DP4 outPos.x, pr[0], vec; DP4 outPos.y, pr[1], vec; DP4 outPos.z, pr[2], vec; DP4 outPos.w, pr[3], vec; Вот полный код: !!ARBvp1.0 ATTRIB inPos = vertex.position; ATTRIB inColor = vertex.color; ATTRIB inSize = vertex.normal; ATTRIB inTex = vertex.texcoord[0]; OUTPUT outPos = result.position; OUTPUT outColor = result.color; OUTPUT outTex = result.texcoord[0]; PARAM mv[4] = { state.matrix.modelview }; PARAM pr[4] = { state.matrix.projection }; PARAM rotmat[2] = { program.local[0..1] }; TEMP vec,vecT; MOV vec.x,inSize.x; MOV vec.y,inSize.y; MOV vec.z,0; MOV vec.w,1; DP3 vecT.x, rotmat[0], vec; DP3 vecT.y, rotmat[1], vec; DP3 vecT.z, vec.zzzw, vec; DP4 vec.x, mv[0], inPos; DP4 vec.y, mv[1], inPos; DP4 vec.z, mv[2], inPos; DP4 vec.w, mv[3], inPos; ADD vec, vecT, vec; DP4 outPos.x, pr[0], vec; DP4 outPos.y, pr[1], vec; DP4 outPos.z, pr[2], vec; DP4 outPos.w, pr[3], vec; MOV outTex, inTex; MOV outColor, inColor; END Процедура рендера теперь другая: sha:=shaders.GetShaderByName('billboard'); sha.Bind; size:=size/10; glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 0, pmat[0][0], pmat[0][1], 0, 1); glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 1, pmat[1][0], pmat[1][1], 0, 1); glBegin(GL_QUADS); glNormal3f(size,size,0); glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0); glVertex3fv(@ pos); glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0); glNormal3f(-size,size,0); glVertex3fv(@ pos); glNormal3f(-size,-size,0); glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1); glVertex3fv(@ pos); glNormal3f(size,-size,0); glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1); glVertex3fv(@ pos); glEnd; sha.UnBind; pmat-матрица 2х2 рассчитываемая следующим образом: function jlMat2(ang:single):TDotMatrix2x2; var fs,fc:Extended; begin Sincos(ang,fs,fc); Result[0][0] := fc; Result[0][1] := fs; Result[1][0] := -fs; Result[1][1] := fc; end; pmat:=jlMat2(jldegtorad(Random(359)));
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
![]() |
![]() |
![]() |
Дизайн Elite Games V5 beta.18 EGM Elite Games Manager v5.17 02.05.2010 |
![]() |