opengl es 2.0上的纹理vbos

时间:2014-08-07 16:02:51

标签: c++ opengl-es texture-mapping

我试图在Opengl ES 2.0中使用VBO进行渲染。

我设置了vbo,它显示自己非常正确(屏幕顶部的一个三角形),我使用片段着色器显示加载的纹理,它也是正确的。

但是,TextureCoordinates都是0.0f,因此渲染全部错误(仅1种颜色)。

有我的代码:

#include "glee.h"
#include <windows.h>
#include <time.h>

#include <math.h>

HDC hDC;

const GLchar* vertexSource=
                                                        "#version 100\n"
                                                        "\n"
                                                        "attribute vec3 a_position;     \n"
                                                        "attribute vec2 a_texCoord; \n"

                                                        "varying vec2 v_textcoord; \n"
                                                        "uniform sampler2D s_texture;   \n"
                                                        "\n"
                                                        "void main()\n"
                                                        "{\n"
                                                        "    gl_Position = vec4(a_position, 1.0);\n"
                                                        "    v_textcoord = a_texCoord;\n"
                                                        "}\n";

const GLchar*  fragmentSource=
                                                        "#ifdef GL_ES                                   \n"
                                                        "precision mediump float;           \n"
                                                        "#else                                              \n"
                                                        "#version   100                                 \n"
                                                        "precision mediump float;           \n"
                                                        "#endif                                             \n"
                                                        "varying vec2 v_textcoord; \n"
                                                        "uniform sampler2D s_texture;   \n"


                                                        "void main() {\n"
                                                    " gl_FragColor= texture2D( s_texture, v_textcoord ); \n"
                                                        "       }\n";


#include <stdlib.h> 
float noise(float p)
{
    return (float)(rand()%(int)(p+1));
}

float fbm(float p)
{
    float f =0.5000*noise(p); p*=2.01;
                f+=0.2500*noise(p); p*=2.03;
                f+=0.2500*noise(p); p*=2.01;
                f+=0.1250*noise(p); p*=2.02;
                f+=0.0625*noise(p); p*=2.02;
                f/=0.9375;
                return f;
}


extern "C" __declspec(noreturn) void WinMainCRTStartup()
{
    HWND    hWnd;

    hWnd = CreateWindow("EDIT","EDIT",WS_POPUP|WS_VISIBLE, 0,0, 600, 400,0,0,0,0);
    hDC = GetDC(hWnd);

    // Pixel Format
PIXELFORMATDESCRIPTOR pfd = {
            sizeof(PIXELFORMATDESCRIPTOR),
            1,
            PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
            PFD_TYPE_RGBA,
            32,             // Colour buffer bit depth
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            32,             // Depth buffer bit depth
            0, 0,
            PFD_MAIN_PLANE, 
            0, 0, 0, 0 };

    SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd);
    wglMakeCurrent(hDC,wglCreateContext(hDC));

                                        glMatrixMode(GL_PROJECTION);
                                        glLoadIdentity();

                                        glMatrixMode(GL_MODELVIEW);                                                                                 

                                        glClearColor(0.0f,0.0f,0.0f,1.0f);

                                        // Enable z-buffer
                                        glEnable(GL_DEPTH_TEST);
                                        glDepthMask(GL_TRUE);
                                        glEnable(GL_CULL_FACE);

                                        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
                                        glAlphaFunc(GL_GREATER,0.1f);

                                        glEnable(GL_BLEND);
                                        glEnable(GL_ALPHA_TEST);

                                        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                                        glLoadIdentity(); 

                                        glDepthFunc(GL_LESS);               // The Type Of Depth Test To Do
                                        glShadeModel(GL_SMOOTH);            // Enables Smooth Color Shading

    SetForegroundWindow(hWnd);
    SetFocus(hWnd);

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexSource, NULL);
    glCompileShader(vertexShader);
    GLint status;
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
    char buffer[512];
    glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
    OutputDebugStringA(buffer);

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
    glCompileShader(fragmentShader);

    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
    glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
    OutputDebugStringA(buffer);
    glGetShaderInfoLog(vertexShader, 512, NULL, buffer);

    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);

    glLinkProgram(shaderProgram);

    glUseProgram(shaderProgram);

    GLuint handle;

    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &handle);
    glBindTexture(GL_TEXTURE_2D, handle); 

    GLboolean isTex=glIsTexture(handle);

    char * tbuffer=new char[4*512*512];

    for (int y=0;y<512;y++)
    for (int x=0;x<512;x++)
    {
        float f=rand()%255; 
        int off=(y*512)+x;
        off*=4;

        tbuffer[off+0]=f;
        tbuffer[off+1]=f;
        tbuffer[off+2]=f;
        tbuffer[off+3]=255;
    }

    glTexImage2D(GL_TEXTURE_2D,  0, GL_RGBA
                                                                , 512
                                                                , 512
                                                                , 0
                                                                , GL_RGBA
                                                                , GL_UNSIGNED_BYTE
                                                                , tbuffer);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S        ,   GL_CLAMP_TO_EDGE);  // Warning: Android OpenGL GLES MUST and can ONLY receive this param
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T        ,   GL_CLAMP_TO_EDGE); 


    glUseProgram(shaderProgram);

int n=0;
    glBindAttribLocation(shaderProgram, n++, "a_position");
    glBindAttribLocation(shaderProgram, n++, "a_texCoord");
    glUniform1i(glGetUniformLocation(shaderProgram, "s_texture"), 0);
    GLuint texCoordLoc=glGetUniformLocation(shaderProgram, "a_texCoord");


    GLuint VertexVBOID;
    GLuint IndexVBOID;

struct MyVertex
  {
    float x, y, z;        //Vertex
    float nx, ny, nz;     //Normal
    float s0, t0;         //Texcoord0
  };

  MyVertex pvertex[3];
  //VERTEX 0
  pvertex[0].x = -1.0;
  pvertex[0].y = 0.0;
  pvertex[0].z = 0.0;
  pvertex[0].nx = 0.0;
  pvertex[0].ny = 0.0;
  pvertex[0].nz = 1.0;
  pvertex[0].s0 = 0.0;
  pvertex[0].t0 = 1.0;
  //VERTEX 1
  pvertex[1].x = 1.0;
  pvertex[1].y = 0.0;
  pvertex[1].z = 0.0;
  pvertex[1].nx = 0.0;
  pvertex[1].ny = 0.0;
  pvertex[1].nz = 1.0;
  pvertex[1].s0 = 1.0;
  pvertex[1].t0 = 0.0;
  //VERTEX 2
  pvertex[2].x = 0.0;
  pvertex[2].y = 1.0;
  pvertex[2].z = 0.0;
  pvertex[2].nx = 0.0;
  pvertex[2].ny = 0.0;
  pvertex[2].nz = 1.0;
  pvertex[2].s0 = 1.0;
  pvertex[2].t0 = 1.0;


  glGenBuffers(1, &VertexVBOID);
  glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
  glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*3, &pvertex, GL_STATIC_DRAW);

  unsigned short pindices[6];
  pindices[0] = 0;
  pindices[1] = 1;
  pindices[2] = 2;
  pindices[3] = 0;
  pindices[4] = 3;
  pindices[5] = 1;

  glGenBuffers(1, &IndexVBOID);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*3, pindices, GL_STATIC_DRAW);

  #define BUFFER_OFFSET(i) ((void*)(i))

  glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);

  glEnableClientState(GL_VERTEX_ARRAY);
  glVertexPointer(3, GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(0));   //The starting point of the VBO, for the vertices

  glClientActiveTexture(GL_TEXTURE0);

    glEnableVertexAttribArray(texCoordLoc);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glTexCoordPointer(2, GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(24));   //The starting point of texcoords, 24 bytes away
    GLenum err (glGetError());

    while(!GetAsyncKeyState(VK_ESCAPE) && !GetAsyncKeyState(VK_SPACE) )
    {   
        glClearColor(0.1f,0.2f,0.3f,0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);

         glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO

            SwapBuffers(hDC);
            MSG msg;

        while (PeekMessage(&msg,0,0,0,PM_REMOVE)==0);
    }

    ExitProcess (0);
}

我该怎么办?我理解使用vbo,纹理坐标已经发送到着色器。有什么问题?

1 个答案:

答案 0 :(得分:1)

你在这里得到了相当疯狂的组合。您说您使用的是ES 2.0,但是您使用了许多不属于ES 2.0的API条目。然后,您会以不兼容的方式部分混合传统和当前功能。我会尝试指出主要问题,但我可能不会详细介绍所有内容。

  1. PIXELFORMATDESCRIPTOR有两个看似不寻常的值。它为cColorBits指定了32。这只是RGB组件的大小,因此每个组件8位应为24。它还为深度缓冲区指定32位,这是许多硬件不支持的值。 24是更常用的尺寸。
  2. ES +中不存在
  3. glMatrixMode()glLoadIdentity()
  4. ES +中不存在
  5. glAlphaFunc()GL_ALPHA_TEST
  6. ES +中不存在
  7. glShadeModel()
  8. 代码检查在编译片段着色器后第二次编译顶点着色器是否成功,而不是检查片段着色器。
  9. glBindAttribLocation()之后调用
  10. glLinkProgram()。这没有效果。您必须先致电glBindAttribLocation() glLinkProgram(),或glGetAttribLocation() glLinkProgram()
  11. glGetUniformLocation()号召唤a_texCoord,这是一个属性,而不是制服。这应该是glGetAttribLocation()
  12. ES +中不存在
  13. glEnableClientState()glVertexPointer()glTexCoordPointer()。它们也与着色器代码中使用的通用顶点属性不兼容。需要使用glEnableVertexAttribArray()glVertexAttribPointer()
  14. 最大的问题很可能是这个列表中的第7项和第8项,这肯定会阻止纹理坐标与任何版本的OpenGL一起使用。