Opengl Array Texture,适用于原始数据,但不适用于图像数据
Posted
技术标签:
【中文标题】Opengl Array Texture,适用于原始数据,但不适用于图像数据【英文标题】:Opengl Array Texture, works with raw data but not with image data 【发布时间】:2014-12-01 05:03:57 【问题描述】:我可以加载单个纹理 我可以创建一个纹理数组传递纹素数据(如这里的示例) https://www.opengl.org/wiki/Array_Texture
但是当我将图像数据传递给 glTexSubImage3D 时,我什么都看不到。
源代码: https://github.com/omenking/17array_texture
#include <iostream>
using namespace std;
#include <cstdlib>
#include <stdio.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
GLFWwindow* window;
#define WINDOW_HEIGHT 768
#define WINDOW_WIDTH 1024
#include "common/shaders.h"
#include "common/texture.h"
#include "common/controls.h"
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
static void error_callback(int error, const char* description);
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
int main(void)
if (!glfwInit())
fprintf( stderr, "Failed to initialize GLFW\n" );
exit(EXIT_FAILURE);
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE , GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Ortho", NULL, NULL);
if (!window)
fprintf(stderr, "Failed to create window\n");
glfwTerminate();
exit(EXIT_FAILURE);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glfwSetErrorCallback(error_callback);
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
glfwSetCursorPos(window, WINDOW_WIDTH/2, WINDOW_HEIGHT/2);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
fprintf(stderr, "Failed to initialize GLEW\n");
glfwTerminate();
exit(EXIT_FAILURE);
if (GL_EXT_texture_array)
fprintf(stderr, "GL_EXT_texture_array\n");
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
GLuint vai; // vertex array id
glGenVertexArrays(2, &vai);
glBindVertexArray(vai);
char vert[] = "shaders/triangles.vert";
char frag[] = "shaders/triangles.frag";
GLuint program = load_shaders(vert,frag);
GLuint matrix_id = glGetUniformLocation(program, "MVP");
GLuint texture_id = glGetUniformLocation(program, "material");
GLsizei width = 16;
GLsizei height = 16;
GLsizei layerCount = 2;
GLsizei mipLevelCount = 1;
unsigned char* data = bmp_data("uvtemplate.bmp");
//unsigned char* data = bmp_data("tiles.bmp");
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D_ARRAY, texture_id);
//GLubyte texels[32] =
//
////Texels for first image.
//0, 0, 0, 255,
//255, 0, 0, 255,
//0, 255, 0, 255,
//0, 0, 255, 255,
////Texels for second image.
//255, 255, 255, 255,
//255, 255, 0, 255,
//0, 255, 255, 255,
//255, 0, 255, 255,
//;
//glTexStorage3D(GL_TEXTURE_2D_ARRAY, mipLevelCount, GL_RGBA8, width, height, layerCount);
//glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, layerCount, GL_RGBA, GL_UNSIGNED_BYTE, texels);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_BGR, width, height, layerCount);
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, layerCount, GL_BGR, GL_UNSIGNED_BYTE, data);
//glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
delete [] data;
GLuint vbo;
GLuint uvbo;
glGenBuffers(1, &vbo);
glGenBuffers(1, &uvbo);
// prep tile
GLfloat vertex[] =
-1, 1,0,
1, 1,0,
1,-1,0,
-1, 1,0,
-1,-1,0,
1,-1,0,
;
GLfloat uv[] =
//-1, 1,0,
//1, 1,0,
//1,-1,0,
//-1, 1,0,
//-1,-1,0,
//1,-1,0,
0.000059f, 1.0f-0.000004f,
0.000103f, 1.0f-0.336048f,
0.335973f, 1.0f-0.335903f,
0.000059f, 1.0f-0.000004f,
0.000103f, 1.0f-0.336048f,
0.335973f, 1.0f-0.335903f,
;
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, uvbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(uv), uv, GL_STATIC_DRAW);
glUseProgram(program);
while (!glfwWindowShouldClose(window))
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
computeMatricesFromInputs();
glm::mat4 ProjectionMatrix = getProjectionMatrix();
glm::mat4 ViewMatrix = getViewMatrix();
glm::mat4 ModelMatrix = glm::mat4(1.0);
glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;
glUniformMatrix4fv(matrix_id, 1, GL_FALSE, &MVP[0][0]);
glUniform1i(texture_id, 0);
// render tile
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glBindBuffer(GL_ARRAY_BUFFER, uvbo);
glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,0,(void*)0);
glDrawArrays(GL_TRIANGLES, 0, 2*3);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glfwSwapBuffers(window);
glfwPollEvents();
glfwDestroyWindow(window);
glDeleteProgram(program);
glDeleteVertexArrays(2, &vai);
glfwTerminate();
exit(EXIT_SUCCESS);
static void error_callback(int error, const char* description)
fputs(description, stderr);
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, 1);
【问题讨论】:
【参考方案1】:你传递给glTexStorage3D()
的格式有问题:
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_BGR, width, height, layerCount);
GL_BGR
不是glTexStorage3D()
的有效格式。仅支持大小格式。有关有效格式的列表,请参阅man page。在您的情况下,GL_RGB8
可能是您想要的格式:
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGB8, width, height, layerCount);
如果这是输入数据的字节顺序,您仍然可以在 glTexSubImage3D()
调用中使用 GL_BGR
作为格式参数。
一些可能会或可能不会导致您当前代码出现问题的小注释:
这会导致写入超出数组的边界,因为数组的大小为 1,但您请求两个顶点数组名称:
GLuint vai; // vertex array id
glGenVertexArrays(2, &vai);
您需要创建一个包含两个 id 的数组,或者将第一个参数更改为 1。
您可能需要当前已注释掉的glTexParameteri()
调用,至少是GL_TEXTURE_MIN_FILTER
的调用。
【讨论】:
通过将格式更改为 GL_RGB8,我能够看到渲染的纹理。 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGB8, width, height, layerCount); glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 宽度, 高度, layerCount, GL_BGR, GL_UNSIGNED_BYTE, 数据);以上是关于Opengl Array Texture,适用于原始数据,但不适用于图像数据的主要内容,如果未能解决你的问题,请参考以下文章
openGL之API学习(二零零)GL_TEXTURE_GEN_S GL_TEXTURE_GEN_T GL_TEXTURE_GEN_R GL_TEXTURE_GEN_Q