加载 bmp 图像 OPENGL 3.x - 只加载一个像素?
Posted
技术标签:
【中文标题】加载 bmp 图像 OPENGL 3.x - 只加载一个像素?【英文标题】:loading bmp images OPENGL 3.x - only loading one pixel? 【发布时间】:2014-03-29 01:31:17 【问题描述】:所以我在加载纹理图像时遇到了一些麻烦。我不确定我做错了什么。它似乎只读取最后一个像素,我不知道为什么? 任何帮助表示赞赏。这是我的代码:
#include "Angel.h"
#include <glew.h>
#include <glut.h>
#include <typeinfo>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
using namespace std;
vec4 gridLines[] =
vec4(-0.5, -0.5, 0.0, 1.0), //v1
vec4(0.5, -0.5, 0.0, 1.0), //v2
vec4(-0.5, 0.5, 0.0, 1.0), //v3
vec4(0.5, 0.5, 0.0, 1.0), //v4
;
GLuint vertexID[3];
GLuint bufferID2;
GLuint ProjectionLocation, ModelViewLocation;
mat4 instance;
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
float
roundTo(float value, int digits)//Ensures rounding is done correct
//check to see if the value is very close to zero
if ((int)(value*10.0) == 0)
return 0.0;
double factor = pow(10.0, digits - ceil(log10(fabs(value))));
return round(value * factor) / factor;
void
init(void) //Initialize Buffers for all objects
//1. Load shaders and use the resulting shader program
GLuint program = InitShader("vshader81.glsl", "fshader81.glsl");
glUseProgram(program);
GLuint vPosition = glGetAttribLocation(program, "vPosition");
GLuint vColor = glGetAttribLocation(program, "vColor");
glGenVertexArrays(1, &vertexID[1]);
vec4 colors2[] =
vec4(1.0, 1.0, 1.0, 1.0), //1
vec4(1.0, 1.0, 1.0, 1.0), //2
vec4(1.0, 1.0, 1.0, 1.0), //3
vec4(1.0, 1.0, 1.0, 1.0), //4
;
// Create and initialize a buffer object
glBindVertexArray(vertexID[1]);
glGenBuffers(1, &bufferID2);
glBindBuffer(GL_ARRAY_BUFFER, bufferID2);
glBufferData(GL_ARRAY_BUFFER, sizeof(gridLines)+sizeof(colors2), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(gridLines), gridLines);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(gridLines), sizeof(colors2), colors2);
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
GLuint textureid;
// Texture coordinates
vec4 tex_coords[] =
vec4(-0.5, -0.5, 0.0, 1.0), //v1
vec4(0.5, -0.5, 0.0, 1.0), //v2
vec4(-0.5, 0.5, 0.0, 1.0), //v3
vec4(0.5, 0.5, 0.0, 1.0), //v4
;
glGenTextures(1, &textureid);
glBindTexture(GL_TEXTURE_2D, textureid);
/***********************************************/
const char * imagepath = "checkboard2.bmp";
// Data read from the header of the BMP file
unsigned char header[54]; // Each BMP file begins by a 54-bytes header
unsigned int dataPos; // Position in the file where the actual data begins
unsigned int width, height;
unsigned int imageSize; // = width*height*3
// Actual RGB data
unsigned char * data;
// Open the file
FILE * file = fopen(imagepath, "rb");
if (!file) printf("Image could not be opened\n");
if (fread(header, 1, 54, file) != 54) // If not 54 bytes read : problem
printf("Not a correct BMP file\n");
if (header[0] != 'B' || header[1] != 'M')
printf("Not a correct BMP file\n");
cout << "great.." << endl;
// Read ints from the byte array
dataPos = *(int*)&(header[0x0A]);
imageSize = *(int*)&(header[0x22]);
cout << "Image Size: " << imageSize << endl;
width = *(int*)&(header[0x12]);
cout << "width: " << width << endl;
height = *(int*)&(header[0x16]);
// Some BMP files are misformatted, guess missing information
if (imageSize == 0) imageSize = width*height * 3; // 3 : one byte for each Red, Green and Blue component
if (dataPos == 0) dataPos = 54; // The BMP header is done that way
// Create a buffer
data = new unsigned char[imageSize];
// Read the actual data from the file into the buffer
fread(data, 1, imageSize, file);
//Everything is in memory now, the file can be closed
fclose(file);
//GLuint Texture = loadBMP_custom("brick_converted.bmp");
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//glActiveTexture(GL_TEXTURE0);
GLuint vTexCoord = glGetAttribLocation(program, "vTexCoord");
glEnableVertexAttribArray(vTexCoord);
glVertexAttribPointer(vTexCoord, 2, GL_FLOAT, GL_FALSE, 0,
BUFFER_OFFSET(sizeof(gridLines)));
glUniform1i(glGetUniformLocation(program, "texture"), 0);
//4. Bind all Buffers
glBindVertexArray(0);
//5.Set Background Color
glClearColor(0.5, 0.5, 0.5, 0.0); // background
//----------------------------------------------------------------------------
// Draw on Screen
//----------------------------------------------------------------------------
void
paintOnScreen()
glBindVertexArray(vertexID[1]);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
void
display(void) //Display to screen
//1.Clear the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_CULL_FACE);
//2.Translations/Rotations/Projections etc..
glViewport(0, 0, 300, 300);
//3.Draw Objects
paintOnScreen();
glBindVertexArray(0);
//3.Force OpenGL to render
glFlush();
void
reshape(int width, int height)
glViewport(0, 0, width, height);
//aspect = GLfloat(width)/height;
void
keyboard(unsigned char key, int x, int y)
switch (key)
case 033: //ESC
exit(EXIT_SUCCESS);
break;
//----------------------------------------------------------------------------
int
main(int argc, char **argv)
// Initialize glut library
glutInit(&argc, argv);
// Create the window
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowSize(300, 300);
glutInitWindowPosition(300, 200);
glutCreateWindow("Test");
// Initialize glew library
glewInit();
// Your own initialization
init();
// Set callback functions
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
// Start the main loop
glutMainLoop();
return 0;
还有我的片段着色器:
#version 150
in vec2 texCoord;
out vec4 fColor;
uniform sampler2D texture;
void main()
fColor = texture2D( texture, texCoord );
还有我的顶点着色器:
#version 150
in vec4 vPosition;
in vec2 vTexCoord;
out vec2 texCoord;
void main()
texCoord = vTexCoord;
gl_Position = vPosition;
【问题讨论】:
【参考方案1】:您没有正确指定纹理坐标。您定义了一个 tex_coords
数组,但此数据永远不会复制到 VBO(或根本不会在代码中引用)。您设置了vTexCoord
属性指针以指向VBO 中您复制colors2
数据数组的位置,这都是1.0,因此您不断访问最后一个纹素。
【讨论】:
谢谢你!完全错过了!以上是关于加载 bmp 图像 OPENGL 3.x - 只加载一个像素?的主要内容,如果未能解决你的问题,请参考以下文章