2019電腦圖學 Computer Graphics 授課教師: 葉正聖 銘傳大學資訊傳播工程系 每週主題: 程式環境、點線面顏色、移動/旋轉/縮放與矩陣(Matrix)、階層性關節轉動(T-R-T)、做出機器人、打光、貼圖、glu/glut函式、鍵盤、滑鼠、計時器(timer)、讀入3D模型、粒子系統、聲音、特效、投影矩陣、攝影機與運鏡、機器人2.0、期末作品
2019年6月13日 星期四
2019年6月6日 星期四
電腦圖學-三大總複習
(0)預備工作:
檔案網址:http://www.cmlab.csie.ntu.edu.tw/~jsyeh/3dcg10/
-
壓縮在同一個資料夾(WINDOWS要包含DATA跟GLUT32.DLL和SOURCE)
Download
freeglut 3.0.0 for MinGW壓縮檔案,在LIB裡面複製LIBFREEGLUT,貼上改成LIBGLUT32。
開啟CODEBLOCK。FILE(左上角)->NEW->PROJECT->GLUT PROJECT->(命名檔案)->下一步->路徑改成FREEGLUT資料夾的路徑。
貼圖。注意事項。
- A:貼圖要放在FREEGLUT/BIN。
- B:貼圖需要安裝OPENCV2.1。FREEGLUT。
- C:CODEBLOCK需要在專案的OPTION中進行設定。
- C-1:LINKER SETTING增加 CXCORE210,CV210,HIGHGUI210。(全小寫)
- D-1 SEARCH DIRECTORIES COMPLIER 增加 C:\OPENCV2.1\include
- D-2 SEARCH LINKER C:\OPENCV2.1\lib
- 重開一次CODEBLOCK。
#include <GL/glut.h>
#include <opencv/highgui.h> ///OpenCV High GUI讀圖 ///貼圖需要它
#include <opencv/cv.h> ///OpenCV cvCvtColor() to convert color///貼圖需要它
///程式碼是對的, 但是沒有設定好include, lib, bin
GLuint id1, id2, id3;///NOW2 ///貼圖需要它
float a=0;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, id1);///id1 for background ///貼圖需要它
glBegin(GL_POLYGON); ///貼圖需要它
glTexCoord2f(0, 0); glVertex3f(-1, +1, 0); ///貼圖需要它
glTexCoord2f(0, 1); glVertex3f(-1, -1, 0); ///貼圖需要它
glTexCoord2f(1, 1); glVertex3f(+1, -1, 0); ///貼圖需要它
glTexCoord2f(1, 0); glVertex3f(+1, +1, 0); ///貼圖需要它
glEnd();///貼圖需要它
glBindTexture(GL_TEXTURE_2D, id3);///id3 for rotating square
glPushMatrix();
glTranslatef(0.5, 0.5, 0);
glRotatef(a++, 0, 0, 1);
glScalef(0.3, 0.3, 0.3);
glBegin(GL_POLYGON);
glTexCoord2f(0, 0); glVertex3f(-1, +1, 0);
glTexCoord2f(0, 1); glVertex3f(-1, -1, 0);
glTexCoord2f(1, 1); glVertex3f(+1, -1, 0);
glTexCoord2f(1, 0); glVertex3f(+1, +1, 0);
glEnd();
glPopMatrix();
glBindTexture(GL_TEXTURE_2D, id2);///id2 for teapot
glutSolidTeapot( 0.3 );
glutSwapBuffers();
}
///void myInit()
GLuint myTexture(char * filename) ///貼圖需要它
{
IplImage * img = cvLoadImage(filename); ///NOW OpenCV ///貼圖需要它
cvCvtColor(img, img, CV_BGR2RGB);///convert color ///NOW OpenCV ///貼圖需要它
GLuint id; ///貼圖需要它
glEnable(GL_TEXTURE_2D); ///貼圖需要它
glGenTextures(1, &id ); ///貼圖需要它
glBindTexture(GL_TEXTURE_2D, id); ///貼圖需要它
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_MAG_FILTER, GL_NEAREST); ///貼圖需要它
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); ///貼圖需要它
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height, 0, GL_RGB, GL_UNSIGNED_BYTE, img->imageData); ///貼圖需要它
return id;///貼圖需要它
}
int main(int argc, char **argv)
{
///IplImage * img = cvLoadImage("marvel.jpg");
///cvShowImage("opencv", img);
///cvWaitKey(0);///等你按按鍵
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE |GLUT_DEPTH);
glutCreateWindow("GLUT");///之後
///建好GLUT視窗,可以開始準備 3D 貼圖 (要在create...MainLoop才能建貼圖)
id1 = myTexture("Thunder.jpg"); ///myInit();///我們的貼圖在這裡 ///貼圖需要它
id2 = myTexture("Zero.jpg");
id3 = myTexture("wolf.jpg");
glutDisplayFunc(display);
glutIdleFunc(display);
glutMainLoop();///之前
}
/
glm注意事項
glm注意事項
- glm.c(改名)->glm.cpp,glm.h。記得需要放在專案裡面。
- 專案記得需要addfiles。
- 模組匯入方面。記得OBJ和MLT放在FREEGLUT/BIN5j/
/
#include <GL/glut.h>
#include <opencv/highgui.h> ///OpenCV High GUI讀圖 ///貼圖需要它
#include <opencv/cv.h> ///OpenCV cvCvtColor() to convert color///貼圖需要它
///程式碼是對的, 但是沒有設定好include, lib, bin
GLuint id1, id2, id3;///NOW2 ///貼圖需要它
float a=0;
#include "glm.h"///呼叫外掛 ///glm需要它
GLMmodel * pmodel=NULL;///準備指標 ///glm需要它
GLMmodel * pmodel2=NULL;///準備指標 ///glm需要它
GLMmodel * pmodel3=NULL;///準備指標 ///glm需要它
GLMmodel * pmodel4=NULL;///準備指標 ///glm需要它
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, id1);///id1 for background ///貼圖需要它
glBegin(GL_POLYGON); ///貼圖需要它
glTexCoord2f(0, 0); glVertex3f(-1, +1, -1); ///貼圖需要它
glTexCoord2f(0, 1); glVertex3f(-1, -1, -1); ///貼圖需要它
glTexCoord2f(1, 1); glVertex3f(+1, -1, -1); ///貼圖需要它
glTexCoord2f(1, 0); glVertex3f(+1, +1, -1); ///貼圖需要它
glEnd();///貼圖需要它
if (!pmodel) { ///glm需要它
pmodel = glmReadOBJ("al.obj"); ///glm需要它
if (!pmodel) exit(0); ///glm需要它
///glmUnitize(pmodel); ///glm需要它
glmFacetNormals(pmodel); ///glm需要它
glmVertexNormals(pmodel, 90.0); ///glm需要它
}
glDisable(GL_TEXTURE_2D);
glPushMatrix();
glRotatef(a++, 0,1,0);
glScalef(0.2, 0.2, 0.2);
glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
if (!pmodel2) { ///glm需要它
pmodel2 = glmReadOBJ("F-16.obj"); ///glm需要它
if (!pmodel2) exit(0); ///glm需要它
///glmUnitize(pmodel2); ///glm需要它
glmFacetNormals(pmodel2); ///glm需要它
glmVertexNormals(pmodel2, 90.0); ///glm需要它
}
glDisable(GL_TEXTURE_2D);
glPushMatrix();
glRotatef(a, 0,1,0);
glScalef(0.2, 0.2, 0.2);
glmDraw(pmodel2, GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
glutSwapBuffers();
}
///void myInit()
GLuint myTexture(char * filename) ///貼圖需要它
{
IplImage * img = cvLoadImage(filename); ///NOW OpenCV ///貼圖需要它
cvCvtColor(img, img, CV_BGR2RGB);///convert color ///NOW OpenCV ///貼圖需要它
GLuint id; ///貼圖需要它
glEnable(GL_TEXTURE_2D); ///貼圖需要它
glGenTextures(1, &id ); ///貼圖需要它
glBindTexture(GL_TEXTURE_2D, id); ///貼圖需要它
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_MAG_FILTER, GL_NEAREST); ///貼圖需要它
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); ///貼圖需要它
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height, 0, GL_RGB, GL_UNSIGNED_BYTE, img->imageData); ///貼圖需要它
return id;///貼圖需要它
}
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f }; ///glm需要它
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; ///glm需要它
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; ///glm需要它
const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f }; ///glm需要它
int main(int argc, char **argv)
{
///IplImage * img = cvLoadImage("marvel.jpg");
///cvShowImage("opencv", img);
///cvWaitKey(0);///等你按按鍵
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE |GLUT_DEPTH);
glutCreateWindow("GLUT");///之後
///建好GLUT視窗,可以開始準備 3D 貼圖 (要在create...MainLoop才能建貼圖)
id1 = myTexture("Zero.jpg"); ///myInit();///我們的貼圖在這裡 ///貼圖需要它
id2 = myTexture("wolf.jpg");
id3 = myTexture("Thunder.jpg");
glutDisplayFunc(display);
glutIdleFunc(display);
glEnable(GL_DEPTH_TEST); ///glm需要它
glEnable(GL_LIGHT0); ///glm需要它
glEnable(GL_NORMALIZE); ///glm需要它
glEnable(GL_COLOR_MATERIAL); ///glm需要它
glEnable(GL_LIGHTING); ///glm需要它
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); ///glm需要它
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); ///glm需要它
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); ///glm需要它
glLightfv(GL_LIGHT0, GL_POSITION, light_position); ///glm需要它
glMatrixMode(GL_PROJECTION); ///投影矩陣相關 戴好我們的正確度數的眼睛
glLoadIdentity(); ///投影矩陣相關 戴好我們的正確度數的眼睛
glOrtho(-1,+1, -1,+1, -100,+100); ///投影矩陣相關 戴好我們的正確度數的眼睛
glMatrixMode(GL_MODELVIEW); ///投影矩陣相關 切換回我們正確的矩陣
glutMainLoop();///之前
}
/
2019年5月30日 星期四
06160494電腦圖學_攝影機。
(0)預備工作:
檔案網址:http://www.cmlab.csie.ntu.edu.tw/~jsyeh/3dcg10/
-
壓縮在同一個資料夾(WINDOWS要包含DATA跟GLUT32.DLL和SOURCE)
Download
freeglut 3.0.0 for MinGW壓縮檔案,在LIB裡面複製LIBFREEGLUT,貼上改成LIBGLUT32。
開啟CODEBLOCK。FILE(左上角)->NEW->PROJECT->GLUT PROJECT->(命名檔案)->下一步->路徑改成FREEGLUT資料夾的路徑。
2.
主題:攝影機,運鏡
主題:投影,矩陣
複習:位置移動VS轉動
複習:背景貼圖
期末作品極度警報
右上改模型,又下改投影。ORTHO壓扁
FRUSTUM觀察。
/
#include <GL/glut.h>///GLUT 外掛
#include "glm.h"///glm.cpp for 3D model glmReadOBJ(), glmDraw(), glmUnitized()
GLMmodel * pmodel=NULL;///指標
void drawmodel(void)
{
if (!pmodel) {
pmodel = glmReadOBJ("data/al.obj");
if (!pmodel) exit(0);
glmUnitize(pmodel);
glmFacetNormals(pmodel);
glmVertexNormals(pmodel, 90.0);
}
glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawmodel();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(512,512);
glutInitWindowPosition(50, 50);
glutCreateWindow("week15");
// glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
#include <GL/glut.h>///GLUT 外掛
#include "glm.h"///glm.cpp for 3D model glmReadOBJ(), glmDraw(), glmUnitized()
GLMmodel * pmodel=NULL;///指標
void drawmodel(void)
{
if (!pmodel) {
pmodel = glmReadOBJ("data/al.obj");
if (!pmodel) exit(0);
glmUnitize(pmodel);
glmFacetNormals(pmodel);
glmVertexNormals(pmodel, 90.0);
}
glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawmodel();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(512,512);
glutInitWindowPosition(50, 50);
glutCreateWindow("week15");
// glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
#include <GL/glut.h>///GLUT 外掛
#include "glm.h"///glm.cpp for 3D model glmReadOBJ(), glmDraw(), glmUnitized()
GLMmodel * pmodel=NULL;///指標
void drawmodel(void)
{
if (!pmodel) {
pmodel = glmReadOBJ("data/al.obj");
if (!pmodel) exit(0);
glmUnitize(pmodel);
glmFacetNormals(pmodel);
glmVertexNormals(pmodel, 90.0);
}
glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawmodel();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(512,512);
glutInitWindowPosition(50, 50);
glutCreateWindow("week15");
// glutReshapeFunc(reshape);
glutDisplayFunc(display);
GLfloat light_pos[] = { 0.0, 0.0, -1.0, 0.0 };
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
glutMainLoop();
return 0;
}
/
2019年5月23日 星期四
06160494電腦圖學_計時器。
(0)預備工作:
檔案網址:http://www.cmlab.csie.ntu.edu.tw/~jsyeh/3dcg10/
-
壓縮在同一個資料夾(WINDOWS要包含DATA跟GLUT32.DLL和SOURCE)
Download
freeglut 3.0.0 for MinGW壓縮檔案,在LIB裡面複製LIBFREEGLUT,貼上改成LIBGLUT32。
開啟CODEBLOCK。FILE(左上角)->NEW->PROJECT->GLUT PROJECT->(命名檔案)->下一步->路徑改成FREEGLUT資料夾的路徑。.
(1)今天的主題:
- 主題:計時器。*glutTimerFun(timer)
- 主題:內差公式。(移動補間)
- 主題:動畫。
- 期末作品。
☆聲音檔需要放在FREEGLUT的BIN下☆
☆聲音檔可以打關鍵字WAV下載安裝☆☆為什麼不能打ALT+41400呢?☆
★原來是要換英文阿★
ALPHA*末值+(1-ALPHA)*初值。
OLDANGLE★NEWANGLE☆
注意事項。公式 alpha * newAngle[i] + (1-alpha) * oldAngle[i];。
需要在同時間有著NEW 和 OLD ,兩種的20矩陣。
因此需要將上次從文件讀近來的數字,將此指派給OLD★( oldAngle[i] = newAngle[i];)★
然後從文件讀入新值給NEW ★(fscanf(fin, "%f", &newAngle[i]);)★
之後才可以由
float alpha= (t%30)/30.0;///NOW4 算出alpha值 0.0 ... 1.0
for(int i=0; i<20; i++){///NOW4 20個關節角度
angle[i] = alpha * newAngle[i] + (1-alpha) * oldAngle[i];///NOW4 都要做內插
}
利用公式將內差做出來。
2019年5月16日 星期四
06160494電腦圖學_檔案
(0)預備工作:
檔案網址:http://www.cmlab.csie.ntu.edu.tw/~jsyeh/3dcg10/
-
壓縮在同一個資料夾(WINDOWS要包含DATA跟GLUT32.DLL和SOURCE)
Download
freeglut 3.0.0 for MinGW壓縮檔案,在LIB裡面複製LIBFREEGLUT,貼上改成LIBGLUT32。
開啟CODEBLOCK。FILE(左上角)->NEW->PROJECT->GLUT PROJECT->(命名檔案)->下一步->路徑改成FREEGLUT資料夾的路徑。.
(1)今天的主題:
- 主題:檔案。
- 主題:關節,擺動作。
- 複習:TRT。
- 作業:機器人擺動作。
(2)///切記,READ一次只能讀到一行(目前狀況),write(目前是按了之後會把之後讀到的資料給送進文件中。)(但要在關閉CMD之後才會真實的運作,所以狂按W會導致上次的還沒成功存檔之前,又上傳一次,這會導致。上一次上傳的資料被消除,所以W不要一直按。)
#include <GL/glut.h>
#include <stdio.h>///NOW_FILE (0)
float angle[20];///NOW2
int angleID=1;///NOW3
FILE * fout = NULL;///NOW_FILE (1)
FILE * fin = NULL;///NOW_FILE_READ (1)
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glColor3f(1, 1, 1);///white
glutSolidTeapot( 0.3 );///body
glPushMatrix();///右邊
glTranslatef(0.2, 0, 0);///NOW2 (3)掛上去
glRotatef(angle[1], 0,0,1);///NOW2 ///(2)旋轉
glTranslatef(0.15, 0, 0);///NOW2 (1)旋轉中心
glColor3f(1, 0, 0);///red
glutSolidTeapot( 0.2 );///right arm
glPushMatrix();
glTranslatef(0.2, 0, 0);///NOW2 (3)掛上去
glRotatef(angle[2], 0,0,1);///NOW2 ///(2)旋轉
glTranslatef(0.15, 0, 0);///NOW2 (1)旋轉中心
glColor3f(1, 0, 0);///red
glutSolidTeapot( 0.2 );///right lower arm
glPopMatrix();
glPopMatrix();
glPushMatrix();///左邊
glTranslatef(-0.2, 0, 0);///NOW2 (3)掛上去
glRotatef(angle[3], 0,0,1);///NOW2 ///(2)旋轉
glTranslatef(-0.15, 0, 0);///NOW2 (1)旋轉中心
glColor3f(1, 0, 0);///red
glutSolidTeapot( 0.2 );///right arm
glPushMatrix();
glTranslatef(-0.2, 0, 0);///NOW2 (3)掛上去
glRotatef(angle[4], 0,0,1);///NOW2 ///(2)旋轉
glTranslatef(-0.15, 0, 0);///NOW2 (1)旋轉中心
glColor3f(1, 0, 0);///red
glutSolidTeapot( 0.2 );///right lower arm
glPopMatrix();
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
}
int oldX=0;///NOW2
void mouse(int button, int state, int x, int y)///NOW2
{///NOW2
oldX = x;///NOW2
}
void motion(int x, int y)///NOW2
{///NOW2
angle[angleID] += x-oldX;///NOW3
oldX = x;///NOW2
if(fout == NULL) fout = fopen("motion.txt", "w+");///NOW_FILE (2)
for(int i=0;i<20;i++){///NOW3
printf(" %.2f ", angle[i]);///NOW3
fprintf(fout, " %.2f ", angle[i]);///NOW_FILE
}
printf("\n");///NOW3
fprintf(fout, "\n");///NOW_FILE
display();///NOW2
}
void keyboard(unsigned char key, int x, int y)///NOW3
{///NOW3
if(key=='1') angleID=1;///NOW3
if(key=='2') angleID=2;///NOW3
if(key=='3') angleID=3;///NOW3
if(key=='4') angleID=4;///NOW3
if(key=='w'){///NOW_FILE
fout = fopen("motion.txt", "w+");///NOW_FILE (2)
}
if(key=='r'){
if(fin==NULL) fin = fopen("motion.txt", "r");///NOW_FILE_READ (2)
///scanf("%d", &n);
for(int i=0;i<20; i++){///NOW_FILE_READ
fscanf(fin, "%f", &angle[i]);///NOW_FILE_READ
printf(" %.2f ", angle[i]);///順便印出來看數字對不對
}
}
glutPostRedisplay();///NOW_FILE_READ 和 display()很像
}
int main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
///glutInitWindowSize(600,600);///可以開大一點的window
glutCreateWindow("Week 13 angle motion file");
glutKeyboardFunc(keyboard);///NOW3
glutMouseFunc(mouse);///NOW2
glutMotionFunc(motion);///NOW2
glutDisplayFunc(display);
glutMainLoop();
}
//
FILE * fout=NULL;///宣告檔案指標。
FILE * fout2=NULL;///宣告檔案指標。寫進另一個檔案。
FILE * fin2=NULL;///宣告檔案指標。讀另一個檔案。
fout = fopen("filename.txt","w+");///開檔案,寫進去///大寫沒意義。RWBA。
fprintf(fout,"HelloWorld\n");///印進去。
同理 scanf的改寫就是 fscanf(fout,"%c");**注意,這類方式fout後段不是w+,是r+或r
//
///
EX衍伸知識區
"r"
Opens for reading. If the file does not exist or cannot be found, the fopen call fails.
"w"
Opens an empty file for writing. If the given file exists, its contents are destroyed.
"a"
Opens for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; creates the file first if it doesn’t exist.
"r+"
Opens for both reading and writing. (The file must exist.)
"w+"
Opens an empty file for both reading and writing. If the given file exists, its contents are destroyed.
"a+"
Opens for reading and appending; the appending operation includes the removal of the EOF marker before new data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn’t exist.
Opens for reading. If the file does not exist or cannot be found, the fopen call fails.
"w"
Opens an empty file for writing. If the given file exists, its contents are destroyed.
"a"
Opens for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; creates the file first if it doesn’t exist.
"r+"
Opens for both reading and writing. (The file must exist.)
"w+"
Opens an empty file for both reading and writing. If the given file exists, its contents are destroyed.
"a+"
Opens for reading and appending; the appending operation includes the removal of the EOF marker before new data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn’t exist.

by:"S's Journal"
///
訂閱:
文章 (Atom)

