📄 render.cpp
字号:
#include <stdio.h>
#include "render.h" //We need the defines and prototypes of there
EGLDisplay glesDisplay; // EGL display
EGLSurface glesSurface; // EGL rendering surface
EGLContext glesContext; // EGL rendering context
//Texture handles
GLuint texture1 = 0;
GLuint texture2 = 0;
//Variables declared in main.cpp, but used here too
extern HWND hWnd; // A handle to the window we will create
extern HDC hDC; // A handle to the device context of the window. Needed to
bool InitOGLES()
{
EGLConfig configs[10];
EGLint matchingConfigs;
/*configAttribs is a integers list that holds the desired format of
our framebuffer. We will ask for a framebuffer with 24 bits of
color and 16 bits of z-buffer. We also ask for a window buffer, not
a pbuffer or pixmap buffer*/
const EGLint configAttribs[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, EGL_DONT_CARE,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, EGL_DONT_CARE,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE, EGL_NONE
};
hDC = GetWindowDC(hWnd);
glesDisplay = eglGetDisplay(hDC); //Ask for an available display
//Display initialization (we don't care about the OGLES version numbers)
if(!eglInitialize(glesDisplay, NULL, NULL))
return false;
/*Ask for the framebuffer confiburation that best fits our
parameters. At most, we want 10 configurations*/
if(!eglChooseConfig(glesDisplay, configAttribs, &configs[0], 10, &matchingConfigs))
return false;
//If there isn't any configuration enough good
if (matchingConfigs < 1) return false;
/*eglCreateWindowSurface creates an onscreen EGLSurface and returns
a handle to it. Any EGL rendering context created with a
compatible EGLConfig can be used to render into this surface.*/
glesSurface = eglCreateWindowSurface(glesDisplay, configs[0], hWnd, configAttribs);
if(!glesSurface) return false;
// Let's create our rendering context
glesContext=eglCreateContext(glesDisplay,configs[0],0,configAttribs);
if(!glesContext) return false;
//Now we will activate the context for rendering
eglMakeCurrent(glesDisplay, glesSurface, glesSurface, glesContext);
/*Remember: because we are programming for a mobile device, we cant
use any of the OpenGL ES functions that finish in 'f', we must use
the fixed point version (they finish in 'x'*/
glClearColorx(FixedFromFloat(0.5f), FixedFromFloat(0.5f), FixedFromFloat(0.5f), ONE);
//Do not want to see smoothed colors, only a plain color for face
glShadeModel(GL_FLAT);
//Enable the depth test in order to see the cube correctly
glEnable(GL_DEPTH_TEST);
/*Taking care of specifying correctly the winding order of the
vertices (counter clock wise order), we can cull all back faces.
This is probably one of the best optimizations we could do,
because, by this way, we avoid a lot of computations that wont be
reflected in the screen. Use glEnable(GL_CULL_FACE) to do the work*/
glEnable(GL_CULL_FACE);
/*In order to set a viewport that fits entirely our window, we need
to know the window dimensions. They could be obtained through the
WinCE call GetWindowRect, using our window handle*/
RECT r;
GetWindowRect(hWnd, &r);
glViewport(r.left, r.top, r.right - r.left, r.bottom - r.top);
SetPerspective();
bool result = LoadTexture("./resources/door128.tga",&texture1);
result &= LoadTexture("./resources/fire128.tga",&texture2);
return result;
}
//----------------------------------------------------------------------------
void Render()
{
static int rotation = 0;
// We are going to draw a cube centered at origin, and with an edge of 10 units
/*
7 6
+--------------------+
/ | /|
/ | / |
3 / | 2 / |
+---------------------+ |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| |4 | |5
| +-------------|------+
| / | /
| / | /
| / | /
+---------------------+
0 1
*/
static GLubyte front[] = {2,1,3,0}; //front face
static GLubyte back[] = {5,6,4,7}; //back face
static GLubyte top[] = {6,2,7,3}; //top face
static GLubyte bottom[] = {1,5,0,4}; //bottom face
static GLubyte left[] = {3,0,7,4}; //left face
static GLubyte right[] = {6,5,2,1}; //right face
static GLshort vertices[] = {-5,-5,-5, 5,-5,-5, 5,5,-5, -5,5,-5,
-5,-5,5, 5,-5,5, 5,5,5, -5,5,5};
static GLfixed texCoords[] = {0,0, ONE,0, ONE,ONE, 0,ONE,
ONE,ONE ,0,ONE, 0,0, ONE,0};
/*GLfixed TWO = FixedFromInt(2);
static GLfixed texCoords[] = {0,0, TWO,0, TWO,TWO, 0,TWO,
TWO,TWO ,0,TWO, 0,0, TWO,0};*/
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatex(0, 0, FixedFromInt(-20));
glRotatex(FixedFromInt(45), ONE, 0, 0);
glRotatex(FixedFromInt(rotation++), 0, ONE,0);
//Enable the vertices array
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_SHORT, 0, vertices);
//3 = XYZ coordinates, GL_SHORT = data type, 0 = 0 stride bytes
glActiveTexture(GL_TEXTURE0);
glClientActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FIXED, 0, texCoords);
glActiveTexture(GL_TEXTURE1);
glClientActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture2);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FIXED, 0, texCoords);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
static float offset = 0.0f;
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatex(FixedFromFloat(offset+=0.01f),0,0);
glMatrixMode(GL_MODELVIEW);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, front);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, back);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, top);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, bottom);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, left);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, right);
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glActiveTexture(GL_TEXTURE0);
glClientActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
eglSwapBuffers(glesDisplay, glesSurface);
}
//----------------------------------------------------------------------------
void Perspective (GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar)
{
GLfixed xmin, xmax, ymin, ymax, aspectFixed, znearFixed;
aspectFixed = FixedFromFloat(aspect);
znearFixed = FixedFromFloat(zNear);
ymax = MultiplyFixed(znearFixed, FixedFromFloat((GLfloat)tan(fovy * 3.1415962f / 360.0f)));
ymin = -ymax;
xmin = MultiplyFixed(ymin, aspectFixed);
xmax = MultiplyFixed(ymax, aspectFixed);
glFrustumx(xmin, xmax, ymin, ymax, znearFixed, FixedFromFloat(zFar));
}
//----------------------------------------------------------------------------
void SetPerspective()
{
RECT r;
GetWindowRect(hWnd, &r);
float ratio = (float)(r.right - r.left)/(r.bottom - r.top);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
Perspective(45.0f,ratio, 1.0f, 40.0f);
glMatrixMode(GL_MODELVIEW);
}
//----------------------------------------------------------------------------
void Clean()
{
if(glesDisplay)
{
eglMakeCurrent(glesDisplay, NULL, NULL, NULL);
if(glesContext) eglDestroyContext(glesDisplay, glesContext);
if(glesSurface) eglDestroySurface(glesDisplay, glesSurface);
eglTerminate(glesDisplay);
}
}
//----------------------------------------------------------------------------
bool LoadTexture(const char *fileName, GLuint *id)
{
FILE *f = fopen(fileName, "rb");
GLubyte *pixels = NULL;
if(!f) return false;
WORD width = 0, height = 0;
byte headerLength = 0;
byte imageType = 0;
byte bits = 0;
int format= 0;
int lineWidth = 0;
fread(&headerLength, sizeof(byte), 1, f);
//skip next byte
fseek(f,1,SEEK_CUR);
//read in the imageType (RLE, RGB, etc...)
fread(&imageType, sizeof(byte), 1, f);
//skip information we don't care about
fseek(f, 9, SEEK_CUR);
//read the width, height and bits per pixel (16, 24 or 32). We only will take care of 24 bits uncompressed TGAs
fread(&width, sizeof(WORD), 1, f);
fread(&height, sizeof(WORD), 1, f);
fread(&bits, sizeof(byte), 1, f);
//move the file pointer to the pixel data
fseek(f, headerLength + 1, SEEK_CUR);
//check if the image is not compressed.
if(imageType != 10)
{
//check if the image is a 24
if(bits == 24)
{
format = bits >> 3; //Another way to divide between 8. We want to know the pixel size in bytes.
lineWidth = format * width;
pixels = new GLubyte[lineWidth * height];
//we are going to load the pixel data line by line
for(int y = 0; y < height; y++)
{
//Read current line of pixels
GLubyte *line = &(pixels[lineWidth * y]);
fread(line, lineWidth, 1, f);
/*Because the TGA is BGR instead of RGB, we must swap the R and G components (OGL ES does not have the
GL_BGR_EXT extension*/
for(int i=0;i<lineWidth ; i+=format)
{
int temp = line[i];
line[i] = line[i+2];
line[i+2] = temp;
}
}
}
else
{
fclose(f);
*id = 0;
return false;
}
}
fclose(f);
/*Creation of the OpenGL Texture:
OpenGL ES texturing only allows 2D textures (1D textures could be easily achieved, using '1' as
height parameter in the glTexImage2D call).
Allowed filtering modes are:
GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR
and GL_LINEAR_MIPMAP_LINEAR.
Because OpenGL ES is written against OpenGL 1.5, it supports automatic mipmap generation, through:
glTexParameterx(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
Allowed clamping modes are:
GL_REPEAT and GL_CLAMP_TO_EDGE (GL_CLAMP, GL_CLAMP_TO_BORDER and GL_MIRRORED_REPEAT are not supported)
Allowed formats are:
Internal & External Format Type Bytes per Pixel
GL_RGBA GL_UNSIGNED_BYTE 4
GL_RGB GL_UNSIGNED_BYTE 3
GL_RGBA GL_UNSIGNED_SHORT_4_4_4_4 2
GL_RGBA GL_UNSIGNED_SHORT_5_5_5_1 2
GL_RGB GL_UNSIGNED_SHORT_5_6_5 2
GL_LUMINANCE_ALPHA GL_UNSIGNED_BYTE 2
GL_LUMINANCE GL_UNSIGNED_BYTE 1
GL_ALPHA GL_UNSIGNED_BYTE 1
Texture borders are not suported at all
*/
glGenTextures(1, id);
glBindTexture(GL_TEXTURE_2D, *id);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
delete [] pixels;
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -