本文整理汇总了C#中VertexBuffer类的典型用法代码示例。如果您正苦于以下问题:C# VertexBuffer类的具体用法?C# VertexBuffer怎么用?C# VertexBuffer使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
VertexBuffer类属于命名空间,在下文中一共展示了VertexBuffer类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C#代码示例。
示例1: LoadContent
public void LoadContent(ContentManager content, GraphicsDeviceManager graphicsDeviceManager)
{
texture = content.Load<Texture2D>("brick_texture_map");
wall = new VertexPositionTexture[22];
wall[0] = new VertexPositionTexture(new Vector3(200, 0, 200), new Vector2(0, 0));
wall[1] = new VertexPositionTexture(new Vector3(200, 200, 200), new Vector2(2, 0));
wall[2] = new VertexPositionTexture(new Vector3(0, 0, 200), new Vector2(0, 2));
wall[3] = new VertexPositionTexture(new Vector3(0, 200, 200), new Vector2(2, 2));
wall[4] = new VertexPositionTexture(new Vector3(0, 0, 220), new Vector2(0, 0));
wall[5] = new VertexPositionTexture(new Vector3(0, 200, 220), new Vector2(2, 0));
wall[6] = new VertexPositionTexture(new Vector3(200, 0, 220), new Vector2(0, 2));
wall[7] = new VertexPositionTexture(new Vector3(200, 200, 220), new Vector2(2, 2));
wall[8] = new VertexPositionTexture(new Vector3(200, 0, 200), new Vector2(0, 0));
wall[9] = new VertexPositionTexture(new Vector3(200, 200, 220), new Vector2(2, 0));
wall[10] = new VertexPositionTexture(new Vector3(200, 200, 200), new Vector2(2, 2));
wall[11] = new VertexPositionTexture(new Vector3(0, 200, 220), new Vector2(0, 2));
wall[12] = new VertexPositionTexture(new Vector3(0, 200, 200), new Vector2(0, 0));
// Set vertex data in VertexBuffer
vertexBuffer = new VertexBuffer(graphicsDeviceManager.GraphicsDevice, typeof(VertexPositionTexture), wall.Length, BufferUsage.None);
vertexBuffer.SetData(wall);
// Initialize the BasicEffect
effect = new BasicEffect(graphicsDeviceManager.GraphicsDevice);
}
开发者ID:Woodje,项目名称:3DGame,代码行数:26,代码来源:Wall.cs
示例2: RenderVertexPositionColorList
public static void RenderVertexPositionColorList(GraphicsDevice gd,
BasicEffect effect, Matrix world, Matrix view, Matrix proj,
VertexPositionColor[] vertices, VertexDeclaration vertexDeclaration,
VertexBuffer vertex_buffer)
{
// gd.VertexDeclaration = vertexDeclaration;
effect.World = world;
effect.View = view;
effect.Projection = proj;
effect.VertexColorEnabled = true;
if (vertex_buffer == null)
{
vertex_buffer = new VertexBuffer(gd, typeof(VertexPositionColor), vertices.Length, BufferUsage.WriteOnly);
vertex_buffer.SetData<VertexPositionColor>(vertices);
}
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
gd.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, vertices, 0, vertices.Length / 3);
}
}
开发者ID:DigitalLibrarian,项目名称:xna-forever,代码行数:25,代码来源:Renderer.cs
示例3: ChunkRenderer
public ChunkRenderer(Chunk chunk, World world)
{
this.WorldObj = world;
this.Chunk = chunk;
this.Buffer = new VertexBuffer();
}
开发者ID:CM12000,项目名称:Legends-of-Arcodia,代码行数:7,代码来源:ChunkRenderer.cs
示例4: InitializeGraphics
public static void InitializeGraphics(GraphicsDevice graphicsDevice,
Triangle[] triangles,
Guid id)
{
var basicEffect = new BasicEffect(graphicsDevice)
{
LightingEnabled = false,
VertexColorEnabled = false
};
var index = 0;
var vertices = new VertexPositionColor[triangles.SelectMany(i => i.Points).Count()];
foreach (var point in triangles.SelectMany(triangle => triangle.Points))
vertices[index++] = new VertexPositionColor(new Vector3(point.X,
point.Y,
point.Z),
Color.White);
var vertexBuffer = new VertexBuffer(graphicsDevice,
typeof (VertexPositionColor),
vertices.Length,
BufferUsage.None);
vertexBuffer.SetData(vertices);
Subscriptions.Add(id, new RendererHelperData
{
BasicEffect = basicEffect,
VertexBuffer = vertexBuffer
});
}
开发者ID:naighes,项目名称:AsteroidChallenge,代码行数:31,代码来源:TrianglesRenderer.cs
示例5: DoInitialize
protected override void DoInitialize()
{
base.DoInitialize();
{
// velocity
var buffer = VertexBuffer.Create(typeof(vec4), ParticleModel.particleCount, VBOConfig.Vec4, "empty", BufferUsage.DynamicCopy);
unsafe
{
var random = new Random();
var array = (vec4*)buffer.MapBuffer(MapBufferAccess.WriteOnly);
for (int i = 0; i < ParticleModel.particleCount; i++)
{
array[i] = new vec4(
(float)(random.NextDouble() - 0.5) * 0.2f,
(float)(random.NextDouble() - 0.5) * 0.2f,
(float)(random.NextDouble() - 0.5) * 0.2f,
0);
}
buffer.UnmapBuffer();
}
this.VelocityBuffer = buffer;
}
this.PositionBuffer = this.DataSource.GetVertexAttributeBuffer(ParticleModel.strPosition, null);
}
开发者ID:bitzhuwei,项目名称:CSharpGL,代码行数:26,代码来源:ParticleRenderer.cs
示例6: GetVertexAttributeBuffer
public VertexBuffer GetVertexAttributeBuffer(string bufferName, string varNameInShader)
{
if (bufferName == strPosition)
{
if (positionBuffer == null)
{
//int length = positions.Length;
//VertexBuffer buffer = VertexBuffer.Create(typeof(float), length, VBOConfig.Vec3, BufferUsage.DynamicDraw, varNameInShader);
//unsafe
//{
// IntPtr pointer = buffer.MapBuffer(MapBufferAccess.WriteOnly);
// var array = (float*)pointer;
// for (int i = 0; i < positions.Length; i++)
// {
// array[i] = positions[i];
// }
// buffer.UnmapBuffer();
//}
//this.positionBuffer = buffer;
this.positionBuffer = positions.GenVertexBuffer(VBOConfig.Vec3, varNameInShader, BufferUsage.DynamicDraw);
}
return positionBuffer;
}
else
{
return null;
}
}
开发者ID:bitzhuwei,项目名称:CSharpGL,代码行数:28,代码来源:BillboardModel.cs
示例7: CreateTextures
public bool CreateTextures()
{
CustomVertex[] verts;
try {
string textureFile;
// Load the textures, named from "walk1.bmp" to "walk10.bmp"
for(int i=1; i<=10; i++) {
textureFile = Application.StartupPath + @"\..\..\Images\walk" + i.ToString() + ".bmp";
textures[i-1] = TextureLoader.FromFile(device, textureFile);
}
// Define the vertex buffer to hold our custom vertices
vertBuffer = new VertexBuffer(typeof(CustomVertex),
numVerts, device, Usage.WriteOnly, customVertexFlags, Pool.Default);
// Locks the memory, which will return the array to be filled
verts = vertBuffer.Lock(0, 0) as CustomVertex[];
// Defines the vertices
SquareVertices(verts);
// Unlock the buffer, which will save our vertex information to the device
vertBuffer.Unlock();
return true;
}
catch {
return false;
}
}
开发者ID:timdetering,项目名称:BeginningNetGameProgramming,代码行数:25,代码来源:WindowTest.cs
示例8: Sprite2DBatch
public Sprite2DBatch( GraphicsContext graphics, int maxSpriteCount )
{
int maxVertexCount = maxSpriteCount * 4 ;
int maxIndexCount = maxSpriteCount * 6 ;
graphicsContext = graphics ;
#if !RESIZE_VERTEX_BUFFER
vertexBuffer = new VertexBuffer( maxVertexCount, maxIndexCount, vertexFormats ) ;
spriteCapacity = maxSpriteCount ;
#endif // RESIZE_VERTEX_BUFFER
vertexData = new Vertex[ maxVertexCount ] ;
indexData = new ushort[ maxIndexCount ] ;
spriteList = new Sprite2D[ maxSpriteCount ] ;
sortedList = new Sprite2D[ maxSpriteCount ] ;
#if ENABLE_SIN_TABLE
if ( sinTable == null ) {
sinTable = new float[ 4096 ] ;
for ( int i = 0 ; i < 4096 ; i ++ ) {
sinTable[ i ] = FMath.Sin( i * ( FMath.PI / 2048.0f ) ) ;
}
}
#endif // ENABLE_SIN_TABLE
}
开发者ID:hatano0x06,项目名称:Coroppoxus,代码行数:25,代码来源:Sprite2dBatch.cs
示例9: OnCreateDevice
public void OnCreateDevice(object sender, EventArgs e )
{
Device dev = (Device)sender;
vertexBuffer =
new VertexBuffer(typeof(CustomVertex.TransformedColored ),
3, dev, 0, CustomVertex.TransformedColored.Format,
Pool.Default ) ;
GraphicsStream stm = vertexBuffer.Lock( 0, 0, 0 ) ;
CustomVertex.TransformedColored[ ] verts = new CustomVertex.TransformedColored[ 3 ] ;
verts[0].X = 150 ;
verts[0].Y = 50 ;
verts[0].Z = 0.5f ;
verts[0].Rhw = 1 ;
verts[0].Color = System.Drawing.Color.Aqua.ToArgb ( ) ;
verts[1].X = 250 ;
verts[1].Y = 250 ;
verts[1].Z = 0.5f ;
verts[1].Rhw = 1 ;
verts[1].Color = System.Drawing.Color.Brown.ToArgb ( ) ;
verts[2].X = 50 ;
verts[2].Y = 250 ;
verts[2].Z = 0.5f ;
verts[2].Rhw = 1 ;
verts[2].Color = System.Drawing.Color.LightPink.ToArgb ( ) ;
stm.Write ( verts ) ;
vertexBuffer.Unlock ( ) ;
}
开发者ID:JeremiahZhang,项目名称:AKA,代码行数:29,代码来源:triangle.cs
示例10: PointsGisLayerCPU
public PointsGisLayerCPU(Game game, int maxPointsCount, bool isDynamic = true) : base(game)
{
PointsCountToDraw = maxPointsCount;
indeces = new int[maxPointsCount*6];
PointsDrawOffset = 0;
SizeMultiplier = 1;
var vbOptions = isDynamic ? VertexBufferOptions.Dynamic : VertexBufferOptions.Default;
currentBuffer = new VertexBuffer(Game.GraphicsDevice, typeof(Gis.CartPoint), maxPointsCount * 4, vbOptions);
PointsCpu = new Gis.CartPoint[maxPointsCount*4];
indBuf = new IndexBuffer(Game.GraphicsDevice, indeces.Length);
for (int i = 0; i < maxPointsCount; i += 1) {
indeces[i*6 + 0] = i*4 + 0;
indeces[i*6 + 1] = i*4 + 1;
indeces[i*6 + 2] = i*4 + 2;
indeces[i*6 + 3] = i*4 + 1;
indeces[i*6 + 4] = i*4 + 3;
indeces[i*6 + 5] = i*4 + 2;
}
indBuf.SetData(indeces);
shader = Game.Content.Load<Ubershader>("globe.Debug.hlsl");
factory = shader.CreateFactory(typeof(PointFlags), Primitive.TriangleList, VertexInputElement.FromStructure<Gis.CartPoint>(), BlendState.AlphaBlend, RasterizerState.CullCW, DepthStencilState.None);
}
开发者ID:demiurghg,项目名称:FusionEngine,代码行数:29,代码来源:PointsGisLayerCPU.cs
示例11: RenderToDevice
public override void RenderToDevice(GraphicsDevice device, BasicEffect basicEffet)
{
if (Visible)
{
if (!basicEffet.LightingEnabled)
{
if (isConstructed == false)
Construct();
using
(
VertexBuffer buffer = new VertexBuffer(
device,
VertexPositionColor.VertexDeclaration,
points,
BufferUsage.WriteOnly)
)
{
// Load the buffer
buffer.SetData(pointList);
// Send the vertex buffer to the device
device.SetVertexBuffer(buffer);
device.DrawUserIndexedPrimitives<VertexPositionColor>(PrimitiveType.LineList, pointList, 0, 6, lineListIndices, 0, 3);
}
}
}
}
开发者ID:codec-abc,项目名称:3DIsoTetrisXNA,代码行数:28,代码来源:DummyObject.cs
示例12: CreateShape
public void CreateShape()
{
double angle = MathHelper.TwoPi / CIRCLE_NUM_POINTS;
_vertices = new VertexPositionNormalTexture[CIRCLE_NUM_POINTS + 1];
_vertices[0] = new VertexPositionNormalTexture(
Vector3.Zero, Vector3.Forward, Vector2.One);
for (int i = 1; i <= CIRCLE_NUM_POINTS; i++)
{
float x = (float)Math.Round(Math.Sin(angle * i), 4);
float y = (float)Math.Round(Math.Cos(angle * i), 4);
Vector3 point = new Vector3(
x,
y,
0.0f);
_vertices[i] = new VertexPositionNormalTexture(
point,
Vector3.Forward,
new Vector2());
}
buffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionNormalTexture), _vertices.Length,
BufferUsage.None);
// Set the vertex buffer data to the array of vertices
buffer.SetData<VertexPositionNormalTexture>(_vertices);
InitializeLineStrip();
}
开发者ID:ravduke,项目名称:Tank-Wars,代码行数:32,代码来源:BoundingSphere3D.cs
示例13: CreateVertexBuffer
void CreateVertexBuffer()
{
VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[number_of_vertices];
float halfWidth = (number_of_cols - 1) * 0.5f;
float halfDepth = (number_of_rows - 1) * 0.5f;
float du = 1.0f / (number_of_cols - 1);
float dv = 1.0f / (number_of_rows - 1);
for (int i = 0; i < number_of_rows; ++i)
{
float z = halfDepth - i;
for (int j = 0; j < number_of_cols;++j)
{
float x = -halfWidth + j;
float y = getHeight(x, z);
vertices[i * number_of_cols + j].Position = new Vector3(x, y, z);
vertices[i * number_of_cols + j].TextureCoordinate = new Vector2(j * du, i * dv);
Vector3 normal = new Vector3();
normal.X = -0.03f * z * (float)Math.Cos(0.1f * x) - 0.3f * (float)Math.Cos(0.1f * z);
normal.Y = 1;
normal.Z = -0.3f * (float)Math.Sin(0.1f * x) + 0.03f * x *(float)Math.Sin(0.1f * z);
normal.Normalize();
vertices[i * number_of_cols + j].Normal = normal;
}
}
vertexBuffer = new VertexBuffer(GraphicsDevice, VertexPositionNormalTexture.VertexDeclaration, number_of_vertices, BufferUsage.WriteOnly);
vertexBuffer.SetData<VertexPositionNormalTexture>(vertices);
}
开发者ID:east1011,项目名称:PhysicallyBasedRendering,代码行数:34,代码来源:Game1Backreference.cs
示例14: Sphere
public Sphere(float Radius, GraphicsDevice graphics, Texture2D tex, Texture2D prograde, Texture2D retrograde,
Texture2D maneuverPrograde, Texture2D targetPrograde, Texture2D targetRetrograde)
{
this.prograde = new Bilboard (prograde, Matrix.CreateScale (1.0f));
this.retrograde = new Bilboard (retrograde, Matrix.CreateScale (1.0f));
this.maneuverPrograde = new Bilboard (maneuverPrograde, Matrix.CreateScale (1.0f));
this.targetPrograde = new Bilboard (targetPrograde, Matrix.CreateScale (1.0f));
this.targetRetrograde = new Bilboard (targetRetrograde, Matrix.CreateScale (1.0f));
texture = tex;
radius = Radius;
graphicd = graphics;
effect = new BasicEffect(graphicd);
nvertices = res * res; // 90 vertices in a circle, 90 circles in a sphere
nindices = res * res * 6;
vbuffer = new VertexBuffer(graphics, typeof(VertexPositionNormalTexture), nvertices, BufferUsage.WriteOnly);
ibuffer = new IndexBuffer(graphics, IndexElementSize.SixteenBits, nindices, BufferUsage.WriteOnly);
createspherevertices();
createindices();
vbuffer.SetData<VertexPositionNormalTexture>(vertices);
ibuffer.SetData<short>(indices);
effect.TextureEnabled = true;
effect.LightingEnabled = true;
rotQuat = Quaternion.Identity;
}
开发者ID:BackgroundNose,项目名称:KSP_External_Navball_MK2,代码行数:27,代码来源:Sphere.cs
示例15: Create
/// <summary>
/// Allocates an empty vertex buffer.
/// </summary>
/// <param name="numVertices">The number of vertices to allocate.</param>
public void Create(int numVertices)
{
if (_vertexBuffer != null)
Clear();
_vertexBuffer = new VertexBuffer(GraphicsDevice.Device, PositionColoredTextured.StrideSize * numVertices, Usage.WriteOnly, PositionColoredTextured.Format, Pool.Default);
++_allocationCount;
}
开发者ID:HAF-Blade,项目名称:MediaPortal-2,代码行数:11,代码来源:PrimitiveBuffer.cs
示例16: Tile
public Tile(Texture2D texture2D, GraphicsDeviceManager graphicsDeviceManager, Vector3 position, Vector3 dimension)
{
texture = texture2D;
tile = new VertexPositionTexture[14];
tile[0] = new VertexPositionTexture(new Vector3(position.X, position.Y, position.Z), new Vector2(0, 0));
tile[1] = new VertexPositionTexture(new Vector3(position.X + dimension.X, position.Y, position.Z), new Vector2(1, 0));
tile[2] = new VertexPositionTexture(new Vector3(position.X, position.Y + dimension.Y, position.Z), new Vector2(0, 1));
tile[3] = new VertexPositionTexture(new Vector3(position.X + dimension.X, position.Y + dimension.Y, position.Z), new Vector2(1, 1));
tile[4] = new VertexPositionTexture(new Vector3(position.X + dimension.X, position.Y + dimension.Y, position.Z + dimension.Z), new Vector2(1, 0));
tile[5] = new VertexPositionTexture(new Vector3(position.X + dimension.X, position.Y, position.Z), new Vector2(0, 1));
tile[6] = new VertexPositionTexture(new Vector3(position.X + dimension.X, position.Y, position.Z + dimension.Z), new Vector2(0, 0));
tile[7] = new VertexPositionTexture(new Vector3(position.X, position.Y, position.Z), new Vector2(1, 1));
tile[8] = new VertexPositionTexture(new Vector3(position.X, position.Y, position.Z + dimension.Z), new Vector2(1, 0));
tile[9] = new VertexPositionTexture(new Vector3(position.X, position.Y + dimension.Y, position.Z), new Vector2(0, 1));
tile[10] = new VertexPositionTexture(new Vector3(position.X, position.Y + dimension.Y, position.Z + dimension.Z), new Vector2(0, 0));
tile[11] = new VertexPositionTexture(new Vector3(position.X + dimension.X, position.Y + dimension.Y, position.Z + dimension.Z), new Vector2(1, 0));
tile[12] = new VertexPositionTexture(new Vector3(position.X, position.Y, position.Z + dimension.Z), new Vector2(0, 1));
tile[13] = new VertexPositionTexture(new Vector3(position.X + dimension.X, position.Y, position.Z + dimension.Z), new Vector2(1, 1));
// Set vertex data in VertexBuffer
vertexBuffer = new VertexBuffer(graphicsDeviceManager.GraphicsDevice, typeof(VertexPositionTexture), tile.Length, BufferUsage.None);
vertexBuffer.SetData(tile);
// Initialize the BasicEffect
effect = new BasicEffect(graphicsDeviceManager.GraphicsDevice);
}
开发者ID:Woodje,项目名称:3DGame,代码行数:27,代码来源:Tile.cs
示例17: CreateTextures
public bool CreateTextures()
{
CustomVertex[] verts;
//We will use blue as the transparent color
Color colorKeyVal = Color.FromArgb(255, 0, 0, 255);
try {
//Load the walking guy textures
string textureFile;
for(int i=1; i<=10; i++) {
textureFile = Application.StartupPath + @"\..\..\Images\walk" + i.ToString() + ".bmp";
textures[i-1] = TextureLoader.FromFile(device, textureFile);
}
//Load the transparent texture
TranspTexture = TextureLoader.FromFile(device,
Application.StartupPath + @"\..\..\Images\TranspSample.bmp",
64, 64, D3DX.Default, 0, Format.Unknown, Pool.Managed, Filter.Point, Filter.Point,
colorKeyVal.ToArgb());
vertBuffer = new VertexBuffer(typeof(CustomVertex),
numVerts, device, Usage.WriteOnly, customVertexFlags, Pool.Default);
verts = vertBuffer.Lock(0, 0) as CustomVertex[];
SquareVertices(verts);
vertBuffer.Unlock();
return true;
}
catch {
return false;
}
}
开发者ID:timdetering,项目名称:BeginningNetGameProgramming,代码行数:29,代码来源:TransparentTest.cs
示例18: BufferGlyph
public BufferGlyph(VertexBuffer buffer, int offset, int triangles, Vector2 escape)
: base(escape)
{
Buffer = buffer;
VertexOffset = offset;
TriangleCount = triangles;
}
开发者ID:liwq-net,项目名称:XnaVG,代码行数:7,代码来源:BufferGlyph.cs
示例19: DrawLineList
public static void DrawLineList(Vector3[] lineList, int vertices, Color color)
{
// Initialize an array of indices of type short.
lineListIndices = new short[vertices];
pointList = new VertexPositionColor[vertices];
for (int p = 0; p < vertices; p++)
{
pointList[p] =
new VertexPositionColor(
lineList[p], color
);
lineListIndices[p] = (short)(p);
}
// Initialize the vertex buffer, allocating memory for each vertex.
vertexBuffer = new VertexBuffer(Game.Game.Graphics.GraphicsDevice, vertexDeclaration,
vertices, BufferUsage.None);
// Set the vertex buffer data to the array of vertices.
vertexBuffer.SetData<VertexPositionColor>(pointList);
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
pass.Apply();
Game.Game.Graphics.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
PrimitiveType.LineList,
pointList,
0, // vertex buffer offset to add to each element of the index buffer
vertices, // number of vertices in pointList
lineListIndices, // the index buffer
0, // first index element to read
vertices / 2 // number of primitives to draw
);
}
}
开发者ID:spdemille,项目名称:Baffled,代码行数:35,代码来源:Primitives.cs
示例20: SetupVertices
private void SetupVertices() {
vertices = new VertexPositionColor[size.X * size.Y + 2];
vertexDeclaration = new VertexDeclaration(vertices);
vertexBuffer = new VertexBuffer(CamTest.graphics.GraphicsDevice, typeof(VertexPositionColor), vertices.Length, BufferUsage.None);
int vertID = 0;
for (int x = 0; x < size.X + 1; x++) {
vertices[vertID].Position = new Vector3(x * cellSize.X, 0f, 0f);
vertices[vertID].Color = color;
vertices[vertID + 1].Position = new Vector3(x * cellSize.X, 0f, size.Y * cellSize.Y);
vertices[vertID + 1].Color = color;
vertID += 2;
}
for (int y = 0; y < size.Y + 1; y++) {
vertices[vertID].Position = new Vector3(0f, 0f, y * cellSize.Y);
vertices[vertID].Color = color;
vertices[vertID + 1].Position = new Vector3(size.X * cellSize.X, 0f, y * cellSize.Y);
vertices[vertID + 1].Color = color;
vertID += 2;
}
vertexBuffer.SetData<VertexPositionColor>(vertices);
}
开发者ID:GodLesZ,项目名称:svn-dump,代码行数:25,代码来源:Grid.cs
注:本文中的VertexBuffer类示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论