1. 程式人生 > >GLSL入門2 關於GLSL中的紋理貼圖

GLSL入門2 關於GLSL中的紋理貼圖

我將註解以及原始碼直接放到這裡了

// GLSL01.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <GL/glew.h>
#include <GL/glut.h>
#include <cassert>

using namespace std;

static const int g_timer_id = 0;
static const int g_time_per_frame = 16;//ms

#define OFFSET_MEMBER(s, m) (size_t)&(((s*)0)->m)
//vertex 3 float
//color   3 byte
//texture 2 float

struct VF3_CB3_TF2
{
	GLfloat m_vertex[3];
	GLubyte m_color[3];
	GLfloat m_texture[2];
};

typedef struct _VF3_CB3_TF2_Quad
{
	VF3_CB3_TF2 tl;//top left
	VF3_CB3_TF2 bl;//bottom left
	VF3_CB3_TF2 tr;//top right
	VF3_CB3_TF2 br;//bottom right
} VF3_CB3_TF2_Quad;

static GLuint g_program = 0;
static GLuint g_vertex_shader = 0;
static GLuint g_frag_shader = 0;
static GLuint g_texture = 0;

enum 
{
	eVertex = 0,
	eColor,
	eTexture,
};

static const char *attrib_vertex_name = "a_vertex";
static const char *attrib_color_name = "a_color";
static const char *attrib_texture_name = "a_texture";

static const GLchar *vertex_source =
	"uniform sampler2D texture0;\n"
 	"attribute vec4 a_vertex;\n"
 	"attribute vec3 a_color;\n"
 	"attribute vec2 a_texture;\n"
	"varying vec4 v_color;\n"
	"varying vec2 v_texture;\n"
	"\n"
	
	"void main(void) {\n"
	"gl_Position = gl_ModelViewProjectionMatrix * a_vertex; \n"
	"v_color = vec4(a_color.r/255.0f, a_color.g/255.0f,a_color.b/255.0f, 1.0f);\n" //沒有混合
	"v_texture = a_texture;\n"
	"}\n"
	"//END";

static const GLchar *frag_source =
	"uniform sampler2D texture0;\n"
	"varying vec4 v_color;\n"
	"varying vec2 v_texture;\n"
	"\n"
	"void main(void){\n"
	"\n"
	//v_color在這裡會增加顏色的混合效果,如果去掉
	//或者將其設定為v_color = vec4(1.0f, 1.0f, 1.0f, 1.0f)則
	//直接將紋理顯示到最後結果
	"\n"
	"gl_FragColor =  v_color * texture2D(texture0,v_texture) ;\n"
	"}\n"
	"//END";

//---------------------------------------------------------------------------------------------------------------------
void initShader();
void render();
void initQuadWithData(float top, float left, float width,float height, VF3_CB3_TF2_Quad& quad);
void readBitmp24(const std::string& filename, void* &ptr, int &width, int &height, int& totals);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void init()
{
	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
	glClearDepth(1.0f);
	glShadeModel(GL_SMOOTH);

	glGenTextures(1, &g_texture);
	assert(g_texture);
	
	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);	
	//default texture in multi-textrures
	glActiveTexture(GL_TEXTURE0); 
	glBindTexture(GL_TEXTURE_2D, g_texture);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, 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);

	void *bmpData = 0;
	int width=0, height=0, totals=0;
	readBitmp24("e:/test.bmp",bmpData, width, height, totals);
	assert(bmpData);

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,bmpData);

	delete[] bmpData;
	bmpData = 0;

	glBindTexture(GL_TEXTURE_2D, 0);
	glEnable(GL_TEXTURE_2D);
	assert(glGetError() == GL_NO_ERROR);
}

void readBitmp24(const std::string& filename, void* &ptr, int &width, int &height, int& totals)
{
	fstream in(filename.c_str(), ios_base::in|ios_base::binary);
	if (!in)
	{
		ptr = NULL;
		return;
	}

	in.seekg(0x12); //18個位元組開始讀取寬度和高度
	in.read((char*)&width, sizeof(int));
	in.read((char*)&height,sizeof(int));

	//BMP的每行按照4個位元組對齊
	int realWidth = width;
	int lineLength = width*3;
	while (lineLength % 4 != 0)
		++lineLength;

	totals = lineLength * height;
	ptr = new char[totals];

	in.seekg(0x36); //54開始是資料,按照行讀取
	in.read((char*)ptr, totals);

	//將BGR模式轉換為RGB模式
	char *startPos = NULL,*curPos = NULL;
	for (int i=0; i<height; ++i)
	{
		curPos = ((char*)ptr+i*lineLength);
		for (int j=0; j<realWidth;++j)
		{
			std::swap(curPos[0], curPos[2]);
			curPos += 3;
		}
	}

	in.close();
}

void initQuadWithData( float top, float left, float width,float height,VF3_CB3_TF2_Quad& quad)
{
	memset(&quad, 0, sizeof(VF3_CB3_TF2_Quad));

	//座標
	quad.tl.m_vertex[0] = left;
	quad.tl.m_vertex[1] = top;

	quad.bl.m_vertex[0] = left;
	quad.bl.m_vertex[1] = top-height;

	quad.tr.m_vertex[0] = left+width;
	quad.tr.m_vertex[1] = top;

	quad.br.m_vertex[0] = left+width;
	quad.br.m_vertex[1] = top-height;

	//顏色
	static const GLubyte red_color[3] = {255, 0, 0};
	static const GLubyte green_color[3] = {0, 255, 0};
	static const GLubyte blue_color[3] = {0,0,255};
	static const GLubyte white_color[3] = {255,255,255};

	memcpy(&quad.tl.m_color,blue_color, sizeof(GLubyte)*3);
//  	memcpy(&quad.bl.m_color,white_color, sizeof(GLubyte)*3);
//  	memcpy(&quad.tr.m_color,white_color, sizeof(GLubyte)*3);
	memcpy(&quad.br.m_color,red_color, sizeof(GLbyte)*3);
	//printf("initialize data...\n");

	//紋理
	static const GLfloat tl_texture[2] = {0,1};
	static const GLfloat bl_texture[2] = {0, 0};
	static const GLfloat tr_texture[2] = {1, 1};
	static const GLfloat br_texture[2] = {1,0};

	memcpy(&quad.tl.m_texture, tl_texture, sizeof(GLfloat)*2);
	memcpy(&quad.bl.m_texture, bl_texture, sizeof(GLfloat)*2);
	memcpy(&quad.tr.m_texture, tr_texture, sizeof(GLfloat)*2);
	memcpy(&quad.br.m_texture, br_texture, sizeof(GLfloat)*2);
}

void render()
{
//  	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);	
//  	//glColor3f(0,0,0.5f);
//  	glBegin(GL_TRIANGLE_STRIP);
//  //	glRectf(-.5, .5, .5, -.5);
// 	
// 	glColor3f(0,0,1.0f); //blue
// 	glVertex2f(-0.5, 0.5);
// 
// 	glColor3f(0,0,0);
// 	glVertex2f(-0.5, -0.5);
// 	
// 	glColor3f(0,0,0);
// 	glVertex2f(0.5f, 0.5f);
// 
// 	glColor3f(1.0f, 0, 0);
// 	glVertex2f(0.5f, -0.5f);
// 
//  	glEnd();
//  	glutSwapBuffers();

 	GLenum errorCode = glGetError();
// 	if (errorCode != GL_NO_ERROR)
// 	{
// 		printf("errorCode = %d\n", errorCode);
// 		assert(false);
// 	}
	assert(errorCode == GL_NO_ERROR);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, g_texture);

  	glEnableVertexAttribArray(eVertex);
  glEnableVertexAttribArray(eColor);
	glEnableVertexAttribArray(eTexture);

  	glUseProgram(g_program);
	
	//設定Uniform的值
	GLint loc = glGetUniformLocation(g_program,"texture0");
	assert(loc>=0);
	glUniform1i(loc, 0);

	GLint value = 0;
	glGetUniformiv(g_program, loc, &value);
	assert(!value);
	assert(glGetError() == GL_NO_ERROR);

	//初始化資料
  	VF3_CB3_TF2_Quad quad;
  	initQuadWithData(2.0f, -2.0f, 4.0f, 4.0f, quad);
  	
  	size_t offset = 0;
  	offset = OFFSET_MEMBER(VF3_CB3_TF2, m_vertex);
  	glVertexAttribPointer(eVertex, 3, GL_FLOAT, GL_FALSE, sizeof(VF3_CB3_TF2), (GLvoid*)((char*)&quad+offset));
  
   	offset = OFFSET_MEMBER(VF3_CB3_TF2, m_color);
   	glVertexAttribPointer(eColor, 3, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(VF3_CB3_TF2), (GLvoid*)((char*)&quad+offset));
  	
 	offset = OFFSET_MEMBER(VF3_CB3_TF2, m_texture);
 	glVertexAttribPointer(eTexture, 2, GL_FLOAT, GL_FALSE, sizeof(VF3_CB3_TF2), (GLvoid*)((char*)&quad+offset));

  	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  
  	glDisableVertexAttribArray(eVertex);
  	glDisableVertexAttribArray(eColor);
	glDisableVertexAttribArray(eTexture);

	glBindTexture(GL_TEXTURE_2D, 0);
	glDisable(GL_TEXTURE_2D);

  	glutSwapBuffers();
}

void reshape(int w, int h)
{
	glViewport(0, 0, w, h);

	double factor = (w*1.0)/h;
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	gluPerspective(60, factor, 1, 100);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	gluLookAt(0,0, 5, 0,0,0, 0,1,0);
}

void idle()
{

}

void initShader()
{
	const GLchar* vertexSource[] = {vertex_source};
	const GLchar* fragSource[] = {frag_source};

	g_program = glCreateProgram();
	GLenum err = glGetError();
	if (err)
	{
		printf("error code = %d\n",err);
	}
	g_vertex_shader = glCreateShader(GL_VERTEX_SHADER);
	g_frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
	assert(g_program || g_vertex_shader || g_frag_shader);
	glShaderSource(g_vertex_shader,1, vertexSource, 0);
	glShaderSource(g_frag_shader, 1, fragSource, 0);

	glCompileShader(g_vertex_shader);
	glCompileShader(g_frag_shader);

	GLint status = 0;
	glGetShaderiv(g_vertex_shader, GL_COMPILE_STATUS, &status);
	//assert(status);
	if (!status)
	{
		GLsizei length = 0, written=0;
		glGetShaderiv(g_vertex_shader, GL_INFO_LOG_LENGTH, &length);
		GLchar* src = (GLchar*)malloc(length+1);
		memset(src, 0, (length+1));
		glGetShaderInfoLog(g_vertex_shader, length, &written, src);
		printf("%s", src);
		free(src);
		return;
	}
	glGetShaderiv(g_frag_shader, GL_COMPILE_STATUS, &status);
	//assert(status);
	if (!status)
	{
		GLsizei length = 0, written=0;
		glGetShaderiv(g_vertex_shader, GL_INFO_LOG_LENGTH, &length);
		GLchar* src = (GLchar*)malloc(length+1);
		memset(src, 0, (length+1));
		glGetShaderInfoLog(g_vertex_shader, length, &written, src);
		printf("%s", src);
		free(src);
		return;
	}

	glAttachShader(g_program, g_vertex_shader);
	glAttachShader(g_program, g_frag_shader);

	glBindAttribLocation(g_program,eVertex,attrib_vertex_name);
	glBindAttribLocation(g_program,eColor, attrib_color_name);
	glBindAttribLocation(g_program,eTexture,attrib_texture_name);

	glLinkProgram(g_program);
	glGetProgramiv(g_program, GL_LINK_STATUS,&status);
	if(!status)
	{
		GLsizei bufSize = 0;
		glGetProgramiv(g_program,GL_INFO_LOG_LENGTH, &bufSize);
		GLchar* infoLog =(GLchar*) malloc(bufSize);
		glGetProgramInfoLog(g_program,bufSize, 0, infoLog);
		printf("link error:\n%s",infoLog);
		return;
	}
	assert(glGetError() == GL_NO_ERROR);
	
	//必須在呼叫glUseProgram之後再呼叫glUniformXXX介面
	//否則會包GL_INVALID_OPERATION錯誤
// 	glUseProgram(g_program);
// 	GLint loc = glGetUniformLocation(g_program,"texture0");
// 	assert(loc>=0);
// 	glUniform1i(loc, 0);
// 
// 	GLint value = 0;
// 	glGetUniformiv(g_program, loc, &value);
// 	assert(!value);
// 
// 	GLenum errorCode = glGetError();
// 	assert(glGetError() == GL_NO_ERROR);
// 	printf("program compile and link success~\n");
}

void timer(int value)
{
	if (value != g_timer_id)
		return;
	glutPostRedisplay();
	glutTimerFunc(g_time_per_frame, timer, g_timer_id);
}

int _tmain(int argc, _TCHAR* argv[])
{
	glutInit(&argc, argv);
	//在視窗建立之前,必須要首先初始化顯示模式
	glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
	glutCreateWindow("GLSL");
	glutInitWindowPosition(400, 200);
	glutInitWindowSize(600, 600);
	

	if(glewInit() != GLEW_NO_ERROR)
		return -1;

	init();
	initShader();

	glutDisplayFunc(render);
	glutReshapeFunc(reshape);
	glutIdleFunc(idle);
	
	//glutTimerFunc(g_time_per_frame,timer,g_timer_id);
	glutMainLoop();

	return 0;
}

下面這是沒有加入顏色只應用座標和紋理的效果將著色器的

"gl_FragColor =  v_color * texture2D(texture0,v_texture) ;\n"
這行程式碼的v_color去掉或者改為v_color = vec4(1.0f, 1.0f, 1.0f, 1.0f)即可,其效果如下


呵呵,效果還不錯吧,本人做OpenGL還是GLSL都是用的這個小mm測試!

相關推薦

GLSL入門2 關於GLSL紋理

我將註解以及原始碼直接放到這裡了 // GLSL01.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <iostream> #include <fstream> #include <G

GLSL教程】(八)紋理

簡單的紋理貼圖(Simple Texture)為了在GLSL中應用紋理,我們需要訪問每個頂點的紋理座標。GLSL中提供了一些屬性變數,每個紋理單元一個: attribute vec4 gl_MultiTexCoord0;

在OpenGL進行多紋理

    int Status=FALSE;        // 狀態指示器     AUX_RGBImageRec *TextureImage[6];      // 建立紋理的儲存空間     memset(TextureImage,0,sizeof(void *)*6);     // 將指標設為 NUL

2.x終於照著教程,成功使用OpenGL ES 繪製紋理,增加了灰度

在之前成功繪製變色的幾何圖形之後,今天利用Openg ES的可程式設計管線繪製出第一張紋理。學校時候不知道OpenGL的重要性,怕晦澀的語法,沒有跟老師學習OpenGL的環境配置,如今只能利用cocos2dx 2.2.3 配置好的環境學習OpenGL ES。原始碼來自《co

Opengl ES 1.x NDK實例開發之六:紋理

otto absolute decode super rep mit his viewport 一個 開發框架介紹請參見:Opengl ES NDK實例開發之中的一個:搭建開發框架 本章在第三章(Opengl ES 1.x NDK實例開發之三:多邊形的旋轉)的基礎

WebGL---6.3D紋理

一、例項程式碼 <html> <canvas id='c' width='640' height='480'></canvas> <script type="x-shader/x-vertex" id="vertex-shader">

MFC+OpenGL 紋理後再繪製線條兩個顏色相互影響

    OpenGL渲染方式比GDI+強太多了,所以做繪圖操作時我選擇了OpenGL(新手),但是我在紋理貼圖時出現了這樣一個問題,就是我在貼完圖後再繼續在繪製線條什麼的最後::SwapBuffers(hDC_); glFlush(); 也就是輸出到顯示器時紋理貼圖的顏色竟然

java程式設計入門2 java的四種訪問許可權控制

在java中提供了四種訪問許可權控制:預設訪問許可權(包訪問許可權),public,private以及protected 只有預設訪問許可權(包訪問許可權)和public能用來修飾類(不包括內部類) 修飾變數和方法這四種許可權均可 1.public 修飾類表示該類對其他所有類可見 修飾一個類的變數和

android平臺下OpenGL ES 3.0實現2D紋理顯示bitmap

OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E

OpenGL ES (3):平面圖形-表面紋理

1.簡介 上一篇已經將一個平面圖形繪製出來了,這一次我們將在上一次繪製出來的圖形的表面上進行紋理貼圖。 圖片準備:(寬高須為2的N次方) 最終圖片是以Bitmap形式。現在考慮如何把這張圖片對映到繪製的平面上? 所以這裡也需要一個數組float[] 用於設定紋理座

OpenGL ES (16): 紋理

1.前言 圖片如下:紋理座標為 左上角為(0,0),右下角為(1,1) 我們繪製一個正方形,頂點座標資料如下: 此次程式碼不包含z軸,預設為0。 要做的事就是把圖片貼到正方形的表面,並繪製出正方形。 所以上面的紋理座標和頂點座標的順序要一致。這樣繪製的圖片才

DirectX9.0 Texture紋理()示例程式

DirectX9.0 Texture紋理對映 將DirectX SDK 上的Texture略微修改,它是一個旋轉的空心圓柱體。我覺得用正方形能更好的理解紋理座標。其實在用遊戲引擎時,是不會關心紋理是如何具體對映的 1.紋理座標 DirectX中的紋理與OpenG

OpenGL方式

OpenGL為我們提供了三種紋理——GL_TEXTURE_1D、GL_TEXTURE_2D和GL_TEXTURE_3D。它們分別表示1維紋理、2維紋理和3維紋理。無論是哪一中紋理,使用方法都是相同的:即先建立一個紋理物件和一個儲存紋理資料的n維陣列,在呼叫glTexIma

圖形學取樣、走樣與反走樣等,圖形學走樣

計算機圖形學中不可避免的會涉及到影象分析與處理的相關知識,前些時間也重溫了下常用到的取樣、重建以及紋理貼圖等內容,並對其中的走樣與反走樣有了更多的認識,這裡小結一下。 1. 基本問題 訊號的取樣與重建過程中首先面臨著兩個基本的問題: 給定一個連續的

【一步步學OpenGL 16】 -《紋理

教程16 紋理貼圖基礎 背景 紋理貼圖意思是將任意型別的圖片貼在3d模型的一個或者多個面上。圖片可以是任意的但通常是一種通用的樣式,比如:磚塊、植物、荒蕪的土地等等,可以提高場景的真實性。比較下面兩幅圖片: 為了實現紋理貼圖我們需

使用glfw庫將OpenCV讀取到的圖片作為OpenGL的背景紋理

轉載請註明出處:http://my.csdn.NET/ye_shen_wei_mian 前段時間接觸過一點glfw,個人而言不太喜歡freeglut的回撥機制,glfw不失為一個可以替代的選擇。 使用glfw應當注意以下幾點: 1;glfw是可以使用在多執行緒當中使用的。

Cocos2dx-OpenGL ES2.0教程:紋理(6)

在上一篇文章中,我們介紹瞭如何繪製一個立方體,裡面涉及的知識點有VBO(Vertex Buffer Object)、IBO(Index Buffer Object)和MVP(Modile-View-Projection)變換。 本文將在教程4的基礎之上,新增紋理貼圖支

Android OpenGL ES正方體紋理(每個面一張)

正方體的紋理貼圖步驟如下: 1.陣列 1.1:頂點陣列 1.2:三角形 1.3:貼圖陣列 2.onSurfaceChanged:與3D的一樣 3.onSurfaceCreated:需要新增東西 3.1允許2D貼圖gl.glEnable(GL10.GL_TEXTURE_2D

管理項目-Texture overview插件

pack 人員 反編譯 mage sets list tps 技術 sset Texture overview插件管理項目中的貼圖 1. Assetstore地址 2. 總覽項目中所有貼圖 3. 針對不同平臺的貼圖壓縮設置 在插件的右上角 4. 支持多選批

OpenGL ES 紋理

頂點座標和紋理座標 在沒有投影矩陣的情況下,我們要傳給頂點著色器的座標值都在(-1,1)範圍內,超出了這個範圍將不可見。因此對於一個四邊形的繪製,我們經常看到下面的頂點座標: GLfloat vertices[] = { // P