加载 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 - 只加载一个像素?的主要内容,如果未能解决你的问题,请参考以下文章

无法将 BMP 图像转换为矩形 OpenGL

OpenGL中不用AUX库来加载BMP图片作为纹理

BMP 纹理不显示

OpenGL:将图像加载到纹理数组中

使用 SDL 加载 OpenGL 纹理

使用OpenGL显示图像?