关于opengl arb中glMultiTexCoord2fARB函数的应用

OpenGL中的几何体实例化OpenGL Geometry Instancing_博客园
当前位置: >
>OpenGL中的几何体实例化OpenGL Geometry Instancing
OpenGL中的几何体实例化OpenGL Geometry Instancing
& 作者:江枫月 & 来源: 博客园-jamesclarke &
&&&&&&在GPU Gems 2中有一篇文章是专门介绍几何体实例化的,不过它是基于DirectX的。经过多年的发展,OpenGL在几何体实例化方面也做出了改进,于2008年在OpenGL3.0中正式引入实例化函数,该函数只被NVIDIA 8系列以上显卡支持。
&&&&&&几何体实例化,是通过对具有相同顶点数据的几何体,赋予不同的空间位置、颜色或纹理等特征,从而创造出不同实例对象的技术。尤其适合于草地、石块、数目、士兵群等对象的绘制。它的好处在于,只需传递一次单个模型的顶点数据(或者说调用一个批次的绘制指令),再传递不同对象的特征数据,就能实现多个对象的绘制。
&&&&&&最早,OpenGL是不支持几何体实例化的。它通过即时模式,调用glDrawElements等函数,能较高效的实现多个对象的绘制。然而,这还是会造成占用大量的VBO存储空间和数据传输带宽。
&&&&&&在GPU可编程后,通过设置全局统一参数glUniformMatrix4fvARB来传递对象的特征数据给Vertex Shader,来间接实现实例化。然而这还是不能够减少绘制指令的调用次数。
&&&&&&而后,NVIDIA提出了伪实例化(pseudo-instancing)的方法,利用顶点数据指令,如glColor3f、glTexCoord、glMultiTexCoord等,将对象的特征数据传递给Vertex Shader。虽然这同样不能减少绘制指令的调用次数,但它却比方法2提高了2~3倍的效率。原因有2:一此文来自: 马开东博客
转载请注明出处 网址:
是方法2中的全局统一参数函数设置的是GPU寄存器,或者说是改变Vertex shader当前的全局处理状态,很显然将等待当前GPU正在执行的Vertex process完成后才能返回,即需要CPU等待GPU完成该对象的绘制,存在严重的效率问题[1];二是全局统一参数函数设置的GPU寄存器是全局共享的,Vertex Shader拜访该寄存器所耗费的时间显然要多于拜访本地寄存器(由顶点数据指令设置的)所花费的时间。
&&&&&&最后,ARB终于通过了实例化的函数,有两个:DrawArraysInstancedARB、DrawElementsInstancedARB。在GLSL中,通过instance ID获取实例的ID,加以控制。这两个函数不能用在显示列表中。
&&&&&&JeGX对以上四种方法进行了,有兴趣的童鞋,可以点击链接去看看。测试的结论是[2]:
&&&&&&1、在OpenGL中,每个实例的顶点数越小,实例化带来的效率提升越明显。因此要尽量将实例模型的面数和顶点数控制到最小。
&&&&&&2、新的实例化函数,虽然减少了指令的个数,但当实例模型的面数和顶点数比较大的时候,好像没有带来太大的性能改变。
&&&&&&我曾经把特征数据编码进顶点纹理,通过Vertex Shader来获取,实现实例化,然而效果好像并不是非常明显(相较于第2种方法而言)。目前还没有试验第4种方法,希望以后有时间的时候来试验一下。
参考文献:
相关阅读:
来源:(微信/QQ:,微信公众号:makaidong-com) &&&&&& 欢迎分享本文,转载请保留出处!
&&&&&& 【原文阅读】:
上一篇:没有了
【相关文章】
每日最新文章
每日最热文章
本周最热文章
本月最热文章
本年最热文章
Powered by
Copyright &
, All Rights ReservedDescription of your first forum.
9 篇帖子 & 分页:1 / 1
由 小飞点 & 星期三, 日 16:47
请问:如何在 7 中使用 Open GL 将一张BMP(JPG)图片生成具有3D效果并能旋转的图象?最好有原代码.
由 zhang214 & 星期三, 日 21:51
好象OpenGl,是图形的东西,而图片是图象的,,图形是需要建模的...图片恐怕不好使吧...
由 igghdeeee & 星期三, 日 21:54
有道理,而且需要OPENGL支持
由 dcsdcs & 星期三, 日 22:07
你最好直接支持opengl1.2,下在网络上面的open12.pas
因为在opengl.pas当中有几个函数的参数错误。
1)建立场景。
2)创建物体
4)旋转等动作。
由 小飞点 & 星期四, 日 14:25
dcsdcs : 能否具体点.opengl 不太熟悉
由 duhai_lee & 星期四, 日 15:12
&Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
&Dialogs, GL, GLu, GLext, TGA, CgWindow, CgTexture, CgUtils, CgTypes,
&TTTForm = class(TCGForm)
& &procedure FormCreate(Sender: TObject);
& &procedure FormResize(Sender: TObject);
& &procedure FormPaint(Sender: TObject);
& &procedure FormKeyDown(Sender: TO var Key: W
& & &Shift: TShiftState);
& &procedure FormMouseMove(Sender: TO Shift: TShiftS X,
& & &Y: Integer);
& &{ Private declarations }
& &procedure LoadT
& &procedure LoadT
& &procedure ConfigureSingleP
& &procedure ConfigureMultiP
& &procedure RenderSingleP
& &procedure RenderMultiP
& &procedure Idle(Sender: TO var Done: Boolean);
&TTerrainVertex = record
& &R, G, B, A: S
& &U1, V1, U2, V2: S
& &X, Y, Z: S
&TTForm: TTTF
&va: array of TTerrainV & & & & & & & & & & & & &// Vertex array
&ia: array of array of C & & & & & & & & & & & // Index arrays
&T1, T2, T3, L: GL & & & & & & & & & & & & & & & &// Texture objects
&cam: record & & & & & & & & & & & & & & & & & & & & & // Camera information
& &pos: TCGV
& &pitch, yaw: S
&mpos: TP & & & & & & & & & & & & & & & & & & & & // Mouse position
&mW, mH: I & & & & & & & & & & & & & & & & & & &// Heightmap dimensions
&renderProc: & & & & & & & & & & &// Single pass/multipass render?
implementation
{$R *.dfm}
procedure TTTForm.LoadT
&map: array of array of B
&LUT, coverage: TB
&function CalcSlope(x, y: Integer): S
& &s1, s2, s3, s4, s5, s6, s7, s8: B
& &// Calculate slope for a pixel on the heightmap by looking at its neighbors.
& &if (x = 0) or (y = 0) or (x = mW-1) or (y = mH-1) then Result := 0
& &else begin
& & &s1 := map[x-1, y-1] - map[x,y];
& & &s2 := map[x-1, y] - map[x,y];
& & &s3 := map[x-1, y+1] - map[x,y];
& & &s4 := map[x, y+1] - map[x,y];
& & &s5 := map[x+1, y+1] - map[x,y];
& & &s6 := map[x+1, y] - map[x,y];
& & &s7 := map[x+1, y-1] - map[x,y];
& & &s8 := map[x, y-1] - map[x,y];
& & &Result := (s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8) / (256*8);
&procedure Color(x, y: Integer);
& &h, s: S
& &w1, w2, w3, l: S
& &a1, a2: S
& &// Encode the blending weights for this heightmap pixel in an RGBA color.
& &if coverage = nil then
& & &h := map[x,y]/255;
& & &s := CalcSlope(x, y);
& & &cl := LUT.Canvas.Pixels[Trunc(h*LUT.Width), LUT.Height - 1 - Trunc(s*LUT.Height)];
& & &w1 := (cl mod $100) / 255;
& & &w2 := ((cl div $100) mod $100) / 255;
& & &w3 := (cl div $10000) / 255;
& & &l := sqrt(w1*w1 + w2*w2 + w3*w3);
& & &w1 := w1/l;
& & &w2 := w2/l;
& & &w3 := w3/l;
& & &bmp.Canvas.Pixels[x,y] := RGB(Trunc(w1*255), Trunc(w2*255), Trunc(w3*255));
& &else begin
& & &cl := coverage.Canvas.Pixels[x,y];
& & &w1 := (cl mod $100) / 255;
// & & &w2 := ((cl div $100) mod $100) / 255;
& & &w3 := (cl div $10000) / 255;
& &a1 := w1/(1-w3);
& &a2 := 1 - w3;
& &va[y*mW + x].R := a1;
& &va[y*mW + x].G := a1;
& &va[y*mW + x].B := a1;
& &va[y*mW + x].A := a2;
&// Load heightmap:
&bmp := TBitmap.C
&bmp.LoadFromFile('map.bmp');
&mW := bmp.W
&mH := bmp.H
&SetLength(map, mW);
&for x := 0 to mW - 1 do SetLength(map[x], mH);
&SetLength(va, mW*mH);
&{ LUT is a 2D lookup table that maps slope and height to three coverage
& &factors. I use a bitmap so that you can easily change the distribution of
& &the textures. Just edit the bitmap: the horizontal axis is height, the
& &vertical axis is slope, and R, G and B represent the three input textures.
& &Red equals grass, green equals dirt, and blue equals rock. }
&LUT := TBitmap.C
&LUT.LoadFromFile('lookup.bmp');
&for x := 0 to mW-1 do
& &for y := 0 to mH-1 do
& & &map[x,y] := bmp.Canvas.Pixels[x,y] mod $100;
&{ If a file 'coverage.bmp' exists, we will load the coverage factors from it
& &rather than generating them procedurally. Otherwise, we generate the factors
& &and then save them to coverage.bmp. You can look at this image and edit it.
& &If you screw up, just delete the file and a new one will be generated. }
('coverage.bmp') then
& &coverage := TBitmap.C
& &coverage.LoadFromFile('coverage.bmp');
&else begin
& &bmp := TBitmap.C
& &bmp.PixelFormat := pf24
& &bmp.Width := mW;
& &bmp.Height := mH;
& &coverage :=
&// Fill up the vertex array: &
&for x := 0 to mW - 1 do
& &for y := 0 to mH - 1 do
& & &Color(x, y);
& & &va[y*mW + x].U1 :=
& & &va[y*mW + x].V1 :=
& & &va[y*mW + x].U2 := x/mW;
& & &va[y*mW + x].V2 := 1-y/mH;
& & &va[y*mW + x].X := 4000*(x - (mW div 2))/(mW div 2);
& & &va[y*mW + x].Y := 1000*map[x,y]/256;
& & &va[y*mW + x].Z := 4000*(y - (mH div 2))/(mH div 2);
&if bmp && nil then
& &bmp.SaveToFile('coverage.bmp');
&// Create index arrays for glDrawElements().
&SetLength(ia, mW-1);
&for x := 0 to mW-2 do
& &SetLength(ia[x], mH*2);
& &for y := 0 to mH-1 do
& & &ia[x,y*2] := y*mW + x+1;
& & &ia[x,y*2+1] := y*mH +
procedure TTTForm.LoadT
&img: TCGT
&// Load the texture images from disk.
&glGenTextures(1, @T1);
&glBindTexture(GL_TEXTURE_2D, T1);
&img := tgaLoad('tile1.tga');
&gluBuild2DMipmaps(GL_TEXTURE_2D, 4, img.Width, img.Height, GL_RGBA, GL_UNSIGNED_BYTE, img.Data);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
&glGenTextures(1, @T2);
&glBindTexture(GL_TEXTURE_2D, T2);
&img := tgaLoad('tile2.tga');
&gluBuild2DMipmaps(GL_TEXTURE_2D, 4, img.Width, img.Height, GL_RGBA, GL_UNSIGNED_BYTE, img.Data);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
&glGenTextures(1, @T3);
&glBindTexture(GL_TEXTURE_2D, T3);
&img := tgaLoad('tile3.tga');
&gluBuild2DMipmaps(GL_TEXTURE_2D, 4, img.Width, img.Height, GL_RGBA, GL_UNSIGNED_BYTE, img.Data);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
&glGenTextures(1, @L);
&glBindTexture(GL_TEXTURE_2D, L);
&img := tgaLoad('lightmap.tga');
&gluBuild2DMipmaps(GL_TEXTURE_2D, 4, img.Width, img.Height, GL_RGBA, GL_UNSIGNED_BYTE, img.Data);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
&glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
procedure TTTForm.ConfigureSingleP
&// Configure OpenGL for the single-pass rendering.
&glEnableClientState(GL_COLOR_ARRAY);
&glColorPointer(4, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].R);
&glClientActiveTextureARB(GL_TEXTURE3_ARB);
&glEnableClientState(GL_TEXTURE_COORD_ARRAY);
&glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U2);
&glClientActiveTextureARB(GL_TEXTURE2_ARB);
&glEnableClientState(GL_TEXTURE_COORD_ARRAY);
&glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U1);
&glClientActiveTextureARB(GL_TEXTURE1_ARB);
&glEnableClientState(GL_TEXTURE_COORD_ARRAY);
&glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U1);
&glClientActiveTextureARB(GL_TEXTURE0_ARB);
&glEnableClientState(GL_TEXTURE_COORD_ARRAY);
&glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U1);
&glEnableClientState(GL_VERTEX_ARRAY);
&glVertexPointer(3, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].X);
&// Texture 3: previous * L
&glActiveTextureARB(GL_TEXTURE3_ARB);
&glEnable(GL_TEXTURE_2D);
&glBindTexture(GL_TEXTURE_2D, L);
&glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
&// Texture 2: lerp(C0.alpha, previous, T3)
&glActiveTextureARB(GL_TEXTURE2_ARB);
&glEnable(GL_TEXTURE_2D);
&glBindTexture(GL_TEXTURE_2D, T3);
&glMatrixMode(GL_TEXTURE);
&glScalef(0.2, 0.2, 0);
&glMatrixMode(GL_MODELVIEW);
&glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
&glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
&glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
&glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
&// Texture 1: lerp(C0.rgb, T1, T2)
&glActiveTextureARB(GL_TEXTURE1_ARB);
&glEnable(GL_TEXTURE_2D);
&glBindTexture(GL_TEXTURE_2D, T1);
&glMatrixMode(GL_TEXTURE);
&glScalef(0.2, 0.2, 0);
&glMatrixMode(GL_MODELVIEW);
&glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
&glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
&glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
&glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
&// Texture 0: T1
&glActiveTextureARB(GL_TEXTURE0_ARB);
&glEnable(GL_TEXTURE_2D);
&glBindTexture(GL_TEXTURE_2D, T2);
&glMatrixMode(GL_TEXTURE);
&glScalef(0.2, 0.2, 0);
&glMatrixMode(GL_MODELVIEW);
&glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
procedure TTTForm.ConfigureMultiP
&// Configure OpenGL for the multipass rendering.
&glEnable(GL_BLEND);
&glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
&glDepthFunc(GL_LEQUAL);
&glActiveTextureARB(GL_TEXTURE1_ARB);
&glClientActiveTextureARB(GL_TEXTURE1_ARB);
&glEnableClientState(GL_TEXTURE_COORD_ARRAY);
&glEnable(GL_TEXTURE_2D);
&glMatrixMode(GL_TEXTURE);
&glScalef(0.2, 0.2, 0);
&glMatrixMode(GL_MODELVIEW);
&glActiveTextureARB(GL_TEXTURE0_ARB);
&glClientActiveTextureARB(GL_TEXTURE0_ARB);
&glEnableClientState(GL_TEXTURE_COORD_ARRAY);
&glEnable(GL_TEXTURE_2D);
&glMatrixMode(GL_TEXTURE);
&glScalef(0.2, 0.2, 0);
&glMatrixMode(GL_MODELVIEW);
&glEnableClientState(GL_VERTEX_ARRAY);
&glVertexPointer(3, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].X);
procedure TTTForm.FormCreate(Sender: TObject);
&CSKY: array [0..3] of GLfloat = (0.2, 0.6, 1, 1);
& &// Multitexture
& &if not glext_ExtensionSupported('GL_ARB_multitexture') then
& & &raise Exception.Create('This demo requires GL_ARB_multitexture!');
& &glActiveTextureARB := wglGetProcAddress('glActiveTextureARB');
& &glClientActiveTextureARB := wglGetProcAddress('glClientActiveTextureARB');
& &glMultiTexCoord2fARB := wglGetProcAddress('glMultiTexCoord2fARB');
& &if (not Assigned(glActiveTextureARB)) or
& & & (not Assigned(glClientActiveTextureARB)) or
& & & (not Assigned(glMultiTexCoord2fARB)) then
& & &raise Exception.Create('Error loading GL_ARB_multitexture!');
& &// Texture_env_combine
& &if not glext_ExtensionSupported('GL_ARB_texture_env_combine') then
& & &raise Exception.Create('This demo requires GL_ARB_texture_env_combine!');
& &// Load the terrain data:
& &// Check if we can do it in a single pass:
& &glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, @TUs);
& &if TUs &= 4 then
& & &ConfigureSingleP
& & &renderProc := RenderSingleP
& &else if TUs &= 2 then
& & &ConfigureMultiP
& & &renderProc := RenderMultiP
& &else raise Exception.Create('This demo requires at least two texture units!');
& &// Basic stuff:
& &glClearColor(CSKY[0], CSKY[1], CSKY[2], CSKY[3]);
& &glEnable(GL_CULL_FACE);
& &glCullFace(GL_BACK);
& &glFrontFace(GL_CCW);
& &glEnable(GL_DEPTH_TEST);
& &cam.pos := cgVector(0, 500, 0);
& &cam.pitch := 0;
& &cam.yaw := 0;
& &GetCursorPos(mpos);
& &mpos := ScreenToClient(mpos);
& &cgStartT
& &Application.OnIdle := I
&except on E: Exception do
& & &MessageDlg(E.Message, mtError, [mbOk], 0);
& & &Halt(1);
procedure TTTForm.FormResize(Sender: TObject);
&glViewport(0, 0, ClientWidth, ClientHeight);
&glMatrixMode(GL_PROJECTION);
&gluPerspective(60, ClientWidth/ClientHeight, 1, 10000);
&glMatrixMode(GL_MODELVIEW);
procedure TTTForm.RenderSingleP
&for i := 0 to mW-2 do
& &glDrawElements(GL_TRIANGLE_STRIP, mH*2, GL_UNSIGNED_INT, @ia[i][0]);
procedure TTTForm.RenderMultiP
&// Pass 1: LERP(C0.RGB, T1, T2)
&glDisable(GL_BLEND);
&glEnable(GL_COLOR_ARRAY);
&glColorPointer(4, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].R);
&glActiveTextureARB(GL_TEXTURE1_ARB);
&glClientActiveTextureARB(GL_TEXTURE1_ARB);
&glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U1);
&glEnable(GL_TEXTURE_2D);
&glBindTexture(GL_TEXTURE_2D, T1);
&glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
&glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
&glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
&glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
&glActiveTextureARB(GL_TEXTURE0_ARB);
&glClientActiveTextureARB(GL_TEXTURE0_ARB);
&glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U1);
&glBindTexture(GL_TEXTURE_2D, T2);
&glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
&for i := 0 to mW-2 do
& &glDrawElements(GL_TRIANGLE_STRIP, mH*2, GL_UNSIGNED_INT, @ia[i][0]);
&// Pass 2: LERP(C0.A, T3, FB)
&glEnable(GL_BLEND);
&glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
&glActiveTextureARB(GL_TEXTURE1_ARB);
&glDisable(GL_TEXTURE_2D);
&glActiveTextureARB(GL_TEXTURE0_ARB);
&glBindTexture(GL_TEXTURE_2D, T3);
&glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
&glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
&glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
&glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
&glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PRIMARY_COLOR_ARB);
&glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_ONE_MINUS_SRC_ALPHA);
&for i := 0 to mW-2 do
& &glDrawElements(GL_TRIANGLE_STRIP, mH*2, GL_UNSIGNED_INT, @ia[i][0]);
&// Pass 3: FB * L
&glEnable(GL_BLEND);
&glBlendFunc(GL_DST_COLOR, GL_ZERO);
&glActiveTextureARB(GL_TEXTURE1_ARB);
&glDisable(GL_TEXTURE_2D);
&glDisable(GL_COLOR_ARRAY);
&glActiveTextureARB(GL_TEXTURE0_ARB);
&glBindTexture(GL_TEXTURE_2D, L);
&glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U2);
&glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
&glMatrixMode(GL_TEXTURE);
&for i := 0 to mW-2 do
& &glDrawElements(GL_TRIANGLE_STRIP, mH*2, GL_UNSIGNED_INT, @ia[i][0]);
&glMatrixMode(GL_MODELVIEW);
procedure TTTForm.FormPaint(Sender: TObject);
&glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
&glRotatef(-cam.pitch, 1, 0, 0);
&glRotatef(-cam.yaw, 0, 1, 0);
&glTranslatef(-cam.pos.x, -cam.pos.y, -cam.pos.z);
&fps: Single = 0; & &// Sum of framerate samples.
&fpsc: Integer = 0; &// Number of framerate samples taken.
&FPS_SMOOVE = 20; & &// Number of samples to use for smoothing the fps counter.
procedure TTTForm.Idle(Sender: TO var Done: Boolean);
&dt, speed: S
&Done := FALSE;
&dt := cgTimeE
&// Take framerate sample.
&fps := fps + 1000/
&INC(fpsc);
&// If number of samples is high enough, average them and display the result.
&if fpsc = FPS_SMOOVE then
& &fpsc := 0;
& &fps := fps / FPS_SMOOVE;
& &Caption :=
('Terrain texturing -- %.0f fps', [fps]);
& &fps := 0;
&if GetAsyncKeyState(VK_SHIFT) && 0 then speed := 1
&else speed := 0.5;
&v := cgVector(0, 0, 0);
&if GetAsyncKeyState(VK_UP) && 0 then v.z := -dt*speed
&else if GetAsyncKeyState(VK_DOWN) && 0 then v.z := dt*
&if GetAsyncKeyState(VK_LEFT) && 0 then v.x := -dt*speed
&else if GetAsyncKeyState(VK_RIGHT) && 0 then v.x := dt*
&cgRotateX(v, cam.pitch*PI/180);
&cgRotateY(v, cam.yaw*PI/180);
&cam.pos := cgVecAdd(cam.pos, v);
procedure TTTForm.FormKeyDown(Sender: TO var Key: W
&Shift: TShiftState);
&if Key = VK_ESCAPE then C
procedure TTTForm.FormMouseMove(Sender: TO Shift: TShiftS X,
&Y: Integer);
&if ssLeft in Shift then
& &cam.pitch := cam.pitch - (Y - mpos.Y)/5;
& &cam.yaw := cam.yaw - (X - mpos.X)/5;
& &if cam.pitch & 90 then cam.pitch := 90
& &else if cam.pitch & -90 then cam.pitch := -90;
& &if cam.yaw & 360 then cam.yaw := cam.yaw - 360
& &else if cam.yaw & 0 then cam.yaw := cam.yaw + 360;
&mpos := Point(X, Y);
由 小飞点 & 星期五, 日 08:25
duhai_lee:GL, GLu, GLext, TGA, CgWindow, CgTexture, CgUtils, CgTypes,CgGeometry
哪里去找??
由 duhai_lee & 星期五, 日 08:27
有个gl的控件, 是delphi下面的, 非常棒, 我这台机器上没有, 你可以搜一下,如果找不到, 再找我. &那个控件叫 glsence.
另外你可以去 Gamedev网站去看看. &有很多delphi相关的东西..
由 小飞点 & 星期六, 日 10:39
多人接受***了。
9 篇帖子 & 分页:1 / 1

参考资料

 

随机推荐