中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站定制的公司哪家好百度模擬搜索點(diǎn)擊軟件

網(wǎng)站定制的公司哪家好,百度模擬搜索點(diǎn)擊軟件,2019網(wǎng)站建設(shè),如何上傳網(wǎng)站模板一、前言: OpenGL 1.0采用固定管線,OpenGL 2.0以上版本重要的改變就是采用了可編程管線,Shader 編程是指使用著色器(Shader)編寫代碼來控制圖形渲染管線中特定階段的處理過程。在圖形渲染中,著色器是在 GP…

一、前言:

OpenGL 1.0采用固定管線,OpenGL 2.0以上版本重要的改變就是采用了可編程管線,Shader 編程是指使用著色器(Shader)編寫代碼來控制圖形渲染管線中特定階段的處理過程。在圖形渲染中,著色器是在 GPU 上執(zhí)行的小型程序,用于定義圖形渲染管線中不同階段的處理邏輯,以實(shí)現(xiàn)各種視覺效果,那么渲染管線哪個階段可編程呢?

在這里插入圖片描述

就是上圖的渲染管線藍(lán)色部分。

二、Shader介紹:

1、Vertex Shader和Fragment Shader:

在現(xiàn)代的圖形渲染中,通常會使用兩種主要類型的著色器:頂點(diǎn)著色器(Vertex Shader)和片元著色器(Fragment Shader)。這兩種著色器分別負(fù)責(zé)處理圖形的頂點(diǎn)數(shù)據(jù)和片元(像素)數(shù)據(jù),通過編寫這些著色器程序,開發(fā)人員可以實(shí)現(xiàn)各種復(fù)雜的圖形效果和渲染技術(shù)。

下面是對頂點(diǎn)著色器和片元著色器的簡要介紹:

  • 頂點(diǎn)著色器
    • 頂點(diǎn)著色器用于處理圖形的頂點(diǎn)數(shù)據(jù),如位置、顏色、法線等。
    • 主要作用包括對頂點(diǎn)位置的變換(如模型變換、視圖變換、投影變換)、法線變換、頂點(diǎn)著色等。
    • 頂點(diǎn)著色器的輸出通常是裁剪空間坐標(biāo)或者屏幕空間坐標(biāo)。
  • 片元著色器
    • 片元著色器用于處理圖元的片元(像素)數(shù)據(jù),負(fù)責(zé)計(jì)算最終的顏色輸出。
    • 在片元著色器中,開發(fā)人員可以實(shí)現(xiàn)光照、紋理映射、陰影、透明度等效果。
    • 片元著色器的輸出通常是片元的顏色、深度值、法線等。

2、圖元:

在Shader編程中,“圖元”(Primitive)指的是基本的幾何圖形單元,通常是指在3D圖形渲染中的基本幾何形狀,如點(diǎn)、線、三角形、四邊形等。這些基本的幾何圖形單元是構(gòu)成復(fù)雜場景的基礎(chǔ),它們通過渲染管線進(jìn)行處理和轉(zhuǎn)換,最終呈現(xiàn)在屏幕上。

在Shader編程中,圖元是渲染管線處理的基本單位,Shader程序會對每個圖元進(jìn)行相應(yīng)的處理,包括頂點(diǎn)變換、光照計(jì)算、紋理映射等操作,最終將圖元渲染到屏幕上。常見的幾何圖元有以下幾種:

  1. 點(diǎn)(Point):最簡單的圖元,通常用于表示粒子、光源等。
  2. 線(Line):由兩個點(diǎn)組成的圖元,可用于繪制線條、邊緣等。
  3. 三角形(Triangle):由三個頂點(diǎn)組成的圖元,是最基本的多邊形,是3D圖形學(xué)中最重要的圖元之一,因?yàn)樗袕?fù)雜的表面都可以由三角形網(wǎng)格構(gòu)成。
  4. 四邊形(Quadrilateral):由四個頂點(diǎn)組成的圖元,通常被拆分為兩個三角形處理。

Shader程序通過對這些基本圖元進(jìn)行處理和變換,最終形成了復(fù)雜的場景和圖像。在Shader編程中,開發(fā)人員可以通過編寫頂點(diǎn)著色器和片元著色器來對這些圖元進(jìn)行處理,實(shí)現(xiàn)各種視覺效果和渲染技術(shù)。處理圖元是Shader程序中的一個重要任務(wù),它直接影響著最終的渲染效果和性能。

3、三角形:

上面的四個圖元中,其實(shí)最重要的是三角形,我們把大多數(shù)復(fù)雜的圖形都可以用三角形拼起來,就像我小時(shí)候(不敢說你們00后小時(shí)候)糊燈籠一樣。

比如,我之前文章提到的這個復(fù)雜的圖,也都是由眾多小三角形構(gòu)成:

在這里插入圖片描述

三、重要坐標(biāo)系:

在 OpenGL ES 中,“標(biāo)準(zhǔn)設(shè)備坐標(biāo)系”(Normalized Device Coordinates)和“屏幕坐標(biāo)系”(Screen Coordinates)是兩種不同的坐標(biāo)系,它們在圖形渲染過程中扮演不同的角色。

  1. 標(biāo)準(zhǔn)設(shè)備坐標(biāo)系(Normalized Device Coordinates)
    • 標(biāo)準(zhǔn)設(shè)備坐標(biāo)系是一個抽象的坐標(biāo)系,它是一個以屏幕空間的中心為原點(diǎn),范圍從 -1 到 1 的立方體空間。
    • 在標(biāo)準(zhǔn)設(shè)備坐標(biāo)系中,坐標(biāo) (0, 0) 表示屏幕中心,(-1, -1) 表示左下角,(1, 1) 表示右上角。
    • 所有的頂點(diǎn)數(shù)據(jù)在通過VertexShader處理后都會被映射到標(biāo)準(zhǔn)設(shè)備坐標(biāo)系,這是 OpenGL ES 中進(jìn)行圖形變換和裁剪的標(biāo)準(zhǔn)坐標(biāo)系。
  2. 屏幕坐標(biāo)系(Screen Coordinates)
    • 屏幕坐標(biāo)系是實(shí)際顯示設(shè)備的坐標(biāo)系,它通常以左上角為原點(diǎn),向右為 x 軸正方向,向下為 y 軸正方向。
    • 屏幕坐標(biāo)系的坐標(biāo)值通常是以像素為單位的整數(shù)值,用來確定在屏幕上繪制圖像和文本等元素的位置。

在 OpenGL ES 渲染過程中,頂點(diǎn)數(shù)據(jù)首先被定義在對象坐標(biāo)系中,然后通過模型變換、視圖變換和投影變換將其轉(zhuǎn)換到標(biāo)準(zhǔn)設(shè)備坐標(biāo)系中,最終在屏幕上繪制出來。

在這里插入圖片描述

總結(jié)來說,標(biāo)準(zhǔn)設(shè)備坐標(biāo)系是為了方便進(jìn)行圖形變換和裁剪而定義的坐標(biāo)系,而屏幕坐標(biāo)系則是實(shí)際顯示設(shè)備上的坐標(biāo)系,用于確定最終圖像的位置。OpenGL ES 中的渲染過程涉及將頂點(diǎn)數(shù)據(jù)從對象坐標(biāo)系轉(zhuǎn)換到標(biāo)準(zhǔn)設(shè)備坐標(biāo)系,最終映射到屏幕坐標(biāo)系進(jìn)行顯示。

四、GLSL語言:

1、概念:

著色器是使用一種叫GLSL的類C語言寫成的。GLSL是為圖形計(jì)算量身定制的,它包含一些針對向量和矩陣操作的有用特性。

著色器的開頭總是要聲明版本,接著是輸入和輸出變量、uniform和main函數(shù)。每個著色器的入口點(diǎn)都是main函數(shù),在這個函數(shù)中我們處理所有的輸入變量,并將結(jié)果輸出到輸出變量中。

一個典型的著色器有下面的結(jié)構(gòu):

#version version_number
in type in_variable_name;
in type in_variable_name;out type out_variable_name;uniform type uniform_name;void main()
{// 處理輸入并進(jìn)行一些圖形操作...// 輸出處理過的結(jié)果到輸出變量out_variable_name = weird_stuff_we_processed;
}

當(dāng)我們特別談?wù)摰巾旤c(diǎn)著色器的時(shí)候,每個輸入變量也叫頂點(diǎn)屬性(Vertex Attribute)。我們能聲明的頂點(diǎn)屬性是有上限的,它一般由硬件來決定。OpenGL確保至少有16個包含4分量的頂點(diǎn)屬性可用,但是有些硬件或許允許更多的頂點(diǎn)屬性,你可以查詢GL_MAX_VERTEX_ATTRIBS來獲取具體的上限:

int nrAttributes;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);
std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl;

通常情況下它至少會返回16個,大部分情況下是夠用了。

2、數(shù)據(jù)傳遞:

在這里插入圖片描述

  • 可以將Prog想象成一個芯片,有很多的引腳,比如這兒的1綁定的是VertextShader,2綁定的是FragmentShader。
  • 頂點(diǎn)著色器Vertex負(fù)責(zé)確定3D圖形的三個頂點(diǎn),片元著色器Fragment負(fù)責(zé)確定每個像素的顏色;
  • 數(shù)據(jù)傳給1的時(shí)候,就會自動傳給vPosition;看看具體怎么傳遞的:
    • 通過glGetAttribLocation獲取vPositon的引腳;
    • glEnableVertextAttribArray傳入的參數(shù)就是上一步獲取的ID,這樣,就可以打開這個引腳;
    • 通過glVertexAttribPointer將準(zhǔn)備好的頂點(diǎn)數(shù)據(jù)Vertex Buffer Object傳遞給引腳1,這樣vPosition就收到了;
  • 數(shù)據(jù)傳給2的時(shí)候,就會自動傳給vColor
    • 通過glGetUniformLocation獲取引腳;
    • 通過glUniform4fv傳遞給vColor即可;

3、變量:

1)vertex shader變量:

在這里插入圖片描述

  • 輸入變量有:Attribute類型、Uniforms類型(unform變量相當(dāng)于全局變量)、Samplers類型;
  • 輸出變量有:Varying類型(Vertex Shader的輸出,可以作為后續(xù)的Shader的輸入)
  • 內(nèi)部變量有:gl_Position(這個最重要);
    • 以gl開頭的變量都是內(nèi)部變量;
    • vertex shader需要給gl_Position賦值來確定頂點(diǎn)的位置;
    • 渲染管線會根據(jù)gl_Position進(jìn)行圖元裝配;

2)fragment shader變量:

在這里插入圖片描述

  • Varying類型:作為Fragment Shader的輸入,和Vertex Shader的輸出一一對應(yīng);
  • gl_FragColor:內(nèi)部變量,是Fragment Shader的輸出,保存每個像素的顏色;
    • 確定每個像素的最終顏色;
    • 可以和紋理結(jié)合,實(shí)現(xiàn)紋理的映射;
    • 還可以通過它實(shí)現(xiàn)光照、高亮等顏色特效;

五、繪制一個三角形:

1、步驟:

  • 使用GLSurfaceView創(chuàng)建OpenGL ES環(huán)境;

  • 定義頂點(diǎn)著色器和片元著色器以及OpenGL ES程序;

  • 編譯頂點(diǎn)著色器和片元著色器;

    • 使用GLES30.glCreateShader()創(chuàng)建Shader對象;
    • 使用GLES30.glShaderSource()綁定Shader和其源代碼;
    • 使用GLES30.glCompileShader()編譯Shader;
  • 鏈接OpenGL ES程序;

    • 使用GLES30.glCreateProgram()創(chuàng)建OpenGL ES程序;
    • 使用GLES30.glAttachShader()綁定Shader到OpenGL ES程序;
    • 使用GLES30.glLinkProgram()鏈接整個OpenGL ES程序;
  • 使用OpenGL ES程序;

    • 調(diào)用GLES30.glUseProgram()使用OpenGL ES程序;
    • 傳遞頂點(diǎn)數(shù)據(jù)和片元數(shù)據(jù)

2、創(chuàng)建OpenGL ES環(huán)境:

定義GLSurfaceView

// 文件路徑:com/example/glsurfaceviewdemo/GLSurfaceViewTest.java
public class GLSurfaceViewTest extends GLSurfaceView {public GLSurfaceViewTest(Context context) {super(context);// 設(shè)置OpenGL ES版本(由于3.0兼容2.0,我們使用3.0)setEGLContextClientVersion(3);// 設(shè)置渲染器Renderer,函數(shù)調(diào)用后,里面會啟動一個新線程構(gòu)造EGL環(huán)境setRenderer(new GLRenderTest());}
}

MainActivity使用GLSurfaceView:

// 文件路徑:com/example/glsurfaceviewdemo/MainActivity.java
public class MainActivity extends AppCompatActivity {private GLSurfaceViewTest mGlSurfaceViewTest;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mGlSurfaceViewTest = new GLSurfaceViewTest(this);setContentView(mGlSurfaceViewTest);}
}

3、定義頂點(diǎn)著色器和片元著色器:

// 文件路徑:com/example/glsurfaceviewdemo/Triangle.java
// 定義的頂點(diǎn)著色器代碼private final String mVertexShaderCode ="attribute vec4 vPosition;" +"void main() {" +"  gl_Position = vPosition;" +"}";// 定義的片段著色器代碼private final String mFragmentShaderCode ="precision mediump float;" +"uniform vec4 vColor;" +"void main() {" +"  gl_FragColor = vColor;" +"}";// 定義的三角形頂點(diǎn)坐標(biāo)數(shù)組private final float[] mTriangleCoords = new float[]{0.0f, 0.2f, 0.0f,   // 頂部-0.5f, -0.5f, 0.0f, // 左下角0.5f, -0.5f, 0.0f   // 右下角};// 定義的fragment的顏色數(shù)組,表示每個像素的顏色private final float[] mColor = new float[]{0.0f, 1.0f, 0.0f, 1.0f};

4、定義OpenGL ES程序:

// 文件路徑:com/example/glsurfaceviewdemo/Triangle.java
private int mProgram;
mProgram = GLES30.glCreateProgram();

5、編譯著色器:

// 文件路徑:com/example/glsurfaceviewdemo/Triangle.javapublic Triangle() {// ...// 2.加載并編譯vertexShader和fragmentShaderint vertexShader = Companion.compileShader(GLES30.GL_VERTEX_SHADER, mVertexShaderCode);int fragmentShader = Companion.compileShader(GLES30.GL_FRAGMENT_SHADER, mFragmentShaderCode);// ...}// 定義靜態(tài)內(nèi)部類public static class Companion {// 創(chuàng)建并編譯著色器public static int compileShader(int type, String shaderCode) {// 創(chuàng)建一個著色器int shader = GLES30.glCreateShader(type);// 將著色器代碼設(shè)置到著色器對象中GLES30.glShaderSource(shader, shaderCode);// 編譯著色器GLES30.glCompileShader(shader);return shader;}}

6、鏈接OpenGL ES程序:

// 文件路徑:com/example/glsurfaceviewdemo/Triangle.javapublic Triangle() {// ...// 4.attach兩個編譯好的著色器到program當(dāng)中GLES30.glAttachShader(mProgram, vertexShader);GLES30.glAttachShader(mProgram, fragmentShader);// 5.鏈接整個programGLES30.glLinkProgram(mProgram);}

7、使用OpenGL ES程序:

// 文件路徑:com/example/glsurfaceviewdemo/Triangle.javapublic void draw() {// 使用programGLES30.glUseProgram(mProgram);// 獲取頂點(diǎn)著色器的位置句柄mPositionHandle = GLES30.glGetAttribLocation(mProgram, "vPosition");// 啟用頂點(diǎn)屬性數(shù)組GLES30.glEnableVertexAttribArray(mPositionHandle);// 準(zhǔn)備三角形坐標(biāo)數(shù)據(jù)// 重置緩沖區(qū)位置mVertexBuffer.position(0);// 指定頂點(diǎn)屬性數(shù)據(jù)的格式和位置GLES30.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES30.GL_FLOAT, false, 0, mVertexBuffer);// 獲取片元著色器的顏色句柄mColorHandle = GLES30.glGetUniformLocation(mProgram, "vColor");// 設(shè)置繪制三角形的顏色GLES30.glUniform4fv(mColorHandle, 1, mColor, 0);// 繪制三角形GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, mTriangleCoords.length / COORDS_PER_VERTEX);// 禁用頂點(diǎn)屬性數(shù)組GLES30.glDisableVertexAttribArray(mPositionHandle);}

這就是一個繪制三角形的函數(shù);

8、渲染器調(diào)用:

在渲染器中周期性地調(diào)用上面的繪制函數(shù)。

// 文件路徑:com/example/glsurfaceviewdemo/GLRenderTest.java
public class GLRenderTest implements GLSurfaceView.Renderer {private Triangle mTriangle;@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {GLES30.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);mTriangle = new Triangle();}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {GLES30.glViewport(0, 0,  width, height);}@Overridepublic void onDrawFrame(GL10 gl){GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);mTriangle.draw();}
}

9、運(yùn)行結(jié)果:

在這里插入圖片描述

10、附:全部代碼:

文件路徑:com/example/glsurfaceviewdemo/MainActivity.java

package com.example.glsurfaceviewdemo;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity {private GLSurfaceViewTest mGlSurfaceViewTest;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mGlSurfaceViewTest = new GLSurfaceViewTest(this);setContentView(mGlSurfaceViewTest);}
}

文件路徑:com/example/glsurfaceviewdemo/GLSurfaceViewTest.java

package com.example.glsurfaceviewdemo;import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;public class GLSurfaceViewTest extends GLSurfaceView {public GLSurfaceViewTest(Context context) {super(context);// 設(shè)置OpenGL ES版本(由于3.0兼容2.0,我們使用3.0)setEGLContextClientVersion(3);// 設(shè)置渲染器Renderer,函數(shù)調(diào)用后,里面會啟動一個新線程構(gòu)造EGL環(huán)境setRenderer(new GLRenderTest());}
}

文件路徑:com/example/glsurfaceviewdemo/GLRenderTest.java

package com.example.glsurfaceviewdemo;import android.opengl.GLES30;
import android.opengl.GLSurfaceView;import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;public class GLRenderTest implements GLSurfaceView.Renderer {private Triangle mTriangle;@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {GLES30.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);mTriangle = new Triangle();}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {GLES30.glViewport(0, 0,  width, height);}@Overridepublic void onDrawFrame(GL10 gl){GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);mTriangle.draw();}
}

文件路徑:com/example/glsurfaceviewdemo/Triangle.java

package com.example.glsurfaceviewdemo;import android.opengl.GLES30;import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;import javax.microedition.khronos.opengles.GL;public class Triangle {public Triangle() {// 1.初始化頂點(diǎn)緩沖區(qū),存儲三角形坐標(biāo)// 為頂點(diǎn)坐標(biāo)分配DMA內(nèi)存空間ByteBuffer byteBuffer = ByteBuffer.allocateDirect(mTriangleCoords.length * 4);// 設(shè)置字節(jié)順序?yàn)楸镜刈止?jié)順序(會根據(jù)硬件架構(gòu)自適應(yīng)大小端)byteBuffer.order(ByteOrder.nativeOrder());// 將字節(jié)緩沖區(qū)轉(zhuǎn)換為浮點(diǎn)緩沖區(qū)mVertexBuffer = byteBuffer.asFloatBuffer();// 將頂點(diǎn)三角形坐標(biāo)放入緩沖區(qū)mVertexBuffer.put(mTriangleCoords);// 設(shè)置緩沖區(qū)的位置指針到起始位置mVertexBuffer.position(0);// 2.加載并編譯vertexShader和fragmentShaderint vertexShader = Companion.compileShader(GLES30.GL_VERTEX_SHADER, mVertexShaderCode);int fragmentShader = Companion.compileShader(GLES30.GL_FRAGMENT_SHADER, mFragmentShaderCode);// 3.創(chuàng)建一個OpenGL程序mProgram = GLES30.glCreateProgram();// 4.attach兩個編譯好的著色器到program當(dāng)中GLES30.glAttachShader(mProgram, vertexShader);GLES30.glAttachShader(mProgram, fragmentShader);// 5.鏈接整個programGLES30.glLinkProgram(mProgram);}// 頂點(diǎn)數(shù)據(jù)是float類型,因此,使用這個存儲private FloatBuffer mVertexBuffer;private int mProgram;// 定義的頂點(diǎn)著色器代碼private final String mVertexShaderCode ="attribute vec4 vPosition;" +"void main() {" +"  gl_Position = vPosition;" +"}";// 定義的片段著色器代碼private final String mFragmentShaderCode ="precision mediump float;" +"uniform vec4 vColor;" +"void main() {" +"  gl_FragColor = vColor;" +"}";// 定義的三角形頂點(diǎn)坐標(biāo)數(shù)組private final float[] mTriangleCoords = new float[]{0.0f, 0.2f, 0.0f,   // 頂部-0.5f, -0.5f, 0.0f, // 左下角0.5f, -0.5f, 0.0f   // 右下角};// 定義的fragment的顏色數(shù)組,表示每個像素的顏色private final float[] mColor = new float[]{0.0f, 1.0f, 0.0f, 1.0f};// 頂點(diǎn)著色器的位置句柄private int mPositionHandle = 0;// 片元著色器的位置句柄private int mColorHandle = 0;private final int COORDS_PER_VERTEX = 3;// 定義靜態(tài)內(nèi)部類public static class Companion {// 創(chuàng)建并編譯著色器public static int compileShader(int type, String shaderCode) {// 創(chuàng)建一個著色器int shader = GLES30.glCreateShader(type);// 將著色器代碼設(shè)置到著色器對象中GLES30.glShaderSource(shader, shaderCode);// 編譯著色器GLES30.glCompileShader(shader);return shader;}}public void draw() {// 使用programGLES30.glUseProgram(mProgram);// 獲取頂點(diǎn)著色器的位置句柄mPositionHandle = GLES30.glGetAttribLocation(mProgram, "vPosition");// 啟用頂點(diǎn)屬性數(shù)組GLES30.glEnableVertexAttribArray(mPositionHandle);// 準(zhǔn)備三角形坐標(biāo)數(shù)據(jù)// 重置緩沖區(qū)位置mVertexBuffer.position(0);// 指定頂點(diǎn)屬性數(shù)據(jù)的格式和位置GLES30.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES30.GL_FLOAT, false, 0, mVertexBuffer);// 獲取片元著色器的顏色句柄mColorHandle = GLES30.glGetUniformLocation(mProgram, "vColor");// 設(shè)置繪制三角形的顏色GLES30.glUniform4fv(mColorHandle, 1, mColor, 0);// 繪制三角形GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, mTriangleCoords.length / COORDS_PER_VERTEX);// 禁用頂點(diǎn)屬性數(shù)組GLES30.glDisableVertexAttribArray(mPositionHandle);}
}

六、總結(jié):

本文主要介紹了Shader以及GLSL語言,同時(shí)畫出了一個三角形,但是一般工程中GLSL語言會用單獨(dú)的文件寫,后續(xù)我們改進(jìn)下!

http://www.risenshineclean.com/news/53109.html

相關(guān)文章:

  • 一站式做網(wǎng)站哪家專業(yè)網(wǎng)站怎么收錄到百度
  • 寧波seo網(wǎng)站服務(wù)如何推銷自己的產(chǎn)品
  • oa系統(tǒng)開發(fā)教程seo 資料包怎么獲得
  • 觸摸屏html網(wǎng)站深圳網(wǎng)絡(luò)營銷怎么推廣
  • 溫州專業(yè)微網(wǎng)站制作多少錢sem搜索引擎
  • 建筑資料網(wǎng)站有哪些鄭州seo技術(shù)外包
  • 如果做二手車網(wǎng)站南寧seo公司
  • 團(tuán)購營銷型網(wǎng)站制作關(guān)鍵一招
  • 山西建設(shè)執(zhí)業(yè)注冊管理中心網(wǎng)站怎么推廣比較好
  • 優(yōu)化公司流程制度百度seo關(guān)鍵詞排名 s
  • 旗袍網(wǎng)頁制作模板嘉興seo優(yōu)化
  • 網(wǎng)站建設(shè)方案 安全新媒體營銷成功案例
  • 手表網(wǎng)站有哪個比較好刷外鏈網(wǎng)站
  • WordPress的文本編輯器福建seo
  • 網(wǎng)站開發(fā)的開題任務(wù)書武漢搜索引擎排名優(yōu)化
  • 做紋身注冊什么網(wǎng)站好頭條新聞 最新消息條
  • 二級域名指向 獨(dú)立網(wǎng)站營銷型企業(yè)網(wǎng)站
  • 東莞網(wǎng)站哪家好鄭州粒米seo外包
  • 在線做logo的網(wǎng)站惡意點(diǎn)擊軟件哪幾種
  • 支付網(wǎng)站搭建業(yè)務(wù)推廣網(wǎng)站
  • 做網(wǎng)站前臺用什么軟件軟文營銷是什么
  • 上海建設(shè)網(wǎng)站浦東新區(qū)污水管網(wǎng)工程鄭州網(wǎng)站seo推廣
  • 日本插畫網(wǎng)站中國十大搜索引擎排名
  • 做網(wǎng)站在圖片里加文字流量平臺
  • 做傳奇網(wǎng)站報(bào)毒怎么處理bing搜索引擎入口
  • 用QQ群做網(wǎng)站排名現(xiàn)在最火的推廣平臺有哪些
  • 網(wǎng)站建設(shè)制作視頻長沙seo步驟
  • 做網(wǎng)站怎么每天更新內(nèi)容旺道優(yōu)化軟件
  • 福州做網(wǎng)站互聯(lián)網(wǎng)公司做百度推廣的公司電話號碼
  • 鄭州做網(wǎng)站的公司哪家專業(yè)seo網(wǎng)站