OpenGLES学习第三步:绘制立方体

2024-04-17 14:08

本文主要是介绍OpenGLES学习第三步:绘制立方体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

package test.com.opengles5_3;import android.opengl.GLES20;import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;/*** Created by hbin on 2016/8/2.* 颜色立方体*/
public class Cube {int mProgram;//自定义渲染管线着色器程序idint muMVPMatrixHandle;//总变换矩阵引用int maPositionHandle;//顶点位置属性引用int maColorHandle;//顶点颜色属性引用String mVertexShader;//顶点设色器代码脚本String mFragmentShader;//片元着色器代码脚本FloatBuffer mVertexBuffer;//顶点坐标数据缓冲FloatBuffer mColorBuffer;//顶点着色数据缓冲int vCount=0;public Cube(MySurfaceView mv){initVertexData();initShader(mv);}//初始化顶点坐标与着色数据的方法public void initVertexData(){//总顶点数vCount=12*6;//一共6个面,每个面12个顶点,每个面4个三角形float vertices[]=new float[]{//opengles以三角形方式绘制多边形,此处把一个平面分成4个三角形进行绘制//以立方体的中心点作为三维坐标系的原点,z轴穿过前面,后面的中心点//x轴穿过左右面的中心点//y轴穿过上下面的中心点//前面0,0,Constant.UNIT_SIZE,//前面的中心点Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,// 右上-Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,//左上0,0,Constant.UNIT_SIZE,//前面中心点-Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,//左上-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,//左下0,0,Constant.UNIT_SIZE,//前面中心点-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,//左下Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,//右下0,0,Constant.UNIT_SIZE,//前面中心点Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,//右下Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,//右上//后面0,0,-Constant.UNIT_SIZE,//后面中心点Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//右上Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//右下0,0,-Constant.UNIT_SIZE,//后面中心点Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//右下-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//左下0,0,-Constant.UNIT_SIZE,//后面中心点-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//左下-Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//左上0,0,-Constant.UNIT_SIZE,//后面中心点-Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//左上Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//右上//左面-Constant.UNIT_SIZE,0,0,//左面中心点-Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,//左前-Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//左后-Constant.UNIT_SIZE,0,0,//左面中心点-Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//左后-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//左下-Constant.UNIT_SIZE,0,0,//左面中心点-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,//左下-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,//右下-Constant.UNIT_SIZE,0,0,//左面中心点-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,//右下-Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,// 左后//右面Constant.UNIT_SIZE,0,0,Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,0,0,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,0,0,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,0,0,Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,//上面0,Constant.UNIT_SIZE,0,Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,0,Constant.UNIT_SIZE,0,Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,0,Constant.UNIT_SIZE,0,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,0,Constant.UNIT_SIZE,0,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,Constant.UNIT_SIZE,//下面0,-Constant.UNIT_SIZE,0,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,0,-Constant.UNIT_SIZE,0,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,0,-Constant.UNIT_SIZE,0,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,0,-Constant.UNIT_SIZE,0,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,-Constant.UNIT_SIZE,Constant.UNIT_SIZE,};//创建顶点坐标数据缓冲vertices.length*4是因为一个float四个字节ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4);vbb.order(ByteOrder.nativeOrder());//设置字节顺序mVertexBuffer=vbb.asFloatBuffer();//转为Float型缓冲mVertexBuffer.put(vertices);//向缓冲区放入顶点坐标数据mVertexBuffer.position(0);//设置缓冲区起始位置//顶点颜色值数组,每个顶点4个色彩值  RGBAfloat colors[]=new float[]{//前面1,1,1,0,//中间为白色1,0,0,0,1,0,0,0,1,1,1,0,//中间为白色1,0,0,0,1,0,0,0,1,1,1,0,//中间为白色1,0,0,0,1,0,0,0,1,1,1,0,//中间为白色1,0,0,0,1,0,0,0,//后面1,1,1,0,//中间为白色0,0,1,0,0,0,1,0,1,1,1,0,//中间为白色0,0,1,0,0,0,1,0,1,1,1,0,//中间为白色0,0,1,0,0,0,1,0,1,1,1,0,//中间为白色0,0,1,0,0,0,1,0,//左面1,1,1,0,//中间为白色1,0,1,0,1,0,1,0,1,1,1,0,//中间为白色1,0,1,0,1,0,1,0,1,1,1,0,//中间为白色1,0,1,0,1,0,1,0,1,1,1,0,//中间为白色1,0,1,0,1,0,1,0,//右面1,1,1,0,//中间为白色1,1,0,0,1,1,0,0,1,1,1,0,//中间为白色1,1,0,0,1,1,0,0,1,1,1,0,//中间为白色1,1,0,0,1,1,0,0,1,1,1,0,//中间为白色1,1,0,0,1,1,0,0,//上面1,1,1,0,//中间为白色0,1,0,0,0,1,0,0,1,1,1,0,//中间为白色0,1,0,0,0,1,0,0,1,1,1,0,//中间为白色0,1,0,0,0,1,0,0,1,1,1,0,//中间为白色0,1,0,0,0,1,0,0,//下面1,1,1,0,//中间为白色0,1,1,0,0,1,1,0,1,1,1,0,//中间为白色0,1,1,0,0,1,1,0,1,1,1,0,//中间为白色0,1,1,0,0,1,1,0,1,1,1,0,//中间为白色0,1,1,0,0,1,1,0,};//创建顶点着色数据缓冲ByteBuffer cbb=ByteBuffer.allocateDirect(colors.length*4);cbb.order(ByteOrder.nativeOrder());//设置字节序mColorBuffer=cbb.asFloatBuffer();//转换为Float型缓冲mColorBuffer.put(colors);//向缓冲区放入顶点着色数据mColorBuffer.position(0);//设置缓冲区起始位置}//初始化shaderpublic void initShader(MySurfaceView mv){//加载顶点着色器的脚本内容mVertexShader=ShaderUtil.loadFromAssetsFile("vertex.sh",mv.getResources());//加载片元着色器的脚本内容mFragmentShader=ShaderUtil.loadFromAssetsFile("frag.sh",mv.getResources());//基于顶点着色器与片元着色器创建程序mProgram=ShaderUtil.createProgram(mVertexShader,mFragmentShader);// 获取程序中顶点位置属性引用idmaPositionHandle= GLES20.glGetAttribLocation(mProgram, "aPosition");//获取程序中顶点颜色属性引用idmaColorHandle=GLES20.glGetAttribLocation(mProgram,"aColor");//获取程序中总变换矩阵引用idmuMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram,"uMVPMatrix");}public void drawSelf(){//制定使用某套shader程序GLES20.glUseProgram(mProgram);//将最终变换矩阵传入shader程序GLES20.glUniformMatrix4fv(muMVPMatrixHandle,1,false,MatrixState.getFinalMatrix(),0);//为画笔指定顶点位置数据GLES20.glVertexAttribPointer(maPositionHandle,3,GLES20.GL_FLOAT,false,3*4,mVertexBuffer);//为画笔指定顶点着色数据GLES20.glVertexAttribPointer(maColorHandle,4,GLES20.GL_FLOAT,false,4*4,mColorBuffer);//允许顶点位置数据数组GLES20.glEnableVertexAttribArray(maPositionHandle);GLES20.glEnableVertexAttribArray(maColorHandle);//绘制立方立方体GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,vCount);}
}package test.com.opengles5_3;import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;public class MainActivity extends Activity {private MySurfaceView mGLSurfaceView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 设置为全屏requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置为横屏模式setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);// 初始化GLSurfaceViewmGLSurfaceView = new MySurfaceView(this);// 切换到主界面setContentView(mGLSurfaceView);mGLSurfaceView.requestFocus();// 获取焦点mGLSurfaceView.setFocusableInTouchMode(true);// 设置为可触控}@Overrideprotected void onResume() {super.onResume();mGLSurfaceView.onResume();}@Overrideprotected void onPause() {super.onPause();mGLSurfaceView.onPause();}
}package test.com.opengles5_3;import android.opengl.Matrix;import java.nio.ByteBuffer;/*** Created by hbin on 2016/8/2.* 存储系统矩阵状态的类*/public class MatrixState {private static float[] mProjMatrix=new float[16];//4x4矩阵,投影用private static float[] mVMatrix=new float[16];//摄像机位置朝向9参数矩阵private static float[] currMatrix;//当前变换矩阵//保护变换矩阵的栈static float[][] mStack=new float[10][16];static int stackTop=-1;public static void setInitStack(){currMatrix=new float[16];Matrix.setRotateM(currMatrix,0,0,1,0,0);}public static void pushMatrix(){//保护变换矩阵stackTop++;for (int i=0;i<16;i++){mStack[stackTop][i]=currMatrix[i];}}public static void popMatrix(){//恢复变换矩阵for (int i=0;i<16;i++){currMatrix[i]=mStack[stackTop][i];}stackTop--;}public static void translate(float x,float y,float z){//设置沿xyz轴移动Matrix.translateM(currMatrix,0,x,y,z);}//设置摄像机static ByteBuffer llbb=ByteBuffer.allocateDirect(3*4);static float[] cameraLocation=new float[3];//摄像机位置public static void setCamera(float cx,//摄像机位置xfloat cy,//摄像机位置yfloat cz,//摄像机位置zfloat tx,//摄像机目标点xfloat ty,//摄像机目标点yfloat tz,//摄像机目标点zfloat upx,//摄像机UP向量x分量float upy,//摄像机UP向量y分量float upz//摄像机up向量z分量){Matrix.setLookAtM(mVMatrix,0,cx,cy,cz,tx,ty,tz,upx,upy,upz);}//设置透视投影参数public static void setProjectFrustum(float left,//near面的leftfloat right,//near面的rightfloat bottom,//near面的bottomfloat top,//near面的topfloat near,//near面的距离float far //far面的距离){Matrix.frustumM(mProjMatrix, 0, left, right, bottom, top, near, far);}//设置正交投影参数public static void setProjectOrtho(float left,//near面的leftfloat right,//near面的rightfloat bottom,//near面的bottomfloat top,//near面的topfloat near,//near面距离float far //far面距离){Matrix.orthoM(mProjMatrix,0,left,right,bottom,top,near,far);}//获取具体物体的总变换矩阵static float[] mMVPMatrix=new float[16];public static float[] getFinalMatrix(){Matrix.multiplyMM(mMVPMatrix,0,mVMatrix,0,currMatrix,0);Matrix.multiplyMM(mMVPMatrix,0,mProjMatrix,0,mMVPMatrix,0);return mMVPMatrix;}//获取具体物体的变换矩阵public static float[] getMMatrix(){return currMatrix;}
}package test.com.opengles5_3;import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.util.Log;import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;/*** Created by hbin on 2016/8/2.*/
public class MySurfaceView extends GLSurfaceView{private SceneRenderer mRenderer;//场景渲染器public MySurfaceView(Context context) {super(context);this.setEGLContextClientVersion(2);//设置使用opengl es2.0mRenderer=new SceneRenderer();//创建场景渲染器setRenderer(mRenderer); //设置渲染器setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);}private class SceneRenderer implements GLSurfaceView.Renderer{Cube cube;//立方体@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {//设置屏幕背景色RGBAGLES20.glClearColor(0.5f,0.5f,0.5f,1.0f);//创建立方体对象cube=new Cube(MySurfaceView.this);//打开深度检测GLES20.glEnable(GLES20.GL_DEPTH_TEST);//打开背面剪裁GLES20.glEnable(GLES20.GL_CULL_FACE);}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {//设置视窗大小及位置GLES20.glViewport(0,0,width,height);//计算GLSurfaceView的宽高比Constant.ratio=(float)width/height;//调用此方法计算产生透视投影矩阵MatrixState.setProjectFrustum(-Constant.ratio*0.8f, Constant.ratio*1.2f, -1, 1, 20, 100);//设置摄像机观察矩阵MatrixState.setCamera(-16f,8f,45,0f,0f,0f,0f,1.0f,0.0f);//MatrixState.setCamera(-16f,8f,45,1f,0f,1f,0f,1.0f,0.0f);//初始化变换矩阵MatrixState.setInitStack();}@Overridepublic void onDrawFrame(GL10 gl) {// Log.i("hb-2","onDrawFrame");//清除深度缓冲与颜色缓冲GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);//绘制原立方体MatrixState.pushMatrix();cube.drawSelf();MatrixState.popMatrix();//绘制变换后的立方体MatrixState.pushMatrix();MatrixState.translate(3, 1, -1);cube.drawSelf();MatrixState.popMatrix();}}
}package test.com.opengles5_3;import java.io.ByteArrayOutputStream;
import java.io.InputStream;import android.content.res.Resources;
import android.opengl.GLES20;
import android.util.Log;//加载顶点Shader与片元Shader的工具类
public class ShaderUtil
{//加载制定shader的方法public static int loadShader(int shaderType, //shader的类型  GLES20.GL_VERTEX_SHADER   GLES20.GL_FRAGMENT_SHADERString source   //shader的脚本字符串){//创建一个新shaderint shader = GLES20.glCreateShader(shaderType);//若创建成功则加载shaderif (shader != 0){//加载shader的源代码GLES20.glShaderSource(shader, source);//编译shaderGLES20.glCompileShader(shader);//存放编译成功shader数量的数组int[] compiled = new int[1];//获取Shader的编译情况GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);if (compiled[0] == 0){//若编译失败则显示错误日志并删除此shaderLog.e("ES20_ERROR", "Could not compile shader " + shaderType + ":");Log.e("ES20_ERROR", GLES20.glGetShaderInfoLog(shader));GLES20.glDeleteShader(shader);shader = 0;}}return shader;}//创建shader程序的方法public static int createProgram(String vertexSource, String fragmentSource){//加载顶点着色器int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);if (vertexShader == 0){return 0;}//加载片元着色器int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);if (pixelShader == 0){return 0;}//创建程序int program = GLES20.glCreateProgram();//若程序创建成功则向程序中加入顶点着色器与片元着色器if (program != 0){//向程序中加入顶点着色器GLES20.glAttachShader(program, vertexShader);checkGlError("glAttachShader");//向程序中加入片元着色器GLES20.glAttachShader(program, pixelShader);checkGlError("glAttachShader");//链接程序GLES20.glLinkProgram(program);//存放链接成功program数量的数组int[] linkStatus = new int[1];//获取program的链接情况GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);//若链接失败则报错并删除程序if (linkStatus[0] != GLES20.GL_TRUE){Log.e("ES20_ERROR", "Could not link program: ");Log.e("ES20_ERROR", GLES20.glGetProgramInfoLog(program));GLES20.glDeleteProgram(program);program = 0;}}return program;}//检查每一步操作是否有错误的方法public static void checkGlError(String op){int error;while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR){Log.e("ES20_ERROR", op + ": glError " + error);throw new RuntimeException(op + ": glError " + error);}}//从sh脚本中加载shader内容的方法public static String loadFromAssetsFile(String fname,Resources r){String result=null;try{InputStream in=r.getAssets().open(fname);int ch=0;ByteArrayOutputStream baos = new ByteArrayOutputStream();while((ch=in.read())!=-1){baos.write(ch);}byte[] buff=baos.toByteArray();baos.close();in.close();result=new String(buff,"UTF-8");result=result.replaceAll("\\r\\n","\n");}catch(Exception e){e.printStackTrace();}return result;}
}

 

这篇关于OpenGLES学习第三步:绘制立方体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/912011

相关文章

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

使用Python绘制蛇年春节祝福艺术图

《使用Python绘制蛇年春节祝福艺术图》:本文主要介绍如何使用Python的Matplotlib库绘制一幅富有创意的“蛇年有福”艺术图,这幅图结合了数字,蛇形,花朵等装饰,需要的可以参考下... 目录1. 绘图的基本概念2. 准备工作3. 实现代码解析3.1 设置绘图画布3.2 绘制数字“2025”3.3

使用Python绘制可爱的招财猫

《使用Python绘制可爱的招财猫》招财猫,也被称为“幸运猫”,是一种象征财富和好运的吉祥物,经常出现在亚洲文化的商店、餐厅和家庭中,今天,我将带你用Python和matplotlib库从零开始绘制一... 目录1. 为什么选择用 python 绘制?2. 绘图的基本概念3. 实现代码解析3.1 设置绘图画

Python绘制土地利用和土地覆盖类型图示例详解

《Python绘制土地利用和土地覆盖类型图示例详解》本文介绍了如何使用Python绘制土地利用和土地覆盖类型图,并提供了详细的代码示例,通过安装所需的库,准备地理数据,使用geopandas和matp... 目录一、所需库的安装二、数据准备三、绘制土地利用和土地覆盖类型图四、代码解释五、其他可视化形式1.

如何用Python绘制简易动态圣诞树

《如何用Python绘制简易动态圣诞树》这篇文章主要给大家介绍了关于如何用Python绘制简易动态圣诞树,文中讲解了如何通过编写代码来实现特定的效果,包括代码的编写技巧和效果的展示,需要的朋友可以参考... 目录代码:效果:总结 代码:import randomimport timefrom math

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]