#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位的了。
这样图片就都出来了。