用opengel绘制多张纹理对应到不同位置的顶点

#define _CRT_SECURE_NO_WARNINGS
#include <glad/glad.h>
#include <glfw3.h>
#include <shader.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <string>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;

const char* str[13] = {
	"Poker/1.png","Poker/2.png","Poker/3.png",
	"Poker/4.png","Poker/5.png","Poker/6.png",
	"Poker/7.png","Poker/8.png","Poker/9.png",
	"Poker/10.png","Poker/11.png","Poker/12.png","Poker/13.png"
};

int SCR_WIDTH = 1366, SCR_HEIGHT = 768;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
const int MAX_T = 3;
int main(int argc, char *argv[]) {
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
	if (window == NULL)
	{
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
	{
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}
	Shader ourShader("4.1.texture.vs", "4.1.texture.fs");
	float vertices[] = {
		// positions          // colors           // texture coords
		 -0.6f,  -0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
		 -0.6f, -1.0f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
		-0.8f, -1.0f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
		-0.8f,  -0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f,  // top left 
	};
	glm::vec3 cubePositions[] = {
	  glm::vec3(0.0f,  0.0f,  0.0f),
	  glm::vec3(2.0f,  5.0f, -15.0f),
	  glm::vec3(-1.5f, -2.2f, -2.5f),
	  glm::vec3(-3.8f, -2.0f, -12.3f),
	  glm::vec3(2.4f, -0.4f, -3.5f),
	  glm::vec3(-1.7f,  3.0f, -7.5f),
	  glm::vec3(1.3f, -2.0f, -2.5f),
	  glm::vec3(1.5f,  2.0f, -2.5f),
	  glm::vec3(1.5f,  0.2f, -1.5f),
	  glm::vec3(-1.3f,  1.0f, -1.5f)
	};
	unsigned int VBO, VAO, EBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	//glGenBuffers(1, &EBO);

	glBindVertexArray(VAO);

	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
	// position attribute
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	// color attribute
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(1);
	// texture coord attribute
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
	glEnableVertexAttribArray(2);

	unsigned int texture[MAX_T];//用来存储10个不同的纹理ID
	int width, height, nrChannels;
	unsigned char *data;

	stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
	
	for (size_t i = 0; i < MAX_T; i++)
	{
		glGenTextures(1, &texture[i]);//生成纹理
		glBindTexture(GL_TEXTURE_2D, texture[i]);//绑定到texture[i]这个纹理id上
		// set the texture wrapping parameters
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	// set texture wrapping to GL_REPEAT (default wrapping method)
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		// set texture filtering parameters
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		data = stbi_load(str[i], &width, &height, &nrChannels, 0);

		if (data) {
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
			glGenerateMipmap(GL_TEXTURE_2D);
			std::cout << "texture" << i << endl;
		}
		else
		{
			std::cout << "error Texture:001" << endl;
		}
		width = 0, height = 0, nrChannels = 0;
		stbi_image_free(data);
	}
	while (!glfwWindowShouldClose(window))
	{
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		ourShader.use();
		glBindVertexArray(VAO);
		glm::mat4 model = glm::mat4(1.0f);
		for (int i = 0; i < MAX_T; i++) {
			glBindTexture(GL_TEXTURE_2D, texture[i]);
			model = glm::translate(model, glm::vec3(0.1f, 0.0f, 0.0f));
			ourShader.setMat4("model", model);
			glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
		}
		glfwSwapBuffers(window);
		glfwPollEvents();
	}
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
	glDeleteBuffers(1, &EBO);
	glDeleteTextures(10, texture);
	glfwTerminate();
	return 0;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
	glViewport(0, 0, width, height);
}

很奇怪的是这样最多能显示3个不同的纹理,超过第三个就会出现异常:0x0551F983 (ig9icd32.dll)处(位于 Poker.exe 中)引发的异常: 0xC0000005: 读取位置 0x0F565000 时发生访问冲突。或者是前两个纹理显示正常,后面的纹理显示不正常。有兴趣的可以试一下,看看为什么会这样,我实在是找不出答案了,网上的各种解决方法都试过了,还是不行-.-!

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;
uniform mat4 model;
void main()
{
	gl_Position = model*vec4(aPos, 1.0);
	ourColor = aColor;
	TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

这是我的顶点着色器,你可以把上面的代码拷贝到记事本中以.vs后缀存储,并放到你的项目里。 

#version 330 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

// texture sampler
uniform sampler2D texture1;

void main()
{
	FragColor = texture(texture1, TexCoord);
}

这个是片段着色器,同样的方式把他以.fs文件形式放到项目里。

其他的项目所需文件,不知道的可以参考这个网站https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/ 

 这是我最后的结果,至于三为什么那样我也不清楚。本来想用OpenGL做一个斗地主,却卡到这了。或许你能显示很多张图片,谁能知道为什么请回复我。

图像是我从这张图片扣下来的。 

这两天看代码终于找到问题了,图片位深度不一样,头两张是32位的,后面的图片是24位的,一直以为是内存,或者是指针没有释放。都怪图片查看器,图片打开旋转,结果把图片位深度变了,本来都是24位的结果变成32位的了。

 这样图片就都出来了。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值