GLSL入门2 关于GLSL中的纹理贴图

4 篇文章 2 订阅

我将注解以及源码直接放到这里了

// 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测试!



  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值